What's the "need a swizzler so that RGB8 can be read" about that Core Image give iOS9?
Asked Answered
E

0

6

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?

Erotogenic answered 13/10, 2015 at 8:41 Comment(2)
Have you found out the reason? I came across the same situation.Astraphobia
Something has rotted in some Apple framework. The message is gone on 9.3 So imho you need your workaround only on 9.0 through 9.2Laclair

© 2022 - 2024 — McMap. All rights reserved.