Я смог адаптировать некоторый код, найденный на SO, для создания анимированного GIF из «скриншотов» моего представления, но результаты непредсказуемы. Кадры GIF иногда представляют собой полные изображения, полные кадры (режим «заменить», как отмечает GIMP), в других случаях это просто «diff» из предыдущего слоя (режим «комбинировать»).Создание анимированного GIF в какао - определение типа кадра
Из того, что я видел, когда задействовано меньшее количество кадров и/или меньше, CG записывает GIF в режиме «комбинирования», но не может получить правильные цвета. На самом деле движущиеся части окрашены правильно, фон неправильный. Когда CG сохраняет GIF в качестве полных кадров, цвета в порядке. Размер файла больше, но, эй, очевидно, что у вас не может быть лучшего из обоих миров. :)
Есть ли способ либо:
a) force CG to create "full frames" when saving the GIF
b) fix the colors (color table?)
Что я делаю (режим ARC):
захвата видимой части представления с
[[scrollView contentView] dataWithPDFInsideRect:[[scrollView contentView] visibleRect]];
конвертировать и изменять его размер до NSImageBitmapRep PNG типа
-(NSMutableDictionary*) pngImageProps:(int)quality {
NSMutableDictionary *pngImageProps;
pngImageProps = [[NSMutableDictionary alloc] init];
[pngImageProps setValue:[NSNumber numberWithBool:NO] forKey:NSImageInterlaced];
double compressionF = 1;
[pngImageProps setValue:[NSNumber numberWithFloat:compressionF] forKey:NSImageCompressionFactor];
return pngImageProps;
}
-(NSData*) resizeImageToData:(NSData*)data toDimX:(int)xdim andDimY:(int)ydim withQuality:(int)quality{
NSImage *image = [[NSImage alloc] initWithData:data];
NSRect inRect = NSZeroRect;
inRect.size = [image size];
NSRect outRect = NSMakeRect(0, 0, xdim, ydim);
NSImage *outImage = [[NSImage alloc] initWithSize:outRect.size];
[outImage lockFocus];
[image drawInRect:outRect fromRect:inRect operation:NSCompositeCopy fraction:1];
NSBitmapImageRep* bitmapRep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:outRect];
[outImage unlockFocus];
NSMutableDictionary *imageProps = [self pngImageProps:quality];
NSData* imageData = [bitmapRep representationUsingType:NSPNGFileType properties:imageProps];
return [imageData copy];
}
получить массив BitmapReps и создать GIF
-(CGImageRef) pngRepDataToCgImageRef:(NSData*)data {
CFDataRef imgData = (__bridge CFDataRef)data;
CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData (imgData);
CGImageRef image = CGImageCreateWithPNGDataProvider(imgDataProvider, NULL, true, kCGRenderingIntentDefault);
return image;
}
////////// create GIF from
NSArray *images; // holds all BitmapReps
CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)[NSURL fileURLWithPath:pot],
kUTTypeGIF,
allImages,
NULL);
// set frame delay
NSDictionary *frameProperties = [NSDictionary
dictionaryWithObject:[NSDictionary
dictionaryWithObject:[NSNumber numberWithFloat:0.2f]
forKey:(NSString *) kCGImagePropertyGIFDelayTime]
forKey:(NSString *) kCGImagePropertyGIFDictionary];
// set gif color properties
NSMutableDictionary *gifPropsDict = [[NSMutableDictionary alloc] init];
[gifPropsDict setObject:(NSString *)kCGImagePropertyColorModelRGB forKey:(NSString *)kCGImagePropertyColorModel];
[gifPropsDict setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCGImagePropertyGIFHasGlobalColorMap];
// set gif loop
NSDictionary *gifProperties = [NSDictionary
dictionaryWithObject:gifPropsDict
forKey:(NSString *) kCGImagePropertyGIFDictionary];
// loop through frames and add them to GIF
for (int i=0; i < [images count]; i++) {
NSData *imageData = [images objectAtIndex:i];
CGImageRef imageRef = [self pngRepDataToCgImageRef:imageData];
CGImageDestinationAddImage(destination, imageRef, (__bridge CFDictionaryRef) (frameProperties));
}
// save the GIF
CGImageDestinationSetProperties(destination, (__bridge CFDictionaryRef)(gifProperties));
CGImageDestinationFinalize(destination);
CFRelease(destination);
Я проверил ImageBitmapReps, когда сохраняются как PNG по отдельности, они просто отлично. Как я понял, таблицы цветов должны обрабатываться CG или я отвечаю за то, чтобы выталкивать цвета? Как это сделать?
Даже при повторении одной и той же анимации созданные GIF-файлы могут отличаться.
Это один BitmapRep
single frame http://andraz.eu/stuff/gif/frame.png
И это GIF недостоверными цветов (режим "объединить") combined frames http://andraz.eu/stuff/gif/anim2.gif
Да, есть немного пропущенный код, я вижу его сейчас. allImages = [количество изображений]; и - (CGImageRef) pngRepDataToCgImageRef: (NSData *) Данные { CFDataRef imgData = (__bridge CFDataRef) данных; CGDataProviderRef imgDataProvider = CGDataProviderCreateWithCFData (imgData); CGImageRef image = CGImageCreateWithPNGDataProvider (imgDataProvider, NULL, true, kCGRenderingIntentDefault); Обратное изображение; } У меня есть массив NSImageBitmapRep-s, и пока существует достаточно кадров или они достаточно большие, все работает нормально. Я рассмотрю еще кое-что. – Andraz
Привет, Вы когда-нибудь получить эту работу, у меня аналогичная проблема с не все цвета, фигурирующих в выводимого Gif ... – Chris
да, это работает. подтверждено. –