Load low resolution image and progressive load of

2020-07-31 11:21发布

问题:

How do I display a low resolution image on a page and then after a second delay load a high resolution version? Is this done with layers? Threads?

回答1:

I know this post is old, but just in case someone is looking for it, there is a project called NYXImagesKit that does what you are looking for.

It has a class named NYXProgressiveImageView that is a subclass of UIImageView.

All you have to do is:

NYXProgressiveImageView * imgv = [[NYXProgressiveImageView alloc] init];
imgv.frame = CGRectMake(0, 0, 320, 480);
[imgv loadImageAtURL:[NSURL URLWithString:@"http://yourimage"]];
[self.view addSubview:imgv];
[imgv release];

Also, a good option is to save your images as interlaced so that it loads with low quality and improve with the download. If the image is normal it is loaded from top to bottom.



回答2:

There are several options:

1) Save the images on the server in a format that supports progressive download (progressive JPEG, interlaced PNG). I think you’d have to come up with a special support on the client, ie. write the image decoding part from PNG/JPEG to UIImage yourself, presumably using some library.

2) Save a small thumbnail along each image on the server. When you want to download an image, you’d first download the thumbnail, do a simple scaling to stretch it to the full image size and in the meantime download the full version. There can be multiple thumbnails in various sizes if you really want to get fancy. You’ll have more data on the server, but the client code should be fairly straightforward.

3) Maybe you already have the thumbnails on the client? In that case you can stretch the thumbnail to the full image size to create a low-resolution version while you load the rest.

And if you are asking about how to exactly code the second or third solution… You don’t really need explicit threads and I’m not sure what does “layer” mean in this context. Loading an UIImage from network is pretty easy, a bit like this:

 NSURL *url = [NSURL URLWithString:@"http://somewhere/foo.png"];
 NSURLRequest *request = [NSURLRequest requestWithURL:url];
 NSData *data = [NSURLConnection sendSynchronousRequest:request
    returningResponse:NULL error:NULL];
 UIImage *image = [UIImage imageWithData:data];

You can turn this code into a function, load and display the thumbnail and then load and display the full image. All this could be done in background so that you can do something while the data is loading.



回答3:

In general this feature is achieved with image files saved in some interlaced/progessive mode. This allows the displaying application (i.e. browser) to display the image successively starting in a low quality as the first chunks of data arrive. The more of the data is available, the higher the quality of the image gets.

This feature is independent of the web server. Only the client application is responsible of supporting this mode

This site shows some examples.



回答4:

It sounds like you a describing something like the TTPhotoViewController from Three20 (used in the Facebook iPhone app). When you first start looking at an image it's simply a thumbnail that has been stretched out. The "high res" version is being downloaded in the background, and when that download is complete it replaces the existing stretched image.



回答5:

I was able to download with afnetworking.I used the below code

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath =  [[paths objectAtIndex:0] stringByAppendingPathComponent:@"tempPath"];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"yourUrl"]];

AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:filePath append:NO];

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    self.actualImage = [UIImage imageWithData:[NSData dataWithContentsOfFile:filePath]];

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
    [imageView setImage:[UIImage imageWithData:[NSData dataWithContentsOfFile:filePath]]];
    self.actualImage = [UIImage imageWithData:[NSData dataWithContentsOfFile:filePath]];

}];

[operation start];