swift – 为什么过滤裁剪的图像比过滤尺寸调整的图像慢4倍(两者
我一直在努力解决这个问题而没有运气.我有一个非常简单的
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) 起源是(2000,2000) 知道了这一点,我可以在时间上提出一些事情. 我在Apple的文档中包含了关于裁剪功能的链接.它解释说它正在幕后进行一些CGRect计算,但它没有解释它是如何将像素位从全尺寸CG图像中拉出来的 – 我认为这是真正减速的地方. 最后,看起来时间是由于做了两件完全不同的事情. CGRect.cropping(to:) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |