First of all,i thought a solution to it ,but it's not a good way.I will give in the last.
when i deal with Filter In iOS9
i got "need a swizzler so that RGB8 can be read" error message and the return image is total black by this method
[self.context createCGImage:self.outputImage fromRect:[self.outputImage extent]];
in here
- (UIImage *)fliterImage:(UIImage *)input flitername:(NSString *)name
{
NSString * fliter_name = name;
self.context = [CIContext contextWithOptions:nil];
UIImage *image;
if ([fliter_name isEqualToString:@"OriginImage"]){
image = input;
}else {
self.ciImage = [[CIImage alloc] initWithImage:input];
self.filter = [CIFilter filterWithName:fliter_name keysAndValues:kCIInputImageKey,self.ciImage, nil];
[self.filter setDefaults];
self.outputImage = [self.filter outputImage];
// here give the error message
self.cgimage = [self.context createCGImage:self.outputImage fromRect:[self.outputImage extent]];
UIImage *image1 = [UIImage imageWithCGImage:self.cgimage];
CGImageRelease(self.cgimage);
self.context = [CIContext contextWithOptions:nil];
//
// self.filter=[CIFilter filterWithName:@"CIColorControls"];
// _imageView.image=image;
//
//[self.filter setValue:[CIImage imageWithCGImage:image.CGImage] forKey:@"inputImage"];
image = image1;
}
return image;
}
and the pram input
is create by this method written by my director
-(UIImage *)UIImageFromBmp:(uint8_t**)pixels withPlanesCount:(uint32_t)planeCount
{
uint8_t *rgb = malloc(sizeof(uint8_t)*1920*1080*3);
int step = 1920 * 3;
// CSU: YUV420 has 2 kinds of data structure
// planeCount==3 --> |yyyyyyyy|
// |yyyyyyyy|
// |uuuu|
// |vvvv|
// planeCount==2 --> |yyyyyyyy|
// |yyyyyyyy|
// |uvuvuvuv|
if (planeCount == 3) {
for (int rows=0; rows<1080; rows++) {
for (int cols=0; cols<1920; cols++) {
int y = pixels[0][rows*1920 + cols];
int u = pixels[1][(rows>>1)*960 + (cols>>1)];
int v = pixels[2][(rows>>1)*960 + (cols>>1)];
int r = (int)((y&0xff) + 1.402*((v&0xff)-128));
int g = (int)((y&0xff) - 0.34414*((u&0xff)-128) - 0.71414*((v&0xff)-128));
int b = (int)((y&0xff) + 1.772*((u&0xff)-128));
rgb[rows*step + cols*3 + 0] = MAX(MIN(r, 255), 0);
rgb[rows*step + cols*3 + 1] = MAX(MIN(g, 255), 0);
rgb[rows*step + cols*3 + 2] = MAX(MIN(b, 255), 0);
}
}
} else if(planeCount == 2) {
for (int rows=0; rows<1080; rows++) {
for (int cols=0; cols<1920; cols++) {
int y = pixels[0][rows*1920 + cols];
int u = pixels[1][(rows>>1)*1920 + ((cols>>1)<<1)];
int v = pixels[1][(rows>>1)*1920 + ((cols>>1)<<1)+1];
int r = (int)((y&0xff) + 1.402*((v&0xff)-128));
int g = (int)((y&0xff) - 0.34414*((u&0xff)-128) - 0.71414*((v&0xff)-128));
int b = (int)((y&0xff) + 1.772*((u&0xff)-128));
rgb[rows*step + cols*3 + 0] = MAX(MIN(r, 255), 0);
rgb[rows*step + cols*3 + 1] = MAX(MIN(g, 255), 0);
rgb[rows*step + cols*3 + 2] = MAX(MIN(b, 255), 0);
}
}
} else {
// CSU: should not happen
assert(0);
}
NSData *data = [NSData dataWithBytes:rgb length:step*1080];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
// CSU: Creating CGImage from raw data
CGImageRef imageRef = CGImageCreate(1920, //width
1080, //height
8, //bits per component
8 * 3, //bits per pixel
step, //bytesPerRow
colorSpace, //colorspace
kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info
provider, //CGDataProviderRef
NULL, //decode
false, //should interpolate
kCGRenderingIntentDefault //intent
);
// CSU: Getting UIImage from CGImage
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
free(rgb);
return finalImage;
}
i google it need a swizzler so that RGB8 can be read,and realize it may the image format the cause the prolem.
so i call [self clipImageWithScaleWithsize:_scaledImage.size input:_sourceImage];
to deal the image before it pass to
[self.context createCGImage:self.outputImage fromRect:[self.outputImage extent]];
with this (size is just the image size)
- (UIImage *)clipImageWithScaleWithsize:(CGSize)asize input:(UIImage *)input
{
UIImage *newimage;
UIImage *image = input;
if (nil == image) {
newimage = nil;
}
else{
CGSize oldsize = image.size;
CGRect rect;
if (asize.width/asize.height > oldsize.width/oldsize.height) {
rect.size.width = asize.width;
rect.size.height = asize.width*oldsize.height/oldsize.width;
rect.origin.x = 0;
rect.origin.y = (asize.height - rect.size.height)/2;
}
else{
rect.size.width = asize.height*oldsize.width/oldsize.height;
rect.size.height = asize.height;
rect.origin.x = (asize.width - rect.size.width)/2;
rect.origin.y = 0;
}
UIGraphicsBeginImageContext(asize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClipToRect(context, CGRectMake(0, 0, asize.width, asize.height));
CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]);
UIRectFill(CGRectMake(0, 0, asize.width, asize.height));//clear background
[image drawInRect:rect];
newimage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
return newimage;
}
and it did solve the prombem,but i am still puzzled,and i don't think it's a good way. What does "need a swizzler so that RGB8 can be read" really mean,and why my solution work?