创建于可可GIF动画 - 定义帧类型 [英] Creating an animated GIF in Cocoa - defining frame type

查看:218
本文介绍了创建于可可GIF动画 - 定义帧类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经能够适应一些code发现SO,从我的观点的截屏制作GIF动画,但结果未predictable。 GIF帧有时完整图像,全帧(替换模式,GIMP将其标记),其他时间都只是从previous层(合并模式)差异。

I've been able to adapt some code found on SO to produce an animated GIF from the "screenshots" of my view, but the results are unpredictable. GIF frames are sometimes full images, full frames ("replace" mode, as GIMP marks it), other times are just a "diff" from previous layer ("combine" mode).

这是我所看到的,当有较少的和/或更小的框架介入,CG中写道:结合模式GIF,但未能获得正确的色彩。实际上,运动部件被正确地着色,背景是错误的。
当CG保存为GIF全帧,颜色都OK。文件尺寸较大,但嘿,显然你不能有两全其美。 :)

From what I've seen, when there are fewer and/or smaller frames involved, the CG writes the GIF in "combine" mode, but failing to get the colors right. Actually, the moving parts are colored correctly, the background is wrong. When CG saves the GIF as full frames, the colors are ok. The file size is larger, but hey, obviously you cannot have the best of both worlds. :)

有没有办法要么:

    a) force CG to create "full frames" when saving the GIF
    b) fix the colors (color table?)

我要做的就是(ARC模式):

What I do is (ARC mode):

捕捉与视图的可见部分

[[scrollView contentView] dataWithPDFInsideRect:[[scrollView contentView] visibleRect]];

转换并调整到PNG类型的NSImageBitma preP

-(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];
}

获得Bitma prePS的阵列和创建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);

我检查了ImageBitma prePS,当单独保存为PNG,他们就好了。
我的理解,在色表应该由CG或处理我是负责产生抖动颜色?那怎么办?

I've checked the ImageBitmapReps, when saved as PNG individually, they are just fine. As I understood, the color tables should be handled by CG or am I responsible to produce the dithered colors? How to do that?

即使做同样的动画反复,产生的GIF文件可能会有所不同。

Even when doing the same animation repeatedly, the GIFs produced may vary.

这是一个Bitma preP

This is a single BitmapRep

这是无效的颜色GIF(合并模式)

And this is the GIF with the invalid colors ("combine" mode)

推荐答案

我看了你的code。请仔细检查了allImages,而你正在创建的CGImageDestinationRef,而[图像数]。

I read your code. Please double check the "allImages" while you are creating the CGImageDestinationRef, and the "[images count]".

后续测试code正常工作:

the follow test code works fine:

NSDictionary *prep = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:0.2f] forKey:(NSString *) kCGImagePropertyGIFDelayTime] forKey:(NSString *) kCGImagePropertyGIFDictionary];

CGImageDestinationRef dst = CGImageDestinationCreateWithURL((__bridge CFURLRef)(fileURL), kUTTypeGIF, [filesArray count], nil);

for (int i=0;i<[filesArray count];i++)
{
    //load anImage from array
    ...

    CGImageRef imageRef=[anImage CGImageForProposedRect:nil context:nil hints:nil];
    CGImageDestinationAddImage(dst, imageRef,(__bridge CFDictionaryRef)(prep));

}

bool fileSave = CGImageDestinationFinalize(dst);
CFRelease(dst);

这篇关于创建于可可GIF动画 - 定义帧类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆