Swift 3: how to save Animated images from imageView (GIF)?

4.3k views Asked by At

I am new to swift and I have some images that animated in one imageView, now I want to save it in gallery as we save simple image, How can I do that?

imageView.animationImages = [
            UIImage(named:"1.jpg")!,
            UIImage(named:"2.jpg")!,
            UIImage(named:"3.jpg")!,
            UIImage(named:"4.jpg")!,
            UIImage(named:"5.jpg")!
        ]

        imageView.animationDuration = 3
        imageView.startAnimating()

Any kind of Help will be appreciated...(:

3

There are 3 answers

3
Yogesh Mv On

Convert your GIF image into data and then you can write that data to Photo library:

NSData *data = <GIF Image Data>
ALAssetsLibrary *assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary writeImageDataToSavedPhotosAlbum:data metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {

    NSLog(@"Image Path", [assetURL path] );
}];

I hope this could be useful for you.

0
xue On

Refer the code here -> swift-create-a-gif-from-images-and-turn-it-into-nsdata

The above code is used for OS X, so I adjusted it a little bit.

Import ImageIO and MobileCoreServices

func createGIF(with images: [UIImage], name: URL, loopCount: Int = 0, frameDelay: Double) {

    let destinationURL = name
    let destinationGIF = CGImageDestinationCreateWithURL(destinationURL as CFURL, kUTTypeGIF, images.count, nil)!

    // This dictionary controls the delay between frames
    // If you don't specify this, CGImage will apply a default delay
    let properties = [
        (kCGImagePropertyGIFDictionary as String): [(kCGImagePropertyGIFDelayTime as String): frameDelay]
    ]


    for img in images {
        // Convert an UIImage to CGImage, fitting within the specified rect
        let cgImage = img.cgImage
        // Add the frame to the GIF image
        CGImageDestinationAddImage(destinationGIF, cgImage!, properties as CFDictionary?)
    }

    // Write the GIF file to disk
    CGImageDestinationFinalize(destinationGIF)
}

Use it in this way:

let documentsURL = FileManager.default.urls(for: .documentDirectory,
                                                   in: .userDomainMask).first
let path = documentsURL!.appendingPathComponent("1.gif")
createGIF(with: images, name: path, frameDelay: 0.1)
// you can check the path and open it in Finder, then you can see the file
print(path)

I also made a demo on github -> saveImagesAsGif

0
Oletha On

Using the [UIImage]-to-file code from this answer, you can go from an Array of UIImages to having those images saved in your camera roll by saving the images as a .gif file, then passing the URL for that file to PHPhotoLibrary using PHAssetChangeRequest.

func saveImages(_ images: [UIImage]) {
    let documentsURL = FileManager.default.urls(
        for: .documentDirectory,
        in: .userDomainMask
    ).first
    let imageURL = documentsURL!.appendingPathComponent("MyImage.gif")

    createGIF(with: images, name: imageURL, frameDelay: 0.5)

    PHPhotoLibrary.shared().performChanges({
        PHAssetChangeRequest.creationRequestForAssetFromImage(
            atFileURL: imageURL
        )
    })
}

/// From https://stackoverflow.com/a/42216154/5052894
private func createGIF(with images: [UIImage], name: URL, loopCount: Int = 0, frameDelay: Double) {

    let destinationURL = name
    let destinationGIF =  CGImageDestinationCreateWithURL(destinationURL as CFURL, kUTTypeGIF, images.count, nil)!

    // This dictionary controls the delay between frames
    // If you don't specify this, CGImage will apply a default delay
    let properties = [
        (kCGImagePropertyGIFDictionary as String): [(kCGImagePropertyGIFDelayTime as String): frameDelay]
    ]

    for img in images {
        // Convert an UIImage to CGImage, fitting within the specified rect
        let cgImage = img.cgImage
        // Add the frame to the GIF image
        CGImageDestinationAddImage(destinationGIF, cgImage!, properties as CFDictionary?)
    }

    // Write the GIF file to disk
    CGImageDestinationFinalize(destinationGIF)
}