【问题标题】:How to display GIF image in scenekit?如何在场景包中显示 GIF 图像?
【发布时间】:2021-08-20 14:01:17
【问题描述】:

如何在 scenekit 中显示 GIF 图片。我有下面的代码,但它不显示图像。场景是一片空白。

func displayGIF() {
    if let url = Bundle.main.url(forResource: "circles", withExtension: "gif"){
        let animation = createGIFAnimation(url: url)
        
        let layer = CALayer()
        layer.bounds = CGRect(x: 0, y: 0, width:600, height:200)
        layer.add(animation!, forKey: "contents")

        let material = SCNMaterial()
        material.isDoubleSided = true
        material.diffuse.contents = layer

        let plane = SCNPlane(width: 5, height: 5)
        plane.materials = [material]
        
        let node = SCNNode(geometry: plane)
        self.scenekitView.allowsCameraControl = true
        self.scenekitView.cameraControlConfiguration.allowsTranslation = true
        self.scenekitView.scene?.rootNode.addChildNode(node)
    }
}

func createGIFAnimation(url:URL) -> CAKeyframeAnimation? {

    guard let src = CGImageSourceCreateWithURL(url as CFURL, nil) else { return nil }
    let frameCount = CGImageSourceGetCount(src)

    // Total loop time
    var time : Float = 0

    // Arrays
    var framesArray = [AnyObject]()
    var tempTimesArray = [NSNumber]()

    // Loop
    for i in 0..<frameCount {

        // Frame default duration
        var frameDuration : Float = 0.1;

        let cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(src, i, nil)
        guard let framePrpoerties = cfFrameProperties as? [String:AnyObject] else {return nil}
        guard let gifProperties = framePrpoerties[kCGImagePropertyGIFDictionary as String] as? [String:AnyObject]
            else { return nil }

        // Use kCGImagePropertyGIFUnclampedDelayTime or kCGImagePropertyGIFDelayTime
        if let delayTimeUnclampedProp = gifProperties[kCGImagePropertyGIFUnclampedDelayTime as String] as? NSNumber {
            frameDuration = delayTimeUnclampedProp.floatValue
        }
        else{
            if let delayTimeProp = gifProperties[kCGImagePropertyGIFDelayTime as String] as? NSNumber {
                frameDuration = delayTimeProp.floatValue
            }
        }

        // Make sure its not too small
        if frameDuration < 0.011 {
            frameDuration = 0.100;
        }

        // Add frame to array of frames
        if let frame = CGImageSourceCreateImageAtIndex(src, i, nil) {
            tempTimesArray.append(NSNumber(value: frameDuration))
            framesArray.append(frame)
        }

        // Compile total loop time
        time = time + frameDuration
    }

    var timesArray = [NSNumber]()
    var base : Float = 0
    for duration in tempTimesArray {
        timesArray.append(NSNumber(value: base))
        base += duration.floatValue / time
    }

    // From documentation of 'CAKeyframeAnimation':
    // the first value in the array must be 0.0 and the last value must be 1.0.
    // The array should have one more entry than appears in the values array.
    // For example, if there are two values, there should be three key times.
    timesArray.append(NSNumber(value: 1.0))

    // Create animation
    let animation = CAKeyframeAnimation(keyPath: "contents")

    animation.beginTime = AVCoreAnimationBeginTimeAtZero
    animation.duration = CFTimeInterval(time)
    animation.repeatCount = Float.greatestFiniteMagnitude;
    animation.isRemovedOnCompletion = false
    animation.fillMode = CAMediaTimingFillMode.forwards
    animation.values = framesArray
    animation.keyTimes = timesArray
    //animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
    animation.calculationMode = CAAnimationCalculationMode.discrete

    return animation;
}

【问题讨论】:

  • 我不能 100% 确定这是您的 createGIFAnimation(url:) 函数还是 SCNScene 代码。你能用简单的test.jpg 替换circles.gif 看看它是否有效吗?如果是这样,我假设错误可能存在于您的 displayGIF() 函数中,否则我敢打赌错误存在于 createGIFAnimation(url:)

标签: ios swift scenekit gif


【解决方案1】:

使用gifu 非常适合在scenekit 下渲染gif 图像。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-04
    • 2012-08-21
    • 2012-10-24
    • 1970-01-01
    • 2015-10-21
    • 2016-03-23
    • 1970-01-01
    • 2012-03-01
    相关资源
    最近更新 更多