gpt4 book ai didi

objective-c - 在 Cocoa 中创建动画 GIF - 定义帧类型

转载 作者:搜寻专家 更新时间:2023-10-30 19:46:14 24 4
gpt4 key购买 nike

我已经能够改编在 SO 上找到的一些代码,以从我的 View 的“屏幕截图”中生成动画 GIF,但结果是不可预测的。 GIF 帧有时是完整图像、完整帧(“替换”模式,如 GIMP 标记的那样),其他时候只是与前一层的“差异”(“组合”模式)。

据我所知,当涉及的帧更少和/或更小时,CG 会以“组合”模式写入 GIF,但无法获得正确的颜色。实际上,运动部件的颜色是正确的,背景是错误的。CG 将 GIF 保存为全帧时,颜色正常。文件更大,但是,嘿,显然你不能两全其美。 :)

有没有办法:

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

我做的是(ARC模式):

捕获 View 的可见部分

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

将其转换并调整为PNG类型的NSImageBitmapRep

-(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
(来源:andraz.eu)

这是带有无效颜色的 GIF(“组合”模式) combined frames
(来源:andraz.eu)

最佳答案

我读了你的代码。请在创建 CGImageDestinationRef 和“[images count]”时仔细检查“allImages”。

下面的测试代码工作正常:

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);

关于objective-c - 在 Cocoa 中创建动画 GIF - 定义帧类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15584931/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com