iOS를 통해 애니메이션 GIF를 만들고 내보내시겠습니까?
iOS 앱에는 간단한 프레임 별 플립 북 스타일로 애니메이션되는 일련의 사용자 맞춤 이미지가 있습니다.
내 질문은 이것이다 : 사용자가 애니메이션을 애니메이션 GIF로 내보낼 수있는 방법이 있습니까? 이상적으로는 이메일, 소셜 공유 (T / FB) 또는 (최악의 경우 ..) 애니메이션 GIF를 iTunes를 통해 검색 할 수 있도록 문서 폴더에 저장할 수 있도록하고 싶습니다.
.png를 사진 라이브러리에 저장하는 방법을 알고 있으며 애니메이션을 QT 파일로 기록하는 방법을 찾았습니다 ( http://www.cimgf.com/2009/02/03/record-your-core-animation -animation / ),하지만 평범한 오래된 애니메이션 gif를 쫓아내는 방법을 찾지 못했습니다. Core Animation이나 다른 곳에서 뭔가 빠졌나요? 누구나 추천 할 수있는 접근 방식, 프레임 워크 또는 리소스가 있습니까? 질문이 너무 일반적인 경우 미안합니다. 출발점을 찾는 데 어려움을 겪습니다.
이미지 I / O 프레임 워크 (iOS SDK의 일부)를 사용하여 애니메이션 GIF를 만들 수 있습니다. MobileCoreServices
GIF 유형 상수를 정의하는 프레임 워크 도 포함 할 수 있습니다. 이러한 프레임 워크를 대상에 추가하고 다음과 같이 애니메이션 GIF를 만들 파일에서 헤더를 가져와야합니다.
#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/MobileCoreServices.h>
예를 들어 설명하는 것이 가장 쉽습니다. iPhone 5에서이 GIF를 만드는 데 사용한 코드를 보여 드리겠습니다.
먼저, 크기와 각도를 취하고 UIImage
해당 각도에서 빨간색 디스크의 a 를 반환하는 도우미 함수가 있습니다 .
static UIImage *frameImage(CGSize size, CGFloat radians) {
UIGraphicsBeginImageContextWithOptions(size, YES, 1); {
[[UIColor whiteColor] setFill];
UIRectFill(CGRectInfinite);
CGContextRef gc = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(gc, size.width / 2, size.height / 2);
CGContextRotateCTM(gc, radians);
CGContextTranslateCTM(gc, size.width / 4, 0);
[[UIColor redColor] setFill];
CGFloat w = size.width / 10;
CGContextFillEllipseInRect(gc, CGRectMake(-w / 2, -w / 2, w, w));
}
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
이제 GIF를 만들 수 있습니다. 나중에 두 번 필요하므로 먼저 프레임 수에 대한 상수를 정의합니다.
static void makeAnimatedGif(void) {
static NSUInteger const kFrameCount = 16;
애니메이션을 반복해야하는 횟수를 지정하려면 속성 사전이 필요합니다.
NSDictionary *fileProperties = @{
(__bridge id)kCGImagePropertyGIFDictionary: @{
(__bridge id)kCGImagePropertyGIFLoopCount: @0, // 0 means loop forever
}
};
그리고 우리는 프레임이 표시되어야하는 시간을 지정하는 각 프레임에 첨부 할 또 다른 속성 사전이 필요합니다.
NSDictionary *frameProperties = @{
(__bridge id)kCGImagePropertyGIFDictionary: @{
(__bridge id)kCGImagePropertyGIFDelayTime: @0.02f, // a float (not double!) in seconds, rounded to centiseconds in the GIF data
}
};
또한 문서 디렉토리에 GIF에 대한 URL을 생성합니다.
NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil];
NSURL *fileURL = [documentsDirectoryURL URLByAppendingPathComponent:@"animated.gif"];
이제 CGImageDestination
지정된 URL에 GIF를 쓰는를 만들 수 있습니다 .
CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)fileURL, kUTTypeGIF, kFrameCount, NULL);
CGImageDestinationSetProperties(destination, (__bridge CFDictionaryRef)fileProperties);
I discovered that passing fileProperties
as the last argument of CGImageDestinationCreateWithURL
does not work. You have to use CGImageDestinationSetProperties
.
Now we can create and write our frames:
for (NSUInteger i = 0; i < kFrameCount; i++) {
@autoreleasepool {
UIImage *image = frameImage(CGSizeMake(300, 300), M_PI * 2 * i / kFrameCount);
CGImageDestinationAddImage(destination, image.CGImage, (__bridge CFDictionaryRef)frameProperties);
}
}
Note that we pass the frame properties dictionary along with each frame image.
After we've added exactly the specified number of frames, we finalize the destination and release it:
if (!CGImageDestinationFinalize(destination)) {
NSLog(@"failed to finalize image destination");
}
CFRelease(destination);
NSLog(@"url=%@", fileURL);
}
If you run this on the simulator, you can copy the URL from the debug console and paste it into your browser to see the image. If you run it on the device, you can use the Xcode Organizer window to download the app sandbox from the device and look at the image. Or you can use an app like iExplorer
that lets you browse your device's filesystem directly. (This doesn't require jailbreaking.)
I tested this on my iPhone 5 running iOS 6.1, but I believe the code should work as far back as iOS 4.0.
I've put all the code in this gist for easy copying.
For Swift 3
import Foundation
import UIKit
import ImageIO
import MobileCoreServices
extension UIImage {
static func animatedGif(from images: [UIImage]) {
let fileProperties: CFDictionary = [kCGImagePropertyGIFDictionary as String: [kCGImagePropertyGIFLoopCount as String: 0]] as CFDictionary
let frameProperties: CFDictionary = [kCGImagePropertyGIFDictionary as String: [(kCGImagePropertyGIFDelayTime as String): 1.0]] as CFDictionary
let documentsDirectoryURL: URL? = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let fileURL: URL? = documentsDirectoryURL?.appendingPathComponent("animated.gif")
if let url = fileURL as CFURL? {
if let destination = CGImageDestinationCreateWithURL(url, kUTTypeGIF, images.count, nil) {
CGImageDestinationSetProperties(destination, fileProperties)
for image in images {
if let cgImage = image.cgImage {
CGImageDestinationAddImage(destination, cgImage, frameProperties)
}
}
if !CGImageDestinationFinalize(destination) {
print("Failed to finalize the image destination")
}
print("Url = \(fileURL)")
}
}
}
}
I have converted it from the above answer. I hope it helps.
Available as a gist.
Edits are welcomed.
Swift 3 솔루션을 찾고 있다면 https://github.com/onmyway133/GifMagic 에서 살펴볼 수 있습니다.. It has Encoder
and Decoder
which assembles and disassembles gif file.
기본적으로 Image IO
이러한 기능과 함께 프레임 워크를 사용해야 합니다 CGImageDestinationCreateWithURL
.CGImageDestinationSetProperties
, CGImageDestinationAddImage
, CGImageDestinationFinalize
주석이 달린 API에서 반환 된 Core Foundation 객체는 Swift에서 자동으로 메모리 관리됩니다. CFRetain, CFRelease 또는 CFAutorelease 함수를 직접 호출 할 필요가 없습니다.
참고 URL : https://stackoverflow.com/questions/14915138/create-and-export-an-animated-gif-via-ios
'Nice programing' 카테고리의 다른 글
R에서 밀도 플롯을 오버레이하는 방법은 무엇입니까? (0) | 2020.10.23 |
---|---|
자바 하우투 ArrayList 푸시, 팝, 시프트 및 시프트 해제 (0) | 2020.10.23 |
ManyRelatedManager 개체는 반복 할 수 없습니다. (0) | 2020.10.23 |
Grails (현재)는 그만한 가치가 있습니까? (0) | 2020.10.23 |
보기는 WebViewPage 또는 WebViewPage에서 파생되어야합니다. (0) | 2020.10.23 |