ios - 在 iOS 中快速更改像素的最佳方法
问题描述
我目前正在实施某种着色书,我很好奇在UIImage
. 这是我的代码:
self.context = CGContext(data: nil, width: image.width, height: image.height, bitsPerComponent: 8, bytesPerRow: image.width * 4, space: colorSpace, bitmapInfo: CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue)!
self.context?.draw(image.cgImage, in: CGRect(x: 0, y: 0, width: CGFloat(image.width), height: CGFloat(image.height)))
let ptr = context.data
self.pixelBuffer = ptr!.bindMemory(to: UInt32.self, capacity: image.width * image.height)
并使用此功能更改像素:
@inline (__always) func fill(matrixPosition: MatrixPosition, color: UInt32) {
pixelsBuffer?[self.linearIndex(for: matrixPosition)] = color
}
问题是每次我更改像素时,我都必须调用makeImage
它context
来生成新图像,这需要很长时间:
func generateImage() -> UIImage {
let cgImage = context.makeImage()!
let uiimage = UIImage(cgImage: cgImage)
return uiimage
}
我的方法正确吗?有什么更好更快的方法来实现它?谢谢。
解决方案
正如您所发现的,操作单个像素,然后将整个内存缓冲区复制到 CGContext,然后使用该上下文创建 UIImage 最终会效率低下。
您可以通过更有效地将屏幕外的哪些部分复制到屏幕上来继续改进和优化 CoreGraphics 画布方法。您可以检测已更改的像素,并仅将这些像素的最小边界矩形复制到屏幕上。对于您只用颜色填充区域的用例,这种方法可能已经足够了。
不要复制整个屏幕外,只复制更改的区域:
self.context?.draw(image.cgImage, in: CGRect(x: diffX, y: diffY, width: diffWidth, height: diffHeight))
由您决定更改的矩形以及何时更新屏幕。
这是一个使用 CoreGraphics、CoreImage 和 CADisplayLink 的绘画应用程序示例。代码有点旧,但概念仍然有效,可以作为一个很好的起点。您可以使用 CADisplayLink 查看更改是如何累积并绘制到屏幕上的。
如果您想引入各种类型的墨水和绘画效果,CoreGraphics 方法将更具挑战性。您将需要查看 Apple 的 Metal API。一个很好的教程在这里。
推荐阅读
- aws-sdk - Amazon Connect 自动拨出电话
- android - 错误:包 com.bumptech.glide.request.animation 不存在
- javascript - SecurityError:操作不安全。php
- sql - SQL Server:从包含 json 字符串的 nvarchar(max) 变量中获取所有字符串出现(标签)
- jpa - 外键的列数错误
- c# - .net 核心视图模型提供路由参数
- javascript - 以编程方式在 JSTree 中创建文件夹结构
- android - 如何解决 Quickblox 中的“基本所需会话不存在”错误?
- python - 修复opencv python + ImageMagick中detectAndCompute的windows和linux结果不一致的问题
- javascript - 如何使用 javascript 操作 json 对象并添加密钥?