2014-02-20 1 views
1

В моем приложении у меня есть imageView, изображение в imageView должно давать некоторые эффекты, такие как сепия, черно-белый.
Для эффекта сепии я использовал следующий код,Ошибка при использовании эффекта изображения сепии в iOS?

-(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; 
} 

Это работает отлично, но только для .png изображения, когда я использую изображения .jpg, он просто отображает черный цвет вид на imageView. Любая помощь будет оценена

+0

JPG не поддерживает 32 бита на пиксель макс составляет 24 бита, которое составляет 8 бит каждый для R, G, B (без альфа), так как вы сделали не преобразовывать данные в RGBA, выполните следующие изменения: int imagWidth = image.size.width; int imageheight = image.size.height; NSInteger myDataLength = imagWidth * imageheight * 3; для (int i = 0; i Paulo

ответ

1

Использование обработки сердечника изображения,

-(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]]; 

}

0

Используйте CGImageCreateWithJPEGDataProvider, чтобы получить растровое изображение из 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 
} 

Вы не можете использовать JPEG кодированного изображения как обычный RGB. Итак, сначала расшифруйте его с помощью CGImageCreateWithJPEGDataProvider.

+0

может у вас просьба сообщить – Chandru

+0

Я опубликовал код для изображения JPEG. Для PNG используйте решение, которое работает сейчас. –

+0

сбой в UInt8 * доступ к данным ebad – Chandru

0

Я подозреваю, что вы имеете дело с данными формата RGBA .... JPG для одного не имеет альфа-канала. Вместо того, чтобы иметь дело с тонкостями данных, я предлагаю вам рассмотреть использование фильтров Core Image, я использовал их с jpg и PNG без каких-либо проблем.

Существует множество фильтров основного изображения, включая один для Sepia, а другой для оттенков серого/черного и белого здесь код для 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 документация Apple, на CoreImage хорошо, я предлагаю вам прочитайте об этом.

+0

JPG использует 8-битное изображение в оттенках серого или 24-битный цвет - это 8 бит для r, g и blue. Ваша процедура предполагает 32-битный формат цвета, известный как RBGA8888, используемый PNG. (Обратите внимание, что PNG серого также существует). Я считаю, что есть подпрограммы для проверки используемого CGColorSpaceRef или преобразования его в RGBA, чтобы ваша программа работала, но почему это связано с тем, что если более высокие уровни, такие как CoreImage, уже делают весь тяжелый подъем для вас. – Paulo