UIImage循环通过像素非常低效?

时间:2015-02-16 00:37:20

标签: ios arrays swift uiimage

目前我正在使用此方法遍历每个像素,并根据RGB值将值插入到3D数组中。我需要这个数组用于我程序的其他部分,但它非常慢。当在50 x 50的图片上运行时,它几乎是即时的,但是一旦你开始进入数百甚至数百,它需要很长时间才能达到应用无用的程度。任何人对如何加快我的方法有任何想法?

@IBAction func convertImage(sender: AnyObject) {
    if let image = myImageView.image {

        var pixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage))
        var data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)

        let height = Int(image.size.height)
        let width = Int(image.size.width)
        var zArry = [Int](count:3, repeatedValue: 0)
        var yArry = [[Int]](count:width, repeatedValue: zArry)
        var xArry = [[[Int]]](count:height, repeatedValue: yArry)

        for (var h = 0; h < height; h++) {
            for (var w = 0; w < width; w++) {
                 var pixelInfo: Int = ((Int(image.size.width) * Int(h)) + Int(w)) * 4
                var rgb = 0
                xArry[h][w][rgb] = Int(data[pixelInfo])
                rgb++
                xArry[h][w][rgb] = Int(data[pixelInfo+1])
                rgb++
                xArry[h][w][rgb] = Int(data[pixelInfo+2])
                }
        }
        println(xArry[20][20][1])
    }
}

也许有办法将UIImage转换为不同类型的图像并创建像素数组。我对所有建议持开放态度。谢谢!

目标:目标是使用数组修改所有像素的RGB值,并使用修改的像素创建新图像。我尝试简单地循环遍历所有像素而不存储它们,并将它们修改为新的数组以创建图像,但是遇到了相同的性能问题。

1 个答案:

答案 0 :(得分:7)

更新:

经过无数次尝试,我意识到我正在对调试配置进行测试。

切换到发布,现在它的速度要快得多。

Swift似乎在调试配置上要慢很多倍。

您的代码与我的优化版本之间的差异要快几倍。

使用image.size.width代替本地变量width似乎有一个大幅放缓。

<强>原始

我尝试优化它并提出这个:

@IBAction func convertImage () {

    if let image = UIImage(named: "test") {

        let pixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage))
        let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)

        let height = Int(image.size.height)
        let width = Int(image.size.width)
        let zArry = [Int](count:3, repeatedValue: 0)
        let yArry = [[Int]](count:width, repeatedValue: zArry)
        let xArry = [[[Int]]](count:height, repeatedValue: yArry)

        for (index, value) in xArry.enumerate() {
            for (index1, value1) in value.enumerate() {
                for (index2, var value2) in value1.enumerate() {

                    let pixelInfo: Int = ((width * index) + index1) * 4 + index2

                    value2 = Int(data[pixelInfo])
                }
            }
        }
    }
}

然而,在我的测试中,这个速度提高了不到15%。你需要的是更快的数量级。

另一个想法是在需要时直接使用数据对象而不创建如下数组:

let image = UIImage(named: "test")!

let pixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage))
let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)

let width = Int(image.size.width)

// value for [x][y][z]
let value = Int(data[((width * x) + y) * 4 + z])

你没有说明你在你的应用程序中如何使用这个数组,但我觉得即使你找到一种方法来更快地创建这个数组,当你尝试使用它时会遇到另一个问题,如这也需要很长时间..