質問

In my app, I am having an imageView, the image in the imageView should be give some effects like sepia, black and white.
To do sepia effect I used the following code,

 -(UIImage*)makeSepiaScale:(UIImage*)image
{
    CGImageRef cgImage = [image CGImage];
    CGDataProviderRef provider = CGImageGetDataProvider(cgImage);
    CFDataRef bitmapData = CGDataProviderCopyData(provider);
    UInt8* data = (UInt8*)CFDataGetBytePtr(bitmapData);

    int imagWidth = image.size.width;
    int imageheight = image.size.height;
    NSInteger myDataLength = imagWidth * imageheight * 4;


    for (int i = 0; i < myDataLength; i+=4)
    {
        UInt8 r_pixel = data[i];
        UInt8 g_pixel = data[i+1];
        UInt8 b_pixel = data[i+2];

        int outputRed = (r_pixel * .393) + (g_pixel *.769) + (b_pixel * .189);
        int outputGreen = (r_pixel * .349) + (g_pixel *.686) + (b_pixel * .168);
        int outputBlue = (r_pixel * .272) + (g_pixel *.534) + (b_pixel * .131);

        if(outputRed>255)outputRed=255;
        if(outputGreen>255)outputGreen=255;
        if(outputBlue>255)outputBlue=255;


        data[i] = outputRed;
        data[i+1] = outputGreen;
        data[i+2] = outputBlue;
    }

    CGDataProviderRef provider2 = CGDataProviderCreateWithData(NULL, data, myDataLength, NULL);
    int bitsPerComponent = 8;
    int bitsPerPixel = 32;
    int bytesPerRow = 4 * imagWidth;
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
    CGImageRef imageRef = CGImageCreate(imagWidth, imageheight, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider2, NULL, NO, renderingIntent);

    CGColorSpaceRelease(colorSpaceRef); // YOU CAN RELEASE THIS NOW
    CGDataProviderRelease(provider2); // YOU CAN RELEASE THIS NOW
    CFRelease(bitmapData);

    UIImage *sepiaImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef); // YOU CAN RELEASE THIS NOW
    return sepiaImage;
}

It is working perfectly, but only for .png image, when I use .jpg images, it just displays a black colour view for the imageView. Any help will be appreciated

役に立ちましたか?

解決

Use core image processing,

 -(void)makeSepiaScale
{
CIImage *beginImage =[[CIImage alloc]initWithImage:imageForView];

    CIContext * context=[CIContext contextWithOptions:nil];

    CIFilter *filter = [CIFilter filterWithName:@"CISepiaTone"
                                  keysAndValues: kCIInputImageKey, beginImage,
                        @"inputIntensity", @0.8, nil];
    CIImage *outImage = [filter outputImage];

    CGImageRef cgimg=[context createCGImage:outImage fromRect:[outImage extent]];


[imageView setImage:[UIImage imageWithCGImage:cgimg]];

}

他のヒント

Use CGImageCreateWithJPEGDataProvider to get the bitmap from JPEG:

-(UIImage*)makeSepiaScale:(UIImage*)image {

    CGImageRef cgJpegImage = [image CGImage];
    CGDataProviderRef jpegProvider = CGImageGetDataProvider(cgJpegImage);

    CGImageRef cgBitmapImage = CGImageCreateWithJPEGDataProvider(jpegProvider, nil, NO, kCGRenderingIntentRelativeColorimetric);
    CGDataProviderRef bitmapProvider = CGImageGetDataProvider(cgBitmapImage);

    CFDataRef bitmapData = CGDataProviderCopyData(bitmapProvider);
    UInt8* data = (UInt8*)CFDataGetBytePtr(bitmapData);

    // other code to make sepia effect
}

You can't use JPEG encoded image like plain RGB. So, just decode it with CGImageCreateWithJPEGDataProvider first.

I suspect you are dealing with non RGBA format data .... JPG for one does not have an Alpha channel. Rather than deal with the intricacies of the data I suggest that you consider using Core Image filters, I've used them with jpg and PNG without any issues.

There is a variety of Core Image filters including one for Sepia and another for grayscale / black and white here is the code for Sepia:

-(UIImage*)makeSepiaScale:(UIImage*)input_image output:(UIImage *)output
{

 CIImage *cimage = [[CIImage alloc] initWithImage:input_image];  
CIFilter *myFilter = [CIFilter filterWithName:@"CISepiaTone"];

[myFilter setDefaults];
[myFilter setValue:cimage forKey:@"inputImage"];
[myFilter setValue:[NSNumber numberWithFloat:0.8f] forKey:@"inputIntensity"];

CIImage *image = [myFilter outputImage];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:image fromRect:image.extent];
output = [UIImage imageWithCGImage:cgImage];  
CGImageRelease(cgImage);
return (output);}

PS the Apple documentation on CoreImage is good, I suggest you read up on it.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top