UIImage到raw NSData /避免压缩 [英] UIImage to raw NSData / avoid compression

查看:254
本文介绍了UIImage到raw NSData /避免压缩的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有自己的图片下载器类,它拥有队列并一次下载一个(或一定量)的图像,将它们写入缓存文件夹,并在必要时从缓存文件夹中检索它们。我还有一个UIImageView子类,我可以传递一个URL,通过图像下载器类,如果图像已经存在于设备上,如果它显示它,或下载并显示它完成后。

图像完成下载后,我执行以下操作。我从下载的NSData创建一个UIImage,将下载的NSData保存到磁盘并返回UIImage。

 一个后台线程
downloadedImage = [UIImage imageWithData:downloadedData];
BOOL saved = [fileManager createFileAtPath:filePath content:downloadedData attributes:attributes];
//将下载的图像发送到主线程并执行某些操作

  //这是在后台线程中执行的
if([fileManager fileExistsAtPath:filePath] )
{
NSData * imageData = [fileManager contentsAtPath:filePath];
retrievedImage = [UIImage imageWithData:imageData];
//将retrieveImage发送到主线程并执行操作
}

如你所见,我总是直接从下载的NSData创建一个UIImage,我从来没有使用UIImagePNGRepresentation创建NSData,所以图像永远不会被压缩。当您从压缩的NSData创建UIImage时,UIImage将在主线程上呈现之前对其进行解压缩,从而阻止UI。因为我现在有一个UITableView和一吨小的图像,它必须从磁盘下载或检索,这将是不可接受的,因为它会极大地减慢我的滚动。



现在我的问题。用户还可以从相机胶卷中选择一张照片,保存它,它也必须出现在我的UITableView。但我似乎没有找到一种方法来将UIImage从相机卷转换为NSData,而不使用UIImagePNGRepresentation。所以这里是我的问题。



如何将UIImage转换为未压缩的NSData,所以我可以使用imageWithData将它转换回UIImage,以便它不必在渲染之前解压缩?





有什么办法可以在发送UIImage到主线程和缓存,所以它只需要解压缩一次?



提前感谢。

解决方案


如何将UIImage转换为未压缩的NSData,以便以后可以使用imageWithData将其转换回UIImage,以便在渲染之前不必解压缩? / p>

这里你真正要问的是,如何将UIImage 存储在磁盘上这样一种方式,您可以稍后尽快从磁盘读取UIImage 。你真的不在乎它是否存储为NSData;你只是想要能够快速阅读它。我建议你使用ImageIO框架。通过图片目标保存并稍后通过图片来源抓取。



http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/ImageIOGuide/ikpg_dest/ikpg_dest.html


有什么方法可以在将UIImage发送到主线程之前进行解压缩,并缓存它,要解压缩一次?


是的,好问题。这将是我的第二个建议:使用线程。这是人们必须与表一起做的事情。当表要求的图像,你要么有图像已经或你没有。如果没有,您提供填充图像,并在后台获取实际图像。当真实图像准备就绪时,您已安排获取通知。回到主线程,你告诉表视图再次请求该行的数据;这一次你有了形象,你提供它。因此,用户将在图像出现之前看到轻微的延迟。我相信你已经看到很多这样的应用程序(纽约时报是一个很好的例子)。



我还有一个建议,它可能是最好的。你说它需要时间来解压缩来自磁盘的映像。但如果图像很小,这应该没有时间。但图片应该小,因为它会进入一个小地方 - 表格单元格。换句话说,当您第一次收到图片时,您应该先收缩图片,这样您就可以在每次图片的版本时提出要求。这是一个巨大的时间和记忆的浪费,提供一个大的形象,进入一个小空间。



后来:当然你明白了很多如果不将映像保存到磁盘,这种担心是不必要的。我不清楚为什么你需要这样做。我希望你有一个很好的理由;但是它是一个快了很多,显然,如果你只是把内存中的图像准备好。


I have my own image downloader class, it holds a queue and downloads images one (or a certain amount) at a time, writes them to the cache folder and retrieves them from the cache folder when necessary. I also have a UIImageView subclass to which I can pass a URL, through the image downloader class it will look if the image already exists on the device and show it if it does, or download and show it after it finished.

After an image finishes downloading I do the following. I create a UIImage from the downloaded NSData, save the downloaded NSData to disk and return the UIImage.

// This is executed in a background thread
downloadedImage = [UIImage imageWithData:downloadedData];
BOOL saved = [fileManager createFileAtPath:filePath contents:downloadedData attributes:attributes];
// Send downloadedImage to the main thread and do something with it

To retrieve an existing image I do this.

// This is executed in a background thread
if ([fileManager fileExistsAtPath:filePath])
{
    NSData* imageData = [fileManager contentsAtPath:filePath];
    retrievedImage = [UIImage imageWithData:imageData];
    // Send retrievedImage to the main thread and do something with it
}

As you can see, I always create a UIImage directly from the downloaded NSData, I never create NSData using UIImagePNGRepresentation so the image never gets compressed. When you create a UIImage from compressed NSData, UIImage will decompress it right before rendering on the main thread and thus block the UI. Since I'm now having a UITableView with a ton of small images in it that have to be downloaded or retrieved from disk, this would be unacceptable as it would slow down my scrolling immensely.

Now my problem. The user is also able to select a photo from the camera roll, save it and it also has to appear in my UITableView. But I can't seem to find a way to turn the UIImage from the camera roll into NSData without using UIImagePNGRepresentation. So here's my question.

How can I convert a UIImage into uncompressed NSData so I can convert it back to a UIImage later using imageWithData so that it doesn't have to be decompressed before rendering?

or

Is there any way I can do the decompression before sending the UIImage to the main thread and cache it so it only has to be decompressed once?

Thanks in advance.

解决方案

How can I convert a UIImage into uncompressed NSData so I can convert it back to a UIImage later using imageWithData so that it doesn't have to be decompressed before rendering?

What you're really asking here, I take it, is how to store the UIImage on disk in such a way that you can later read the UIImage from disk as fast as possible. You don't really care whether it is stored as NSData; you just want to be able to read it quickly. I suggest you use the ImageIO framework. Save by way of an image destination and fetch later by way of an image source.

http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/ImageIOGuide/ikpg_dest/ikpg_dest.html

Is there any way I can do the decompression before sending the UIImage to the main thread and cache it so it only has to be decompressed once?

Yes, good question. That was going to be my second suggestion: use threading. This is what people have to do with tables all the time. When the table asks for the image, you either have the image already or you don't. If you don't, you supply a filler image and, in the background, fetch the real image. When the real image is ready, you have arranged to get a notification. Back on the main thread, you tell the table view to ask for the data for that row again; this time you've got the image and you supply it. The user will thus see a slight delay before the image appears. I'm sure you've seen lots of apps that behave this way (New York Times is a good example).

I have one further suggestion, and it may be the best of all. You speak of it taking time to decompress the image from disk. But this should take no time at all if the image is small. But the image should be small, because it's going to go into a small place - a table cell. In other words, you should shrink the images beforehand, when you first receive them, so that you are ready with the small version of each image when asked. It is a huge waste of time and memory to supply a large image that is to go into a small space.

ADDED LATER: Of course you do understand that a lot of this worry would be unnecessary if you weren't saving the images to disk. I'm not at all clear on why you need to do that. I hope you have a good reason for it; but it's a heck of a lot faster, obviously, if you just hold the images ready in memory.

这篇关于UIImage到raw NSData /避免压缩的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆