首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在iOS上将视频转换成动画格式

在iOS上将视频转换成动画格式
EN

Stack Overflow用户
提问于 2015-09-07 21:22:11
回答 3查看 7.3K关注 0票数 7

我想转换一个与相机(.mp4)拍摄的视频文件,并将其转换为动画GIF图像。

我查了一下Apple,似乎没有任何内置的功能。

我该如何处理这项任务?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-09-07 21:29:30

这方面没有内置的API。我发布了一个库,可以将视频文件转换为动画GIF图像,同时提供足够的灵活性来调整设置,如帧速率、帧持续时间、大小等。

这个库名为NSGIF。你可以在这里找到它:http://github.com/NSRare/NSGIF

这是将视频转换为GIF的最简单方法:

代码语言:javascript
复制
[NSGIF optimalGIFfromURL:url loopCount:0 completion:^(NSURL *GifURL) {
    NSLog(@"Finished generating GIF: %@", GifURL);
}];

使用optimalGIFfromURL方法,根据最优设置自动生成GIF。还有更大的灵活性的余地。看看回购的更多样本。

票数 3
EN

Stack Overflow用户

发布于 2016-08-23 12:06:54

您可以在第1步中这样做--计算所需的帧。

代码语言:javascript
复制
CMTime vid_length = asset.duration;
float seconds = CMTimeGetSeconds(vid_length);
int required_frames_count = seconds * 12.5; //You can set according 

致u

代码语言:javascript
复制
int64_t step = vid_length.value / required_frames_count;
int value = 0;

2-使Gif文件设置属性

代码语言:javascript
复制
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];

第三步从视频资产AVAssetImageGenerator生成帧

代码语言:javascript
复制
 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文件中添加框架

代码语言:javascript
复制
- (void)mergeFrameForGif:(UIImage*)pic1
{
    CGImageDestinationAddImage(destination, pic1.CGImage, (CFDictionaryRef)frameProperties);
    pic1=nil;

}
票数 7
EN

Stack Overflow用户

发布于 2020-10-06 22:42:59

更新为Swift 5.1

代码语言:javascript
复制
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)


}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32446196

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档