发布网友 发布时间:2022-11-17 23:02
共1个回答
热心网友 时间:2024-01-24 01:47
GIF 裁剪过程可以大致分为三步
这里主要用到了 Image I/O 的相关接口,Image I/O framework 提供一种不透明的数据类型(opaque data types),从 CGImageSourceRef 获取图片数据,将图片数据写入到 CGImageDestinationRef。它提供一个范围很广的图片格式,包含 web 格式,动态图,原始相机数据等。
首先是获取 GIF 的帧集合。
这里 CGImageSourceRef 就是一个代表图片的不透明的数据类型,它抽象了读取图像数据的通道,但本身不会读取图像的任何数据。
对于 GIF 等 AnimateImage 对象可以包含多个 Image,这里 CGImageSourceGetCount 就可以获取到对应的源图片数据的帧数。
GIF 的一个重要属性是它的 ration 值,这里简单取为帧数的 10%,相当于每一帧的 ration 是 0.1s。SDWebImage 库的 SDWebImageGIFCoder.m 文件中提供了一种更准确的获取方法
通过 CGImageSourceCreateImageAtIndex 方法我们可以从一个 CGImageSourceRef 数据源中读到一个帧位的未解码图片数据,然后通过 CGImageCreateWithImageInRect 对这一帧数据进行裁剪后,解码生成一个 UIImage 对象,将其放入一个数组中。最后通过 [UIImage animatedImageWithImages: ration:] 方法来生成一个被裁剪后的 GIF 的 UIImage 对象。这时候 可以把这个 UIImage 对象赋给 UIImageView 对象来展示一个 GIF 图片。
最后要注意手动释放 CGImageSourceRef 对象
如果要传输裁剪后的 GIF 图片给服务器,还需要将上一步得到的 UIImage 转化为 NSData 对象。
这里通过上一步得到的 UIImage 对象,首先获得 GIF 图的帧数,然后获得每一帧的 ration。同时创建一个 NSMutableData 的对象用于存储 GIF 图片的数据,然后创建一个 CGImageDestinationRef 来指定存入数据区(mutableData)、存入数据类型(kUTTypeGIF)和帧数(frameCount)。最后遍历 animatedImage 的每一个 UIImage 对象,依据每一帧的 ration 值存入 CGImageDestinationRef 对象中。执行完遍历操作后,mutableData 中就是我们需要的裁剪后的 GIF 图片的 NSData 数据。