在 iPhone 上缩放和裁剪大图像

发布于 2024-08-13 23:09:07 字数 804 浏览 10 评论 0原文

在过去的几周里,我一直在绞尽脑汁地尝试让平铺机制在 iPhone 上发挥作用。我需要缩放和裁剪大约 150mb 的图像,以便可以将它们保存为滚动视图所请求的图块,从而允许用户以高分辨率查看图像。

问题是这些图像确实突破了 iPhone 处理能力的极限。将这些巨大的图像缩小到 1000 左右并进行平铺似乎很容易,但对于大缩放级别,我需要中间缩放,比如 4000 宽,这太大了。因此,我想到了从全尺寸图像中制作中等大小的块并将每个块和中等变焦平铺的想法。

通过围绕内部循环创建一个自动释放池,并在每个循环后耗尽它,我基本上可以控制内存,但有时,对我来说,这似乎是随机的,内存正在泄漏,或者至少没有耗尽。我在辅助线程上执行所有这些操作,当它返回到该线程中的第一个函数时,我释放该线程自己的自动释放池,然后才清除最后的内存工件。它似乎并没有打扰模拟器,但 iPhone 的宽容度要低得多,它在完成整个平铺过程之前就崩溃了。我使用的裁剪代码来自 Hive05

http://www.hive05.com/2008/11/crop-an-image-using-the-iphone-sdk/

有其他人曾经处理过这么大的图像吗?预生成图块是最好的方法吗?关于为什么有些循环会增加内存而有些不会,或者如何强制清除内部池上的每个自动释放的东西而不是等待外部池,有什么建议吗?

感谢您阅读本文。

需要补充一点,这些图像是 TIF,因此直接读取位图信息可能比缩放和裁剪整个图像更好

For the last few weeks I've been tearing my hair out trying to get a tiling mechanism working on an iPhone. I need to scale and crop images of about 150mb so that they can be saved as tiles that will be requested by a scroll view, allowing the user to see the image in high resolution.

The problem is that these images are really pushing the bounds of what an iPhone can handle. It seems quite easy to scale these huge images down to 1000 or so across and do that tiling, but for large zoom levels I need to scale it mid-way, say 4000 across and that's too big. So I hit upon the idea of making medium sized blocks from the full sized image and tiling each of those and the medium zoom.

By creating an autoreleasepool around the inner loops, and draining it after each cycle I can mostly keep the memory under control but sometimes, and to me it seems random, memory is getting leaked, or at least not drained. I'm doing all this on a secondary thread and when it gets back to the first function in that thread I release the thread's own autoreleasepool and only then do the last memory artifacts get cleared. It doesn't seem to bother the simulator but the iPhone is much less forgiving and it crashes before it can complete the whole tiling process. The cropping code I am using is from Hive05

http://www.hive05.com/2008/11/crop-an-image-using-the-iphone-sdk/

Has anyone else had to deal with such massive images before? Is pre-generating tiles the best way to go? Any suggestions on why some loops would increase the memory and some not, or how to force every auto-released thing to clear on the inner pool instead of waiting for the outer pool?

Thanks for reading this far.

for got to add, these images are TIFs, so perhaps a direct reading of the bitmap info would be better than scaling and cropping the entire thing

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

何以笙箫默 2024-08-20 23:09:07

首先,我严重怀疑 150 MB 的图像是否适合该设备的内存,即使我们谈论的是 3GS。该内存最多可为第三方应用程序提供约 128 MB 的可用内存。查看设备控制台消息并查找内存警告,我想您会在崩溃之前看到应用程序在尝试加载图像时发出它们。以块的形式读取位图信息似乎更明智,因为您将一次管理较小的部分。我认为 Cocoa 没有随机访问文件 API,因此您必须求助于 C 函数。

First of all, I have serious doubts that an 150 MB image would fit in the device's memory, even if we're talking about a 3GS. That one has about 128 MB available memory for 3rd party apps maximum. See the device console messages and look for memory warnings, I guess you'll see that before crashing, the app emits them when trying to load your image. Reading the bitmap info in chunks would seem more sensible, as you'll be managing smaller sections at a time. I don't think Cocoa has a random-access file API, so you'll have to resort to a C function.

虫児飞 2024-08-20 23:09:07

我已经成功编写了循环遍历 1024x1024 块的循环,并且我的 iPhone 3G 能够完成处理。虽然需要 30 多分钟,所以不是很好,但这就是在手机上处理 150mb TIF 的结果。

为了保持较低的内存使用量,我必须在每次迭代后耗尽 AutoReleasepools。 Apple 技术支持指出,由于 iPhone 是引用计数环境而不是垃圾收集环境,因此最好在每个内部循环开始时创建一个新的 AutoReleasePool 并在每个循环结束时清空它,而不是在之前创建它任何循环都会启动,多次耗尽,然后在循环完成后释放它。在我进行更改之前,我的应用程序会使 iPhone 崩溃,但在模拟器上运行良好。

I've managed to write the loops that cycle through tiles of 1024x1024 and my iPhone 3G is able to finish the processing. It takes over 30 minutes though so it isn't great but that's what you get for working with 150mb TIF on a cellphone.

To keep the memory usage low I had to drain the AutoReleasepools after each iteration. Apple Tech Support pointed out that since the iPhone is a reference-counted environment rather than a garbage collected environment it is better to create a new AutoReleasePool at the start of each inner loop and drain it at the end of each loop than to create it before any loops start, drain it many times and then release it after the loops are done. Until I made that change my app would crash an iPhone but run fine on the simulator.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文