我想转换使用相机拍摄的视频文件(.mp4)并将其转换为动画GIF图像。
我查看了Apple Docs,但似乎没有任何内置功能。</ p>
我该如何处理这项任务?
答案 0 :(得分:2)
没有内置的API。我发布了一个将视频文件转换为动画GIF图像的库,同时提供足够的灵活性来调整帧速率,帧持续时间,大小等设置。
该库名为NSGIF。您可以在此处找到它:http://github.com/NSRare/NSGIF
这是将视频转换为GIF的最简单方法:
[NSGIF optimalGIFfromURL:url loopCount:0 completion:^(NSURL *GifURL) {
NSLog(@"Finished generating GIF: %@", GifURL);
}];
使用optimalGIFfromURL
方法,根据最佳设置自动生成GIF。还有更大的灵活性。查看回购以获取更多样品。
答案 1 :(得分:2)
你可以在Some Step中完成 1- 计算所需的框架
CMTime vid_length = asset.duration;
float seconds = CMTimeGetSeconds(vid_length);
int required_frames_count = seconds * 12.5; //You can set according
到你
int64_t step = vid_length.value / required_frames_count;
int value = 0;
2- 制作GIF文件设置属性
destination = CGImageDestinationCreateWithURL((CFURLRef)[NSURL fileURLWithPath:path],
kUTTypeGIF,
required_frames_count,
NULL);
frameProperties = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0.8] forKey:(NSString *)kCGImagePropertyGIFDelayTime]
forKey:(NSString *)kCGImagePropertyGIFDictionary];
gifProperties = [NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0] forKey:(NSString *)kCGImagePropertyGIFLoopCount]
forKey:(NSString *)kCGImagePropertyGIFDictionary];
第3步 从视频资产AVAssetImageGenerator生成帧
for (int i = 0; i < required_frames_count; i++) {
AVAssetImageGenerator *image_generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
image_generator.requestedTimeToleranceAfter = kCMTimeZero;
image_generator.requestedTimeToleranceBefore = kCMTimeZero;
image_generator.appliesPreferredTrackTransform = YES;
image_generator.maximumSize = CGSizeMake(wd, ht); //to get an unscaled image or define a bounding box of 640px, aspect ratio remains
CMTime time = CMTimeMake(value, vid_length.timescale);
CGImageRef image_ref = [image_generator copyCGImageAtTime:time actualTime:NULL error:NULL];
UIImage *thumb = [UIImage imageWithCGImage:image_ref];
[self mergeFrameForGif:thumb];
CGImageRelease(image_ref);
value += step;
}
NSLog(@"Over all Size of Image(bytes):%ld",t);
CGImageDestinationSetProperties(destination, (CFDictionaryRef)gifProperties);
CGImageDestinationFinalize(destination);
CFRelease(destination);
NSLog(@"animated GIF file created at %@", path);
第4步 在Gif文件中添加框架
- (void)mergeFrameForGif:(UIImage*)pic1
{
CGImageDestinationAddImage(destination, pic1.CGImage, (CFDictionaryRef)frameProperties);
pic1=nil;
}
答案 2 :(得分:0)
已为Swift 5.1更新
import Foundation
import AVFoundation
import PhotosUI
import MobileCoreServices
func makeGIF(asset: AVAsset, destionationURL: URL, width: CGFloat, height: CGFloat) {
let duration = asset.duration
let vid_length : CMTime = duration
let seconds : Double = CMTimeGetSeconds(vid_length)
let tracks = asset.tracks(withMediaType: .video)
let fps = tracks.first?.nominalFrameRate ?? 1.0
let required_frames_count : Int = Int(seconds * Double(fps)) // You can set according
let step : Int64 = vid_length.value / Int64(required_frames_count)
var value : CMTimeValue = CMTimeValue.init(0.0)
let destination = CGImageDestinationCreateWithURL(destionationURL as CFURL, kUTTypeGIF, required_frames_count, nil)
let gifProperties : CFDictionary = [ kCGImagePropertyGIFDictionary : [kCGImagePropertyGIFLoopCount : 0] ] as CFDictionary
for _ in 0 ..< required_frames_count {
let image_generator : AVAssetImageGenerator = AVAssetImageGenerator.init(asset: asset)
image_generator.requestedTimeToleranceAfter = CMTime.zero
image_generator.requestedTimeToleranceBefore = CMTime.zero
image_generator.appliesPreferredTrackTransform = true
// to get an unscaled image or define a bounding box of 640px, aspect ratio remains
image_generator.maximumSize = CGSize(width: width, height: height)
let time : CMTime = CMTime(value: value, timescale: vid_length.timescale)
do {
let image_ref : CGImage = try image_generator.copyCGImage(at: time, actualTime: nil)
let thumb : UIImage = UIImage.init(cgImage: image_ref)
mergeFrameForGif(frame: thumb, destination: destination!)
value = value + step
} catch {
//
}
}
//print("Overall Size of Image(bytes): \(t)")
CGImageDestinationSetProperties(destination!, gifProperties)
CGImageDestinationFinalize(destination!)
print("animated GIF file created at \(destionationURL)")
}
func mergeFrameForGif(frame: UIImage, destination: CGImageDestination) {
let frameProperties : CFDictionary = [ kCGImagePropertyGIFDictionary : [kCGImagePropertyGIFDelayTime : 0.8] ] as CFDictionary
CGImageDestinationAddImage(destination, frame.cgImage!, frameProperties)
}