iOS Core Graphics如何优化大图增量绘制?
iOS Core Graphics how to optimize incremental drawing of very large image?
我有一个用 RXSwift 编写的应用程序,它处理 500 多天的 HealthKit 数据来为用户绘制图表。
图表图像是使用以下代码逐步绘制的。从黑屏开始,先前的图像在图形上下文中绘制,然后在该图像上以一定的偏移量绘制新的片段。合并后的图像被保存,该过程重复大约 70 多次。每次保存图像时,用户都会看到更新。结果是 单个图表图像 用户可以从应用中导出。
即使使用 autorelease
池,我也发现内存使用量峰值高达 1Gb,这使我无法进行其他资源密集型处理。
超大(1440 × 5000像素)图片增量绘制如何优化?
图片以3倍比例显示或保存时,实际为4320 × 15360
有没有比尝试在图像上绘制更好的方法?
autoreleasepool {
//activeEnergyCanvas is custom data processing class
let newActiveEnergySegment = activeEnergyCanvas.draw(in: CGRect(x: 0, y: 0, width: 1440, height: days * 10), with: energyPalette)
let size = CGSize(width: 1440, height: height)
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
//draw existing image
self.activeEnergyImage.draw(in: CGRect(origin: CGPoint(x: 0, y: 0),
size: size))
//calculate where to draw smaller image over larger one
let offsetRect = CGRect(origin: CGPoint(x: 0, y: offset * 10),
size: newActiveEnergySegment.size)
newActiveEnergySegment.draw(in: offsetRect)
//get the combined image
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
//assign combined image to be displayed
if let unwrappedImage = newImage {
self.activeEnergyImage = unwrappedImage
}
}
原来我的错误是在创建图形上下文时传递了无效的绘图比例 (0.0),默认情况下以设备的本机屏幕比例进行绘图。
在 iPhone8 的情况下,它是 3.0 结果需要大量内存来绘制、缩放和导出这些图像。即使所有调试日志打印出该图像的宽度为 1440 像素,实际 canvas 最终还是 1440 * 3.0 = 4320。
通过1.0作为绘图比例使图像更加模糊,但将内存使用量减少到不到200mb。
// UIGraphicsBeginImageContext() <- also uses @3x scale, even when all display size printouts show
let drawingScale: CGFloat = 1.0
UIGraphicsBeginImageContextWithOptions(size, true, drawingScale)
我有一个用 RXSwift 编写的应用程序,它处理 500 多天的 HealthKit 数据来为用户绘制图表。
图表图像是使用以下代码逐步绘制的。从黑屏开始,先前的图像在图形上下文中绘制,然后在该图像上以一定的偏移量绘制新的片段。合并后的图像被保存,该过程重复大约 70 多次。每次保存图像时,用户都会看到更新。结果是 单个图表图像 用户可以从应用中导出。
即使使用 autorelease
池,我也发现内存使用量峰值高达 1Gb,这使我无法进行其他资源密集型处理。
超大(1440 × 5000像素)图片增量绘制如何优化?
图片以3倍比例显示或保存时,实际为4320 × 15360
有没有比尝试在图像上绘制更好的方法?
autoreleasepool {
//activeEnergyCanvas is custom data processing class
let newActiveEnergySegment = activeEnergyCanvas.draw(in: CGRect(x: 0, y: 0, width: 1440, height: days * 10), with: energyPalette)
let size = CGSize(width: 1440, height: height)
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
//draw existing image
self.activeEnergyImage.draw(in: CGRect(origin: CGPoint(x: 0, y: 0),
size: size))
//calculate where to draw smaller image over larger one
let offsetRect = CGRect(origin: CGPoint(x: 0, y: offset * 10),
size: newActiveEnergySegment.size)
newActiveEnergySegment.draw(in: offsetRect)
//get the combined image
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
//assign combined image to be displayed
if let unwrappedImage = newImage {
self.activeEnergyImage = unwrappedImage
}
}
原来我的错误是在创建图形上下文时传递了无效的绘图比例 (0.0),默认情况下以设备的本机屏幕比例进行绘图。
在 iPhone8 的情况下,它是 3.0 结果需要大量内存来绘制、缩放和导出这些图像。即使所有调试日志打印出该图像的宽度为 1440 像素,实际 canvas 最终还是 1440 * 3.0 = 4320。
通过1.0作为绘图比例使图像更加模糊,但将内存使用量减少到不到200mb。
// UIGraphicsBeginImageContext() <- also uses @3x scale, even when all display size printouts show
let drawingScale: CGFloat = 1.0
UIGraphicsBeginImageContextWithOptions(size, true, drawingScale)