версия сепия любого NSImage - PullRequest
       5

версия сепия любого NSImage

0 голосов
/ 27 апреля 2011

Я ищу простой и эффективный способ придать особый оттенок любому значку, содержащемуся в NSImage. Мой первоначальный идентификатор должен иметь значки сепии, но если можно использовать другие цвета, лучше.

Есть ли у вас идеи для достижения этой цели?

Заранее спасибо за помощь,

С уважением,

Ответы [ 2 ]

6 голосов
/ 27 апреля 2011

CoreImage имеет встроенные фильтры , одним из которых является CISepiaTone , которые вы можете легко использовать для преобразования цветов и других аспектов вашего изображения.

Шаги, которые необходимо выполнить, изложены в Обработка изображения :

Получить объект CIContext. Самым простым способом может быть запрос текущего NSGraphicsContext.

Получите CIImage представление вашего изображения. Это не может быть создано непосредственно из NSImage; вы, вероятно, захотите преобразовать NSImage в CGImageRef, используя CGImageForProposedRect:context:hints: (вы можете передать NULL в качестве аргумента proposedRect).

Создайте объект фильтра, установите его значения и получите обработанное изображение.

Наконец, нарисуйте изображение в вашем CIContext.

3 голосов
/ 27 апреля 2011

Я думаю, вам придется брать изображение попиксельно и корректировать значения rgb, чтобы получить эффект.

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

    int width = image.size.width;
    int height = image.size.height;
    NSInteger myDataLength = width * height * 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 * width;
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
    CGImageRef imageRef = CGImageCreate(width, height, 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;
}

Код беззастенчиво копируется из этого потока SO , и в нем говорится о применении фильтра сепии к UIImage вместо NSImage, но логика может быть использована повторно. Также этот поток является одним из самое лучшее, когда дело доходит до обработки изображений .. Одна в закладки ..

Редактировать : Как отметил Джош Касвелл, Core Image можно использовать для создания изображения сепии и некоторой фильтрации изображения. Таким простым способом должно быть использование основного изображения ... Прочитайте его ответ о том, как сделать это .. Этот метод тоже работает хорошо, особенно в iphone, где нет coreImage Framework ..

...