更新保存的 Retina 显示屏图像
我有一个 iPhone 应用程序,除其他功能外,它还允许用户存储照片。当新照片添加到应用程序的数据存储中时,我会缓存该图像的缩略图版本,以便在合理的时间内加载照片缩略图网格。
问题是这些缩略图在 Retina 显示屏之前的屏幕上看起来很棒,但在 RD 显示屏上看起来有点模糊。图像无法使用并不是那么糟糕,但我真的希望能够为用户使用旧版本的应用程序保存的图像充分利用 Retina Display 的优势。
问题是重新创建所有这些缩略图需要太长时间。在我的测试中,在我的 iPhone 4 上将示例数据库重新编码为高分辨率缩略图(确实很大)需要大约一分半钟的时间。在旧硬件上情况会更糟。
我该如何解决这个问题?鉴于上述性能结果,进行一次性迁移似乎是不可能的。其他选项是延迟缩小缩略图(即,当它们显示在屏幕上时),然后将它们保存到数据库中。充满旧图像的屏幕第一次观看时会很迟缓,之后就会变得更快。
还有其他方法可以考虑吗?还有其他人遇到过这个问题吗?
I have an iPhone app that, among other things, allows users to store photos. When a new photo is added to the app's data store, I cache a thumbnail version of the image so that the photo thumbnail grids load in a reasonable amount of time.
The problem is that these thumbnails look great on a pre-Retina Display screen, but they look a little blurry on RD displays. It's not so bad that the images are unusable, but I would really like to be able to get the full benefit of Retina Display for images users saved with older versions of my app.
The problem is that re-creating all these thumbnails takes way too long. In my tests, it took about a minute and a half to re-encode a sample database to high-res thumbnails (admittedly a large one) on my iPhone 4. It will be even worse on older hardware.
How can I get around this? Doing a one-time migration seems out of the question, given the performance results above. Other options are shrinking the thumbnails lazily (i.e. as they're displayed on-screen) and then saving them to the database at that point. Screens full of old images will be sluggish the first time they're viewed, and then snappier after that.
Are there other approaches to consider? Anyone else faced this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我建议您通过显示缩略图的方式以图形方式解决问题。因此,不要全屏显示,而是在该图像周围放置一个边框,并以其真实分辨率显示它(不要放大它)。或者在通常显示 1 个图像的地方显示 4 个图像(因为 iPhone 屏幕的分辨率是 4 倍)。
您可以对缩略图进行双三次上采样,使其大小变为 4 倍,而不是对原始大图像进行重新采样。这会让它有点模糊,但它看起来应该比 iPhone 缩放效果更好,后者看起来真的很糟糕。由于处理小图像,上采样速度会非常快。
我无法帮助您进行上采样,但某处会有一些代码。
干杯,约翰。
I would suggest you graphically solve the problem by how you display the thumbnail images. so instead of fullscreen put a border around this image and show it at its true resolution (dont upscale it). Or show 4 images where you normally show 1 (since iPhone screen is 4x the resolution).
Instead of resampling the original massive image, you could do a bicubic upsample of the thumbnail making it 4x the size. This will make it slightly blurry but it should look better than the iPhone scaling which will look really bad. The upsample would be ultra fast as its working with a small image.
I cannot help you out on upsampling but there will be some code somewhere.
Cheers, John.
它不必是迟缓的。
这有点麻烦,但您可以在后台线程中完成大部分处理。将线程优先级设置为较低的值(例如 0.1)以避免 UI 太慢。最简单的方法是为每个需要转换的图像设置一个 NSOperation,并将它们添加到 maxConcurrentOperationCount=1 的 NSOperationQueue 中。
如果写入不是原子的,请在 -applicationDidEnterBackground: 或 -applicationWillTerminate: 中(或在监听相应通知通知的内容中),执行类似
[queue cancelAllOperations]; 的操作for (NSOperation * 队列中的操作) { [操作 setThreadPriority:1]; [队列 waitUntilAllOperationsAreFinished];
;您大约需要 10 秒左右的时间,这应该足以让图像转换完成写入磁盘(从而避免半写入文件)。为了增强保护,如果写入时间可能超过 10 秒,请在写入之前立即检查[operation isCancelled]
。显然,在 -applicationWillEnterForeground: 中,您应该重新启动转换(记住某些图像已经被转换)。追踪并发问题很有趣...
(请注意,
[data writeToFile:pathatomically:YES]
是不够的 - 如果应用程序在写入过程中被终止,可能会留下临时文件如果可以的话,我建议将缩略图存储在核心数据中,但这对于现有应用程序来说可能是不可能的。)It doesn't have to be sluggish.
It's a bit of a pain, but you can do most of your processing in a background thread. Set the thread priority to something low (like 0.1) to avoid making the UI too slow. The easiest way to do this is to set up an NSOperation for each image you need to convert and add them to a NSOperationQueue with maxConcurrentOperationCount=1.
If writes are not atomic, in -applicationDidEnterBackground: or -applicationWillTerminate: (or in something listening for the corresponding notifications notifications), do something like
[queue cancelAllOperations]; for (NSOperation * operation in queue) { [operation setThreadPriority:1]; } [queue waitUntilAllOperationsAreFinished];
; you get about 10 seconds or so which should be enough for the image conversion to finish writing to disk (and thus avoid half-written files). For added protection, check[operation isCancelled]
immediately before the write if it might take longer than 10 seconds. Obviously, in -applicationWillEnterForeground:, you should restart the conversion (remembering that some of the images have already been converted).Concurrency issues are fun to track down...
(Note that
[data writeToFile:path atomically:YES]
isn't sufficient — it's likely to leave temporary files lying around if the app is killed during the write. I'd recommend storing thumbnails in Core Data if you can, but that might be out of the question for existing apps.)