Last active
August 29, 2015 13:57
-
-
Save mattwymore/9416392 to your computer and use it in GitHub Desktop.
This is an example of taking an array of data and writing it to "path" as a PNG file. This example shows how to properly premultiply alpha in the image as required by CGBitmapContextCreate.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//"bytes" is a pointer to a const array of image data that we can't modify, so we need to copy | |
//the data to a new buffer before multiplying alpha | |
//Premultiply the alpha and create a new image | |
UInt8 *premultipliedBuffer = calloc(totalBytes, 1); | |
memcpy(premultipliedBuffer, bytes, totalBytes); | |
for (int i = 0; i < totalBytes; i += 4) | |
{ | |
UInt8 red = premultipliedBuffer[i]; | |
UInt8 green = premultipliedBuffer[i + 1]; | |
UInt8 blue = premultipliedBuffer[i + 2]; | |
UInt8 alpha = premultipliedBuffer[i + 3]; | |
float alphaFactor = alpha / 255.0; | |
UInt8 premultipliedRed = (UInt8)nearbyintf(alphaFactor * red); | |
UInt8 premultipliedGreen = (UInt8)nearbyintf(alphaFactor * green); | |
UInt8 premultipliedBlue = (UInt8)nearbyintf(alphaFactor * blue); | |
premultipliedBuffer[i] = premultipliedRed; | |
premultipliedBuffer[i + 1] = premultipliedGreen; | |
premultipliedBuffer[i + 2] = premultipliedBlue; | |
} | |
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); | |
#pragma clang diagnostic push | |
#pragma clang diagnostic ignored "-Wconversion" | |
CGContextRef bitmapContext = CGBitmapContextCreate( | |
premultipliedBuffer, | |
imageSize.width, | |
imageSize.height, | |
8, | |
4 * imageSize.width, | |
colorSpace, | |
kCGImageAlphaPremultipliedLast); | |
#pragma clang diagnostic pop | |
CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext); | |
CFRelease(bitmapContext); | |
CFRelease(colorSpace); | |
free(premultipliedBuffer); | |
//Now write out the new image | |
CFURLRef outputUrl = (__bridge CFURLRef)[NSURL fileURLWithPath:path]; | |
CGImageDestinationRef destination = CGImageDestinationCreateWithURL(outputUrl, kUTTypePNG, 1, NULL); | |
CGImageDestinationAddImage(destination, cgImage, NULL); | |
CGImageDestinationFinalize(destination); | |
CFRelease(destination); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment