Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/44.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift中iOS上的大型图像合成_Ios_Iphone_Swift_Image - Fatal编程技术网

Swift中iOS上的大型图像合成

Swift中iOS上的大型图像合成,ios,iphone,swift,image,Ios,Iphone,Swift,Image,虽然我理解图像合成背后的理论,但我并没有处理太多的硬件加速问题,我在iOS(9.2,iPhone6S)上遇到了实现问题。我的项目是按顺序合成大量(20张,一直到数百张)的大型图像(1200万像素),以减少不透明度,我正在寻找关于最佳框架或技术的建议。我知道一定有一个好的、硬件加速的、破坏性的合成工具,能够在iOS上处理大文件,因为我可以在Safari中的HTML画布标记中执行此任务,并以几乎相同的速度在iPhone上的Safari中加载此页面 这可能是一个破坏性的合成任务,就像在画布上画画一样,

虽然我理解图像合成背后的理论,但我并没有处理太多的硬件加速问题,我在iOS(9.2,iPhone6S)上遇到了实现问题。我的项目是按顺序合成大量(20张,一直到数百张)的大型图像(1200万像素),以减少不透明度,我正在寻找关于最佳框架或技术的建议。我知道一定有一个好的、硬件加速的、破坏性的合成工具,能够在iOS上处理大文件,因为我可以在Safari中的HTML画布标记中执行此任务,并以几乎相同的速度在iPhone上的Safari中加载此页面

这可能是一个破坏性的合成任务,就像在画布上画画一样,所以我不应该有内存问题,因为手机只需要存储当前结果就可以了。理想情况下,我喜欢浮点像素组件,我也希望能够在屏幕上看到进度

核心图像的过滤器看起来很棒,但它们旨在对一两张图片进行无损操作并返回一个结果。我可以在下一幅图像中再次将结果输入到过滤器中,以此类推,但由于过滤器不会立即渲染,因此过滤器的链接在大约60幅图像之后耗尽了我的内存。渲染到核心图形图像对象并在每个过滤器后作为核心图像对象读回也没有帮助,因为这样会更快地过载内存

查看文档,iOS还有许多其他方法可以利用GPU,CALayers就是一个很好的例子。但我不清楚它是处理比屏幕大的图片,还是只用于屏幕大小的帧缓冲区

对于此任务-要利用GPU存储1200万像素的破坏性合成“堆栈”,并在顶部以指定的不透明度重复添加一个额外的堆栈,同时将堆栈的当前内容按比例输出到屏幕-最佳方法是什么?我可以使用一个已建立的框架/技术吗,还是我自己更擅长使用OpenGL和Metal?我知道iPhone有这种功能,我只需要想办法利用它

这就是我到目前为止得到的。分析器告诉我渲染大约需要350毫秒,但是如果我增加到20张图片,我的内存就会用完。如果每次循环后不进行渲染,我可以在内存耗尽之前增加到大约60张图片

var stackBuffer: CIImage!
var stackRender: CGImage!
var uiImage: UIImage!

let glContext = EAGLContext(API: .OpenGLES3)
let context = CIContext(EAGLContext: glContext)

// Preload list of 10 test pics
var ciImageArray = Array(count: 10, repeatedValue: CIImage.emptyImage())
for i in 0...9 {
    uiImage = UIImage(named: String(i) + ".jpg")!
    ciImageArray[i] = CIImage(image: uiImage)!
}

// Put the first image in the buffer
stackBuffer = ciImageArray[0]
for i in 1...9 {

    // The next image will have an opacity of 1/n
    let topImage = ciImageArray[i]
    let alphaTop = topImage.imageByApplyingFilter(
        "CIColorMatrix", withInputParameters: [
        "inputAVector"  : CIVector(x:0, y:0, z:0, w:1/CGFloat(i + 1))
        ])

    // Layer the next image on top of the stack
    let filter = CIFilter(name: "CISourceOverCompositing")!
    filter.setValue(alphaTop, forKey: kCIInputImageKey)
    filter.setValue(stackBuffer, forKey: kCIInputBackgroundImageKey)

    // Render the result, and read back in
    stackRender = context.createCGImage(filter.outputImage!, fromRect: stackBuffer.extent)
    stackBuffer = CIImage(CGImage: stackRender)
}

// Output result
uiImage = UIImage(CGImage: stackRender)
compositeView.image = uiImage