加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swift – 为什么过滤裁剪的图像比过滤尺寸调整的图像慢4倍(两者

发布时间:2020-12-14 04:57:44 所属栏目:百科 来源:网络整理
导读:我一直在努力解决这个问题而没有运气.我有一个非常简单的 Swift命令行应用程序,它接受一个参数 – 图像路径加载.它使用SepiaTone过滤器裁剪图像并过滤该图像片段. 它工作得很好.它将图像裁剪为200×200并使用SepiaTone进行过滤.现在这是我面临的问题 – 我的
我一直在努力解决这个问题而没有运气.我有一个非常简单的 Swift命令行应用程序,它接受一个参数 – 图像路径加载.它使用SepiaTone过滤器裁剪图像并过滤该图像片段.

它工作得很好.它将图像裁剪为200×200并使用SepiaTone进行过滤.现在这是我面临的问题 – 我的MacBook Air整个过程需要600毫秒.现在,当我将输入图像调整(而不是裁剪)到相同尺寸(200×200)时,需要150ms.

这是为什么?在这两种情况下,我都会过滤尺寸为200×200的图像.我正在使用this particular image进行测试(5966×3978).

更新:

在处理裁剪图像时,这段特殊代码需要4倍的时间:

var ciImage:CIImage = CIImage(cgImage: cgImage)

更新结束

裁剪代码(200×200):

// parse args and get image path
let args:Array = CommandLine.arguments
let inputFile:String = args[CommandLine.argc - 1]
let inputURL:URL = URL(fileURLWithPath: inputFile)

// load the image from path into NSImage
// and convert NSImage into CGImage
guard
    let nsImage = NSImage(contentsOf: inputURL),var cgImage = nsImage.cgImage(forProposedRect: nil,context: nil,hints: nil)
else {
    exit(EXIT_FAILURE)
}

// CROP THE IMAGE TO 200x200
// THIS IS THE ONLY BLOCK OF CODE THAT IS DIFFERENT
// IN THOSE TWO EXAMPLES
let rect = CGRect(x: 0,y: 0,width: 200,height: 200)

if let croppedImage = cgImage.cropping(to: rect) {
    cgImage = croppedImage
} else {
    exit(EXIT_FAILURE)
}

// END CROPPING



// convert CGImage to CIImage
var ciImage:CIImage = CIImage(cgImage: cgImage)

// initiate SepiaTone
guard
    let sepiaFilter = CIFilter(name: "CISepiaTone")
else {
    exit(EXIT_FAILURE)
}

sepiaFilter.setValue(ciImage,forKey: kCIInputImageKey)
sepiaFilter.setValue(0.5,forKey: kCIInputIntensityKey)

guard
    let result = sepiaFilter.outputImage
else {
    exit(EXIT_FAILURE)
}

let context:CIContext = CIContext()

// perform filtering in a GPU context
guard
    let output = context.createCGImage(sepiaFilter.outputImage!,from: ciImage.extent)
else {
    exit(EXIT_FAILURE)
}

调整大小的代码(200×200):

// parse args and get image path
let args:Array = CommandLine.arguments
let inputFile:String = args[CommandLine.argc - 1]
let inputURL:URL = URL(fileURLWithPath: inputFile)

// load the image from path into NSImage
// and convert NSImage into CGImage
guard
    let nsImage = NSImage(contentsOf: inputURL),hints: nil)
else {
    exit(EXIT_FAILURE)
}

// RESIZE THE IMAGE TO 200x200
// THIS IS THE ONLY BLOCK OF CODE THAT IS DIFFERENT
// IN THOSE TWO EXAMPLES
guard let CGcontext = CGContext(data: nil,height: 200,bitsPerComponent: cgImage.bitsPerComponent,bytesPerRow: cgImage.bytesPerRow,space: cgImage.colorSpace ?? CGColorSpaceCreateDeviceRGB(),bitmapInfo: cgImage.bitmapInfo.rawValue)
else {
    exit(EXIT_FAILURE)
}

CGcontext.draw(cgImage,in: CGRect(x: 0,height: 200))

if let resizeOutput = CGcontext.makeImage() {
    cgImage = resizeOutput
}

// END RESIZING



// convert CGImage to CIImage
var ciImage:CIImage = CIImage(cgImage: cgImage)

// initiate SepiaTone
guard
    let sepiaFilter = CIFilter(name: "CISepiaTone")
else {
    exit(EXIT_FAILURE)
}

sepiaFilter.setValue(ciImage,from: ciImage.extent)
else {
    exit(EXIT_FAILURE)
}

解决方法

看起来你正在做两件截然不同的事情.在“慢速”版本中,您正在裁剪(如在原始图像的小CGRect中),而在“快速”版本中,您正在调整大小(如将原始文件缩小为CGRect).

您可以通过添加两个UIImageViews并在每次声明ciImage之后添加这些行来证明这一点:

slowImage.image = UIImage(ciImage: ciImage)
    fastImage.image = UIImage(ciImage: ciImage)

这是两个模拟器截图,“快速”图像上方的“慢”图像.第一个是您的代码,其中“慢”CGRect原点是(0,0),第二个是将其调整为(2000,2000):

原点是(0,0)

Origin is (0,0)


起源是(2000,2000)

Origin is (2000,2000)

知道了这一点,我可以在时间上提出一些事情.

我在Apple的文档中包含了关于裁剪功能的链接.它解释说它正在幕后进行一些CGRect计算,但它没有解释它是如何将像素位从全尺寸CG图像中拉出来的 – 我认为这是真正减速的地方.

最后,看起来时间是由于做了两件完全不同的事情.

CGRect.cropping(to:)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读