Skip to content

Instantly share code, notes, and snippets.

@mattwymore
Last active August 29, 2015 13:57
Show Gist options
  • Save mattwymore/9416392 to your computer and use it in GitHub Desktop.
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.
//"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