Sepia -Version eines beliebigen NSIMage
-
22-10-2019 - |
Frage
Ich suche eine einfache und effiziente Möglichkeit, jedem in einem NSIMage enthaltenen Symbol eine besondere Farbton zu geben. Meine anfängliche ID benötigt ID für Sepia -Symbole, aber wenn sie andere Farben verwenden können, ist es besser.
Haben Sie eine Idee, um dies zu erreichen?
Vielen Dank im Voraus für Ihre Hilfe,
Grüße,
Lösung
Ich denke, Sie werden Image Pixel von Pixel übernommen und die RGB -Werte anpassen, um den Effekt zu erzielen.
-(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;
}
Der Code wird schamlos daraus kopiert ALSO Thread, und es geht darum, den Sepia -Filter auf UIImage anstelle von NSIMAGE anzuwenden, aber Logik kann wiederverwendet werden. Dies Thread ist einer der besten, wenn es um die Bildverarbeitung geht. Ein Lesezeichen.
Bearbeiten: Wie Josh Caswell betonte, kann das Kernbild zum Erstellen von Sepia -Bild und einer Bildfilterung verwendet werden. Besonders im iPhone, wo es kein CoreImage -Framework gibt.
Andere Tipps
CoreImage hat eingebaute Filter, eines davon ist Cisepiatone, mit dem Sie leicht die Farben und andere Aspekte Ihres Bildes verwandeln können.
Die Schritte, die Sie befolgen müssen Verarbeitung eines Bildes:
Holen Sie sich a CIContext
Objekt. Der einfachste Weg kann darin bestehen, den Strom zu fragen NSGraphicsContext
.
Holen Sie sich a Ciimage Darstellung Ihres Bildes. Dies kann nicht direkt von einem erstellt werden NSImage
; Sie werden wahrscheinlich Ihre konvertieren wollen NSImage
zu einem CGImageRef
Verwendung CGImageForProposedRect:context:hints:
(du kannst passieren NULL
für die proposedRect
Streit).
Erstellen Sie das Filterobjekt, legen Sie seine Werte fest und erhalten Sie das verarbeitete Bild.
Zeichnen Sie zum Schluss das Bild in Ihrem CIContext
.