I am looking for a simple and efficient way to give a special tint to any icon contained in an NSImage. My ini开发者_开发问答tial need id to have sepia icons but if can use other colors it is better.
Do you have any idea to achieve this?
Thanks in advance for your help,
Regards,
CoreImage has built-in filters, one of which is CISepiaTone, that you can easily use to transform the colors and other aspects of your image.
The steps you need to follow are laid out in Processing an Image:
Get a CIContext
object. The simplest way may be to ask the current NSGraphicsContext
.
Get a CIImage representation of your image. This cannot be created directly from an NSImage
; you will probably want to convert your NSImage
to a CGImageRef
using CGImageForProposedRect:context:hints:
(you can pass NULL
for the proposedRect
argument).
Create the filter object, set its values, and get the processed image.
Finally, draw the image in your CIContext
.
I think you will have take image pixel by pixel and adjust rgb values to get the effect.
-(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;
}
Code is shamelessly copied from this SO thread , and it talks about applying sepia filter to UIImage instead of NSImage, but logic can be reused..Also this thread is one of the best when it comes to image processing..One to bookmark..
Edit: As Josh Caswell pointed out, Core Image can be used to create sepia image and some image filtering..So easier method should be to use core Image...Read his answer on how to do it..This method works fine too, especially in iphone where there is no coreImage framework..
精彩评论