简体   繁体   English

为什么用 UIGraphicsImageRenderer 绘制图像时大量使用 memory?

[英]Why use a lot of memory when drawing image with UIGraphicsImageRenderer?

I want to add a white border to the photo, while preserving the quality of the photo, so I use UIGraphicsImageRenderer to draw a white background, and then draw the photo up, the result is a dramatic increase in memory usage, is there any better way?我想给照片加一个白色边框,同时保持照片的质量,所以我用UIGraphicsImageRenderer画了一个白色的背景,然后把照片画上去,结果memory的使用量急剧增加,有没有更好的方法?

The resolution of the original picture is 4032 * 3024.原图分辨率为4032*3024。

let renderer = UIGraphicsImageRenderer(size: CGSize(width: canvasSideLength, height: canvasSideLength))
let newImage = renderer.image { context in
    UIColor.white.setFill()
    context.fill(CGRect(x: 0, y: 0, width: canvasSideLength, height: canvasSideLength))
    image.draw(in: CGRect(x: photoCanvasX, y: photoCanvasY, width: photoCanvasWidth, height: photoCanvasHeight))
}

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

When considering the memory used, don't be misled by the size of the JPG or PNG file, because that is generally compressed.在考虑使用的 memory 时,不要被 JPG 或 PNG 文件的大小误导,因为它们通常是压缩的。 You will require four bytes per pixel when performing image operations in memory (eg width × height × 4, in pixels).在 memory 中执行图像操作时,每个像素需要四个字节(例如,宽 × 高 × 4,以像素为单位)。

Worse, by default, UIGraphicsImageRenderer will generate images at screen resolution (eg potentially 2× or 3× depending upon your device).更糟糕的是,默认情况下, UIGraphicsImageRenderer将生成屏幕分辨率的图像(例如,可能为 2 倍或 3 倍,具体取决于您的设备)。 Eg on a 3× device, consider:例如,在 3× 设备上,考虑:

let rect = CGRect(origin: .zero, size: CGSize(width: 8_519, height: 8_519))
let image = UIGraphicsImageRenderer(bounds: rect).image { _ in
    UIColor.white.setFill()
    UIBezierPath(rect: rect).fill()
}
print(image.cgImage!.width, "×", image.cgImage!.height)

That will print:那将打印:

25557 × 25557 25557 × 25557

When you consider that it then takes 4 bytes per pixel, that adds up to 2.6gb.当您考虑到每个像素需要 4 个字节时,加起来就是 2.6gb。 Even if the image is only 4,032 × 3,024, as suggested by your revised question, that's still 439mb per image.即使图像只有 4,032 × 3,024,正如您修改后的问题所建议的那样,每张图像仍然是 439mb。

You may want to make sure to specify an explicit scale of 1:您可能需要确保指定明确的比例 1:

let rect = CGRect(origin: .zero, size: CGSize(width: 8_519, height: 8_519))
let format = UIGraphicsImageRendererFormat()
format.scale = 1
let image = UIGraphicsImageRenderer(bounds: rect, format: format).image { _ in
    UIColor.white.setFill()
    UIBezierPath(rect: rect).fill()
}
print(image.cgImage!.width, "×", image.cgImage!.height)

That will print, as you expected:如您所料,这将打印:

8519 × 8519 8519 × 8519

Then you are only going to require 290mb for the image.然后你只需要 290mb 的图像。 That's still a lot of memory, but a lot less than if you use the default scale (on retina devices).这仍然是很多 memory,但比使用默认比例(在视网膜设备上)要少得多。 Or, considering your revised 4,032 × 3,024 image, this 1× image could take only 49mb, 1/9th the size of the corresponding 3× image where you didn't set the scale.或者,考虑到您修改后的 4,032 × 3,024 图像,这个 1× 图像可能只需要 49mb,是您未设置比例的相应 3× 图像大小的 1/9。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么不是我的UIGraphicsImageRenderer绘图(iOS 10)? - Why isn't my UIGraphicsImageRenderer drawing (iOS 10)? UIGraphicsImageRenderer:灰度图像的pngData - UIGraphicsImageRenderer: pngData for grayscale image 如何对UIGraphicsImageRenderer使用UIGraphicsRendererFormat? - How to use UIGraphicsRendererFormat for UIGraphicsImageRenderer? 在 UIGraphicsImageRenderer 工作后释放 memory - Release memory after UIGraphicsImageRenderer work 将多个图像上传到服务器时,应用程序占用大量内存 - App consuming a lot memory when uploading multiple image to sever 使用UIGraphicsImageRenderer渲染完整尺寸的图像 - Rendering a full sized image with UIGraphicsImageRenderer UIGraphicsImageRenderer 生成 PPI 不正确的图像 - UIGraphicsImageRenderer produces image with incorrect PPI ScrollView大量使用大量内存的图像 - ScrollView a lot of images which use a lot of memory 在某些情况下,当从扩展中调用时,UIGraphicsImageRenderer 闭包不会完成并返回图像 - UIGraphicsImageRenderer closure doesn't complete and return an image in some cases when invoked from within an extension 循环中使用的 UIGraphicsImageRenderer 以 memory 问题结束 - UIGraphicsImageRenderer used in a loop ends with memory issue
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM