I am trying to limit the number of colors of an animated GIF (created from a CGImageRef array).
However, itโs hard for me to set up a custom color table. Does anyone know how to do this using Core Graphics?
I know kCGImagePropertyGIFImageColorMap . Below is some test code (heavily borrowed from this github gist - as this is the only instance of kCGImagePropertyGIFImageColorMap that Google can find).
NSString *path = [@"~/Desktop/test.png" stringByExpandingTildeInPath]; CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData((CFDataRef)[NSData dataWithContentsOfFile:path]); CGImageRef image = CGImageCreateWithPNGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault); const uint8_t colorTable[ 8 ] = { 0, 0, 0, 0, 255, 255, 255 , 255}; NSData* colorTableData = [ NSData dataWithBytes: colorTable length: 8 ]; NSMutableDictionary *gifProps = [NSMutableDictionary dictionary]; [gifProps setObject:colorTableData forKey:(NSString *)kCGImagePropertyGIFImageColorMap]; [gifProps setObject:[NSNumber numberWithBool:NO] forKey:(NSString *)kCGImagePropertyGIFHasGlobalColorMap]; NSDictionary* imgProps = [ NSDictionary dictionaryWithObject: gifProps forKey: (NSString*) kCGImagePropertyGIFDictionary ]; NSURL* destUrl = [NSURL fileURLWithPath:[@"~/Desktop/test.gif" stringByExpandingTildeInPath]]; CGImageDestinationRef dst = CGImageDestinationCreateWithURL( (CFURLRef) destUrl, kUTTypeGIF, 1, NULL ); CGImageDestinationAddImage( dst, image, imgProps ); CGImageDestinationSetProperties(dst, (CFDictionaryRef) imgProps); CGImageDestinationFinalize( dst ); CFRelease( dst );
This, however, does not create a black and white image.
In addition, I tried to open GIFs to find information about the color table, but that helps a little.
CGImageSourceRef imageSourceRef = CGImageSourceCreateWithURL((CFURLRef) destUrl, NULL); NSDictionary *dict = (NSDictionary *)CGImageSourceCopyPropertiesAtIndex(imageSourceRef,0, NULL); CGImageRef img = CGImageSourceCreateImageAtIndex(imageSourceRef, 0, NULL); printf("Color space model: %d, indexed=%d, rgb = %d\n", CGColorSpaceGetModel(CGImageGetColorSpace(img)), kCGColorSpaceModelIndexed,kCGColorSpaceModelRGB); NSLog(@"%@", dict);
It states that the RGB color space is for GIF. However, if I try this code with indexed PNG, it says the color space is indexed.
Also, all the GIFs I tried have an image dictionary that looks something like this:
{ ColorModel = RGB; Depth = 8; HasAlpha = 1; PixelHeight = 176; PixelWidth = 314; "{GIF}" = { DelayTime = "0.1"; UnclampedDelayTime = "0.04"; }; }
(If I use CGImageSourceCopyProperties(...) , it mentions the global color map, but again the color table is not displayed.)