簡體   English   中英

如何將 Gif 圖像合並到 UIImageView 中並快速覆蓋 UIImageView?

[英]How to combine a Gif Image into UIImageView with overlaying UIImageView in swift?

一個 gif 圖像被加載到 UIImageView 中(通過使用這個擴展),另一個 UIImageView 被覆蓋在它上面。 一切正常,但問題是當我通過下面的代碼將兩者結合起來時,它顯示靜止圖像 (.jpg)。 我想結合兩者,結合后它也應該是一個動畫圖像 (.gif)。

let bottomImage = gifPlayer.image
let topImage = UIImage

let size = CGSize(width: (bottomImage?.size.width)!, height: (bottomImage?.size.height)!)
        
UIGraphicsBeginImageContext(size)
        
let areaSize = CGRect(x: 0, y: 0, width: size.width, height: size.height)
bottomImage!.draw(in: areaSize)

topImage!.draw(in: areaSize, blendMode: .normal, alpha: 0.8)
let newImage = UIGraphicsGetImageFromCurrentImageContext()

UIGraphicsEndImageContext()

請單擊此處了解有關此問題的更多信息。

UIImageView中使用動畫 GIF 時,它會變成UIImage數組。

我們可以設置該數組(例如):

imageView.animationImages = arrayOfImages
imageView.animationDuration = 1.0

或者,我們可以將.image屬性設置為animatedImage這就是您使用的 GIF-Swift 代碼的工作方式:

if let img = UIImage.gifImageWithName("funny") {
    bottomImageView.image = img
}

在這種情況下,圖像還包含持續時間:

img.images?.duration

因此,要生成帶有邊框/疊加圖像的新動畫 GIF,您需要獲取該圖像數組並生成添加了邊框的每個“幀”。

這是一個簡單的例子......

這假設:

  • 你正在使用GIF-Swift
  • 你在 Storyboard 中添加了bottomImageViewtopImageView
  • 你在名為“funny.gif”的包中有一個 GIF(如果你的不同,請編輯代碼)
  • 你在資產中有一個“border.png”(同樣,根據需要編輯代碼)

並且您有一個連接到@IBAction的按鈕:

import UIKit
import ImageIO
import UniformTypeIdentifiers

class animImageViewController: UIViewController {

    @IBOutlet var bottomImageView: UIImageView!
    @IBOutlet var topImageView: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        if let img = UIImage.gifImageWithName("funny") {
            bottomImageView.image = img
        }
        
        if let img = UIImage(named: "border") {
            topImageView.image = img
        }
        
    }
    
    @IBAction func saveButtonTapped(_ sender: Any) {
        generateNewGif(from: bottomImageView, with: topImageView)
    }

    func generateNewGif(from animatedImageView: UIImageView, with overlayImageView: UIImageView) {
        
        var images: [UIImage]!
        var delayTime: Double!
        
        guard let overlayImage = overlayImageView.image else {
            print("Could not get top / overlay image!")
            return
        }
        
        if let imgs = animatedImageView.image?.images {
            // the image view is using .image = animatedImage
            // unwrap the duration
            if let dur = animatedImageView.image?.duration {
                images = imgs
                delayTime = dur / Double(images.count)
            } else {
                print("Image view is using an animatedImage, but could not get the duration!" )
                return
            }
        } else if let imgs = animatedImageView.animationImages {
            // the image view is using .animationImages
            images = imgs
            delayTime = animatedImageView.animationDuration / Double(images.count)
        } else {
            print("Could not get images array!")
            return
        }
        
        // we now have a valid [UIImage] array, and
        //  a valid inter-frame duration, and
        //  a valid "overlay" UIImage
    
        // generate unique file name
        let destinationFilename = String(NSUUID().uuidString + ".gif")
        
        // create empty file in temp folder to hold gif
        let destinationURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(destinationFilename)
        
        // metadata for gif file to describe it as an animated gif
        let fileDictionary = [kCGImagePropertyGIFDictionary : [kCGImagePropertyGIFLoopCount : 0]]
        
        // create the file and set the file properties
        guard let animatedGifFile = CGImageDestinationCreateWithURL(destinationURL as CFURL, UTType.gif.identifier as CFString, images.count, nil) else {
            print("error creating file")
            return
        }
        
        CGImageDestinationSetProperties(animatedGifFile, fileDictionary as CFDictionary)
        
        let frameDictionary = [kCGImagePropertyGIFDictionary : [kCGImagePropertyGIFDelayTime: delayTime]]
        
        // use original size of gif
        let sz: CGSize = images[0].size
        
        let renderer: UIGraphicsImageRenderer = UIGraphicsImageRenderer(size: sz)
        
        // loop through the images
        //  drawing the top/border image on top of each "frame" image with 80% alpha
        //  then writing the combined image to the gif file
        images.forEach { img in
            
            let combinedImage = renderer.image { ctx in
                img.draw(at: .zero)
                overlayImage.draw(in: CGRect(origin: .zero, size: sz), blendMode: .normal, alpha: 0.8)
            }
            
            guard let cgFrame = combinedImage.cgImage else {
                print("error creating cgImage")
                return
            }
            
            // add the combined image to the new animated gif
            CGImageDestinationAddImage(animatedGifFile, cgFrame, frameDictionary as CFDictionary)
            
        }
        
        // done writing
        CGImageDestinationFinalize(animatedGifFile)
        
        print("New GIF created at:")
        print(destinationURL)
        print()
        
        // do something with the newly created file...
        //  maybe move it to documents folder, or
        //  upload it somewhere, or
        //  save to photos library, etc
    }
    
}

筆記:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM