use the following functions to get image from web url or main bundle
TRANSCRIPT
Use the following functions to get Image from Web URL or Main Bundle (Resource Folder) or Document Directory
// From URL
-(UIImage *) getImageFromURL : (NSString *) urlString
{
NSURL *pathURL = [NSURL URLWithString: urlString];
NSData *imageData = [NSData dataWithContentOfURL:pathURL];
UIImage *getImage = [[UIImage alloc]initWithData:imageData];
return getImage;
}
// From Bundle
-(UIImage *) getImageFromResources_FileName: (NSString *)file_Name andFileType: (NSString *) file_Extension
{
NSString *filePath = [[NSBundle mainBundle] pathForResource : file_Name ofType: file_Extension];
UIImage *getImage = [UIImage imageWithContentsOfFile:filePath];
return getImage;
}
// From Document Directory (NSDocumentDirectory)
-(UIImage *) getImageFromDocumentDirectory_ImageName:(NSString *) imageName
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);NSString *docDirectory = [paths objectAtIndex:0];
NSString *destPath = [docDirectory stringByAppendingPathComponent:imageName];//image.pngNSURL *url = [NSURL fileURLWithPath:destPath];UIImage *getImage= [manager imageWithURL:url];if (getImage){UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Image" message:@"Found" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];[alertView show];}else{getImage = [UIImage imageNamed:@"defaultImage.png"];UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Image" message:@"Not Found" delegate:nilcancelButtonTitle:@"OK" otherButtonTitles:nil];[alertView show];}
return getImage;}
procedure:
UIImageView *showImage = [[UIImageView alloc] initWithFrame:CGRectMake(20,20,250,250)];
//Calling from Resources Folder
if(Resources)
{
showImage.image = [self getImageFromResources_FileName:@"Niketan" andFileType:@"png"];
}
else if (webURL)
//Calling from URL
{
showImage.image = [self getImageFromURL : @"your url"]; // @"http://www.yourweb.com/pictures/picname=niketan.png";
}
else
//Calling From Document Directory
{
showImage.image = [self getImageFromDocumentDirectory_ImageName: @"Vinay.png"];
}
[self.view addSubview: showImage];
Starting the iOS Application development process :
1)iOS App Dev: Introduction
2) iOS App Dev: Tools
3) iOS App Dev: Language
4) iOS App Dev: Basic Task
5) iOS App Dev: Frameworks & Design Pattrens
6) iOS App Dev: App Store
7) iOS App Dev: Finding Information
8) iOS App Dev: Queries
Use the following functions to get Image from Web URL or Main Bundle (Resource Folder) or Document Directory
// From URL
-(UIImage *) getImageFromURL : (NSString *) urlString
{
NSURL *pathURL = [NSURL URLWithString: urlString];
NSData *imageData = [NSData dataWithContentOfURL:pathURL];
UIImage *getImage = [[UIImage alloc]initWithData:imageData];
return getImage;
}
// From Bundle
-(UIImage *) getImageFromResources_FileName: (NSString *)file_Name andFileType: (NSString *) file_Extension
{
NSString *filePath = [[NSBundle mainBundle] pathForResource : file_Name ofType: file_Extension];
UIImage *getImage = [UIImage imageWithContentsOfFile:filePath];
return getImage;
}
// From Document Directory (NSDocumentDirectory)
-(UIImage *) getImageFromDocumentDirectory_ImageName:(NSString *) imageName
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDirectory = [paths objectAtIndex:0];
NSString *destPath = [docDirectory stringByAppendingPathComponent:imageName];//image.png
NSURL *url = [NSURL fileURLWithPath:destPath];
UIImage *getImage= [manager imageWithURL:url];
if (getImage)
{
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Image" message:@"Found" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}
else
{
getImage = [UIImage imageNamed:@"defaultImage.png"];
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Image" message:@"Not Found" delegate:nil
cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
}
return getImage;
}
procedure:
UIImageView *showImage = [[UIImageView alloc] initWithFrame:CGRectMake(20,20,250,250)];
//Calling from Resources Folder
if(Resources)
{
showImage.image = [self getImageFromResources_FileName:@"Niketan" andFileType:@"png"];
}
else if (webURL)
//Calling from URL
{
showImage.image = [self getImageFromURL : @"your url"]; // @"http://www.yourweb.com/pictures/picname=niketan.png";
}
else
//Calling From Document Directory
{
showImage.image = [self getImageFromDocumentDirectory_ImageName: @"Vinay.png"];
}
[self.view addSubview: showImage];
//
// UIImage-Extensions.h
//
// Created by Hardy Macia on 7/1/09.
// Copyright 2009 Catamount Software. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface UIImage (CS_Extensions)
- (UIImage *)imageAtRect:(CGRect)rect;
- (UIImage *)imageByScalingProportionallyToMinimumSize:(CGSize)targetSize;
- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize;
- (UIImage *)imageByScalingToSize:(CGSize)targetSize;
- (UIImage *)imageRotatedByRadians:(CGFloat)radians;
- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees;
@end;
//
// UIImage-Extensions.m
//
// Created by Hardy Macia on 7/1/09.
// Copyright 2009 Catamount Software. All rights reserved.
//
#import "UIImage-Extensions.h"
CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
CGFloat RadiansToDegrees(CGFloat radians) {return radians * 180/M_PI;};
@implementation UIImage (CS_Extensions)
-(UIImage *)imageAtRect:(CGRect)rect
{
CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], rect);
UIImage* subImage = [UIImage imageWithCGImage: imageRef];
CGImageRelease(imageRef);
return subImage;
}
- (UIImage *)imageByScalingProportionallyToMinimumSize:(CGSize)targetSize {
UIImage *sourceImage = self;
UIImage *newImage = nil;
CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;
CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;
CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
if (CGSizeEqualToSize(imageSize, targetSize) == NO) {
CGFloat widthFactor = targetWidth / width;
CGFloat heightFactor = targetHeight / height;
if (widthFactor > heightFactor)
scaleFactor = widthFactor;
else
scaleFactor = heightFactor;
scaledWidth = width * scaleFactor;
scaledHeight = height * scaleFactor;
// center the image
if (widthFactor > heightFactor) {
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
} else if (widthFactor < heightFactor) {
thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
}
}
// this is actually the interesting part:
UIGraphicsBeginImageContext(targetSize);
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width = scaledWidth;
thumbnailRect.size.height = scaledHeight;
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
if(newImage == nil) NSLog(@"could not scale image");
return newImage ;
}
- (UIImage *)imageByScalingProportionallyToSize:(CGSize)targetSize {
UIImage *sourceImage = self;
UIImage *newImage = nil;
CGSize imageSize = sourceImage.size;
CGFloat width = imageSize.width;
CGFloat height = imageSize.height;
CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;
CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;
CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
if (CGSizeEqualToSize(imageSize, targetSize) == NO) {
CGFloat widthFactor = targetWidth / width;
CGFloat heightFactor = targetHeight / height;
if (widthFactor < heightFactor)
scaleFactor = widthFactor;
else
scaleFactor = heightFactor;
scaledWidth = width * scaleFactor;
scaledHeight = height * scaleFactor;
// center the image
if (widthFactor < heightFactor) {
thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
} else if (widthFactor > heightFactor) {
thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
}
}
// this is actually the interesting part:
UIGraphicsBeginImageContext(targetSize);
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width = scaledWidth;
thumbnailRect.size.height = scaledHeight;
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
if(newImage == nil) NSLog(@"could not scale image");
return newImage ;
}
- (UIImage *)imageByScalingToSize:(CGSize)targetSize {
UIImage *sourceImage = self;
UIImage *newImage = nil;
// CGSize imageSize = sourceImage.size;
// CGFloat width = imageSize.width;
// CGFloat height = imageSize.height;
CGFloat targetWidth = targetSize.width;
CGFloat targetHeight = targetSize.height;
// CGFloat scaleFactor = 0.0;
CGFloat scaledWidth = targetWidth;
CGFloat scaledHeight = targetHeight;
CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
// this is actually the interesting part:
UIGraphicsBeginImageContext(targetSize);
CGRect thumbnailRect = CGRectZero;
thumbnailRect.origin = thumbnailPoint;
thumbnailRect.size.width = scaledWidth;
thumbnailRect.size.height = scaledHeight;
[sourceImage drawInRect:thumbnailRect];
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
if(newImage == nil) NSLog(@"could not scale image");
return newImage ;
}
- (UIImage *)imageRotatedByRadians:(CGFloat)radians
{
return [self imageRotatedByDegrees:RadiansToDegrees(radians)];
}
- (UIImage *)imageRotatedByDegrees:(CGFloat)degrees
{
// calculate the size of the rotated view's containing box for our drawing space
UIView *rotatedViewBox = [[UIView alloc] initWithFrame:CGRectMake(0,0,self.size.width, self.size.height)];
CGAffineTransform t = CGAffineTransformMakeRotation(DegreesToRadians(degrees));
rotatedViewBox.transform = t;
CGSize rotatedSize = rotatedViewBox.frame.size;
[rotatedViewBox release];
// Create the bitmap context
UIGraphicsBeginImageContext(rotatedSize);
CGContextRef bitmap = UIGraphicsGetCurrentContext();
// Move the origin to the middle of the image so we will rotate and scale around the center.
CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);
// // Rotate the image context
CGContextRotateCTM(bitmap, DegreesToRadians(degrees));
// Now, draw the rotated/scaled image into the context
CGContextScaleCTM(bitmap, 1.0, -1.0);
CGContextDrawImage(bitmap, CGRectMake(-self.size.width / 2, -self.size.height / 2, self.size.width, self.size.height), [self CGImage]);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
@end;
Stack Exchange log in | careers | chat | meta | about | faq
Stack Overflow
Questions Tags Users Badges Unanswered
Ask Question
UIImage to be displayed progressively from serverup vote 14 down vote favorite6
I have been trying to display large image from server, but I have to display it progressively.
I used subclass of UIView and in that I have taken UIImage object, in which I used
NSURLConnection and its delegate methods, I also used
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
in which I am appending data and converting it to UIImage object, and drawing rect using the drawInRect: method of UIImage.
Everything is working fine, but the problem is, when image is being drawn on context, I cannot click anywhere else on screen until entire image is being drawn on to screen.
Is there any good solution, where I can click anywhere else even if image is being drawn on screen?
Any help will be appreciable.
Edit: Is there any efficient way of drawing image blurry progressively in didReceiveData? so drawInRect does not take too much time to draw. Or If anyone has custom drawRect method which efficiently displays image progressively as data received in didReceiveData.
iphone uiimageview uiimage http-headers nsurlconnection
link|improve this question
edited Mar 18 at 20:53
Emil2,64112164
asked Feb 28 at 7:56
Jignesh Brahmkhatri1,0631314
38% accept rate
2How about running the process in background thread ? – Shivan Raptor Feb 28 at 7:58I tried running process in background, but it crashes, because we cannot draw image on screen in background thread, it should be in main thread. – Jignesh Brahmkhatri Feb 28 at 8:00the problem here is that you're redrawing the image constantly and this prevent the UI to be responsible. What you can do is to "filter" redraw, doing it each 10 or 50 iteration of didReceiveData. – Junior B. Feb 28 at 8:13yes, you are absolutely right, drawing image in didReceiveData so many times, creates issue. Is there any other soution to draw image progressively? – Jignesh Brahmkhatri Feb 28 at 8:27If your images are in jpeg format, have you tried using progressive jpegs (faqs.org/faqs/jpeg-faq/part1/section-11.html)? I have no idea if that will help,
but you could try. – Andrew Morton Mar 18 at 20:20show 1 more commentfeedback
10 Answers
active oldest votes up vote 7 down vote+50
I suggest pulling the image data in an asynchronous manner and then applying a correction in order to obtain a valid conversion from partially downloaded NSData to an UIImage:
NSURLRequest *theRequest = [NSURLRequest requestWithURL: [NSURL URLWithString: imageRequestString] cachePolicy: NSURLRequestReloadIgnoringCacheData timeoutInterval: 60.0];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest: theRequest delegate: self];
if (theConnection) receivedData = [[NSMutableData data] retain];
.......
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [receivedData appendData: data];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget: self selector: @selector(loadPartialImage) object: nil]; [[[NSOperationQueue alloc] init] autorelease] addOperation: operation]; [operation release];}
- (void)loadPartialImage { // This is where you would call the function that would "stitch up" your partial // data and make it appropriate for use in UIImage's imageWithData NSData *validPartialData = [self validImageRepresentationFromPartialImageData: receivedData];
UIImage *partialImage = [UIImage imageWithData: validPartialData];
[imageView performSelectorOnMainThread: @selector(setImage:) withObject: partialImage
waitUntilDone: NO];}
+ (void)connectionDidFinishLoading:(NSURLConnection *)connection { [connection release];
UIImage *fullImage = [UIImage imageWithData: receivedData];
imageView.image = fullImage;}
Note that I did not provide the code for validImageRepresentationFromPartialImageData, as, at the moment, I have no clear, specific idea, on how to implement such a correction, or if the [UIImage imageWithData:] wouldn't actually accept partial data as input by default. As you can see, the coercion and UIImage creation would happen on a different thread, while the main thread would only display the updates as they come.
If you are receiving too frequent updates and they are still blocking the interface, you could:
a. Make the image requests on a different thread as well. b. Reduce the frequency of the UIImageView's updates, by only calling setImage once in 10 or 100 updates, according to the zise of your image.
link|improve this answer
answered Mar 2 at 18:51
luvieere13.6k23489
Thanks for your response. Yes, I am doing "a." option mentioned by you, but I am concerning is there any better way to draw images on screen without blocking the interface. May be a better way to draw images so that it takes few time to draw. – Jignesh Brahmkhatri Mar 3 at 6:55
feedbackup vote 4 down vote+100
I have used NYXImagesKit for something similar, downloading images while not blocking the main thread and showing the image progressively. Ive written a really quick and dirty example to illustrate the basic workings. I load the image in a UITableview to show that it doesn't block the User Interface(Main Thread). You can scroll the tableview while the image is loading. Don't forget to add the correct Frameworks, there are a few. Heres the link to the project on Github:
https://github.com/HubertK/ProgressiveImageDownload
It's really easy to use,create a NYXProgressiveImageView object, set the URL and it will
do all the work for you when you call:
loadImageAtURL:
It's a subclass of UIImageView, Works like magic! Here's a link to the developers site:
http://www.cocoaintheshell.com/2012/01/nyximageskit-class-nyxprogressiveimageview/
link|improve this answer
answered Mar 18 at 20:02
Hubert Kunnemeyer1,418147
feedback
up vote 2 down vote
I usually use a really simple GCD pattern for async image loading:
1. Create a GCD queue in which you load the image data form your web server2. Set the image data in your main queue
Example:
dispatch_queue_t image_queue = dispatch_queue_create("com.company.app.imageQueue", NULL);dispatch_queue_t main_queue = dispatch_get_main_queue();
dispatch_async(image_queue, ^{ NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[record imageURLString]]; dispatch_async(main_queue, ^{ [imageView setImage:[UIImage imageWithData:imageData]]; });});
link|improve this answeredited Feb 28 at 14:13
answered Feb 28 at 8:11
moosgummi2,806419
Thanks for your answer, but I have problem when image is being drawn in didReceiveData: method, I cannot click anywhere else on screen. and drawing image should be in main thread, as your answer suggest main queue will also be in main thread, so it will hang until image is not being drawn, because didReceiveData: will be called so many times.... – Jignesh Brahmkhatri Feb 28 at 8:16@JigneshBrahmkhatri Can't you just collect all the image data first and then draw it to
the screen? I guess that's way more efficient – moosgummi Feb 28 at 8:39If I collect all image data and draw image in connectionDidFinishLoading, my concern of showing image progressively will not be accomplished. I want to show image progressively as it appears in didReceiveData... – Jignesh Brahmkhatri Feb 28 at 8:57@JigneshBrahmkhatri Mhh, ok. Maybe you can show a spinner, which indicates a loading progress? I think that's an better approach then blocking your UI thread. – moosgummi Feb 28 at 9:57My first requirement is to show image progressively from server. – Jignesh Brahmkhatri Feb 28 at 11:09
show 3 more commentsfeedback
up vote 2 down vote
Probably didReceiveData is called too often! Just use a NSTimerand update the image regularly in 1-2second steps. That should work more efficiently.
Also you can use performSelectorInBackgroundto convert your NSData to an UIImage; And then call performSelectorOnMainThreadto set the image into the UIImage View. So the converting stuff won't block the main thread.
link|improve this answer
answered Mar 2 at 10:07
jaydee33,1651215
Thanks for replying, I am using alternate solution as you said, but I need proper solution to get it done, because, I will call 40-50 UIImageViews to load from server and will display it progressively. so this solution will also not work. The problem is, it takes too much time in drawing image on screen. – Jignesh Brahmkhatri Mar 2 at 10:17the drawing takes too long!? did you measure that? just reduce the update count like i said. that should work, no? it doesnt matter how much views you load in the end, if you get it right for one of them. just don't redraw on EVERY update from didReceiveData. – jaydee3 Mar 2 at 10:22I update redrawing every 20 times, control comes in didReceiveData, but this is for one image, if 100 images are there then control can come anytime and image will be drawn in main thread, that hangs application until image is being drawn fully. – Jignesh Brahmkhatri Mar 2 at 12:38ok we need more details here. about what imge sizes are you talking? how many of them will be loaded at once? why do you need progressive display? – jaydee3 Mar 2 at 13:54I need progressive display to ensure user that image is being loaded, and This is the first requirement which I cannot leave this requirement. About images, they are coming from server and it can be 10 or 50 – Jignesh Brahmkhatri Mar 2 at 15:06
feedbackup vote Have you considered chopping up your images into smaller chunks on the server, then
2 down vote
redrawing whenever a complete chunk has been received? This would give you control over the "progressiveness" of the load and the frequency of redraws by changing the chunk size. Not sure this is the kind of progressive load you're after, though.
link|improve this answer
answered Mar 2 at 18:59
shawkinaw36219
feedback
up vote 2 down vote
If you have control of the server, split the image into tiles and also create a low res image. Display the low res version first in the lowest layer, and load the tiles on top drawing them as they load?
link|improve this answer
answered Mar 8 at 5:06
Steven Veltema494311
feedbackup vote 2 down vote
You can create a subclass of UIImageView with the URL of the image and a startDownload method. It's a basic sample it must be improved.
@property (nonatomic, strong) NSURL *imageURL;- (void)startDownload;
@implementation ImgeViewSubClass{ NSURLConnection *connection; NSMutableData *imageData;
}
The start download method:
- (void)startDownload{ NSURLRequest *request = [NSURLRequest requestWithURL:imageURL]; connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; [connection start]; imageData = [NSMutableData data];
}
Delegate method from NSURLConnectionDataDelegate
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @synchronized(imageData) { [imageData appendData:data]; }
// this part must be improved using CGImage instead of UIImage because we are not on main thread UIImage *image = [UIImage imageWithData:imageData]; if (image) { [self performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO]; } });
}
link|improve this answeredited Mar 8 at 7:57
answered Mar 8 at 7:18
Julien2935
feedbackup vote 1 down vote
Why don't you use ASIHTTPRequest request.
#import "ASIHTTPRequest.h"
this will help to load/draw in background, can perform other task too...
I m beginer , don't know about drawing but i think this will work...
Try this one :
import "ASIHTTPRequest.h"[self performSelectorInBackground:@selector(DownLoadImageInBackground:) withObject:YOUR IMAGE ARRAY];
-(void) DownLoadImageInBackground:(NSArray *)imgUrlArr1 { NSURL * url = [Image
URL];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];[request setDelegate:self];[request startAsynchronous];
}
-(void)requestFailed:(ASIHTTPRequest *)request
{
NSLog(@"URL Fail : %@",request.url);
NSError *error = [request error];
// you can give here alert too..
}
-(void)requestFinished:(ASIHTTPRequest *)request
{
/////////// Drawing Code Here////////////////////
NSData *responseData = [request responseData]; UIImage *imgInBackground = [[UIImage alloc] initWithData:responseData]; [imageView setImage: imgInBackground];
}
link|improve this answer
answered Mar 2 at 14:56
Rohit Wankhede3747
Thanks for your reply, But I want image to be displayed progressively. Your code will display image only after I receive all data. – Jignesh Brahmkhatri Mar 2 at 15:01I don't have much experience... i think then you can use web view instead of image view. which have its delegate methods . will work on this to display UIImage to be displayed progressively from server... – Rohit Wankhede Mar 6 at 6:17
feedbackup vote I am not sure how the other parts of your code(reg this module) is implemented but give
0 down vote
the following a try,
Try to use this selector with the run loop mode set to NSDefaultRunLoopMode
[self performSelectorOnMainThread:@selector(processImage:) withObject:objParameters waitUntillDone:NO modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]]
This execution will free up your UI interactions, let me know if it helped please.
For more info : APPLE DOCS
link|improve this answer
answered Mar 20 at 4:53
Futur1,4691621
As you have mentioned in the above threads, that you will need to download some where around 40-50 images async, this should help. Let me know abt it, can be a best practice when successful. – Futur Mar 20 at 4:56
feedbackup vote 0 down vote
//JImage.h
#import <Foundation/Foundation.h>
@interface JImage : UIImageView {
NSURLConnection *connection;
NSMutableData* data;
UIActivityIndicatorView *ai;}
-(void)initWithImageAtURL:(NSURL*)url;
@property (nonatomic, retain) NSURLConnection *connection;
@property (nonatomic, retain) NSMutableData* data;
@property (nonatomic, retain) UIActivityIndicatorView *ai;
@end
//JImage.m
#import "JImage.h"
@implementation JImage@synthesize ai,connection, data;
-(void)initWithImageAtURL:(NSURL*)url {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[self setContentMode:UIViewContentModeScaleToFill];
if (!ai){
[self setAi:[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]];
[ai startAnimating];
[ai setFrame:CGRectMake(27.5, 27.5, 20, 20)];
[ai setColor:[UIColor blackColor]];
[self addSubview:ai]; } NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; }
- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)incrementalData {
if (data==nil) data = [[NSMutableData alloc] initWithCapacity:5000];
[data appendData:incrementalData];
NSNumber *resourceLength = [NSNumber numberWithUnsignedInteger:[data length]];
NSLog(@"resourceData length: %d", [resourceLength intValue]);
}- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { NSLog(@"Connection error...");
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[ai removeFromSuperview];
}- (void)connectionDidFinishLoading:(NSURLConnection*)theConnection { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[self setImage:[UIImage imageWithData: data]];
[ai removeFromSuperview]; }@end
//Include the definition in your class where you want to use the image-(UIImageView*)downloadImage:(NSURL*)url:(CGRect)frame {
JImage *photoImage=[[JImage alloc] init];
photoImage.backgroundColor = [UIColor clearColor];
[photoImage setFrame:frame];
[photoImage setContentMode:UIViewContentModeScaleToFill];
[photoImage initWithImageAtURL:url];
return photoImage;}
//call the functionUIImageView *imagV=[self downloadImage:url :rect];
//you can call the downloadImage function in looping statement and subview the returned imageview. //it will help you in lazy loading of images.
//Hope this will help
link|improve this answer
answered Mar 20 at 5:48
Kuldeep1,2661112
Hi Kuldeep, thanks for sharing answer, but this is not the way I want. I want to display image progressively as it retrieves in didReceiveData method. So I want to set image in didReceiveData, which hangs the application till image is set. I want the same
functionality without hanging interaction. – Jignesh Brahmkhatri Mar 20 at 6:04Was this post useful to you?
Your Answer
log in or
Name
Home Page
By posting your answer, you agree to the privacy policy and terms of service.
Not the answer you're looking for? Browse other questions tagged iphone uiimageview uiimage http-headers
nsurlconnection or ask your own question.
tagged
iphone × 141088uiimageview × 2747uiimage × 2461http-headers × 2323nsurlconnection × 1172asked 4 months agoviewed 454 timesactive 3 months ago
Related
UIImage and UIImageView problem Resizing UIimages pulled from the Camera also ROTATES the UIimage? Getting Image from URL/server How to draw a shape on top of a UIImage while respecting the image's alpha mask Create UiImage from NSData Unable to assign images to an imageView from an Array, but can assign images to an imageView from a UIImage variable uiimage allocation problem How to get the filename from a given UIImage object? Problem with setting UIImageView to UIImage from camera (iPhone) UIImage Rotation Can't display UIImage from UIImagePickerController when using IBAction UIImage created from CMSampleBufferRef not displayed in UIImageView? iphone - single UIImage multiple UIImageView? UIImage, releasing the decompression cache? How to delete UIImage from UIImageView? UIImage in a circle UIImage drawAtPoint vs UIImageView origin How to create UIImage from UIWebView UIImage is centred after resize Why not UIImage itself but UIImage view UIImage Is Not Fitting In UIScrollView At Start UIImage from URL difficulty UIImage scale propotionally UIImage VIew Not loading image? UIImageView autoresizingmask, UIImage stretchableImageWithLeftCapWidth question feedabout | faq | blog | chat | data | shop | legal | privacy policy | advertising info | mobile | contact us | feedback
■ stackoverflow.com ■ api/apps ■ careers ■ serverfault.com ■ superuser.com ■ meta
■ area 51 ■ webapps ■ gaming ■ ubuntu ■ webmasters ■ cooking ■ game development
■ math ■ photography ■ stats ■ tex ■ english ■ theoretical cs ■ programmers ■ unix
■ apple ■ wordpress ■ physics ■ home improvement ■ gis ■ electronics ■ android
■ security ■ bicycles ■ dba ■ drupal ■ sharepoint ■ scifi & fantasy ■ user experience
■ skeptics ■ rpg ■ judaism rev 2012.7.13.3355site design / logo © 2012 stack exchange inc; user contributions licensed under cc-wiki with attribution required
By customization we can change look and feel of Navigation Bar. Below is sample code which demonstrates how to customize Navigation Bar.
We can achieve this by using Categories in Objective-C:Code Sample:
/*********************************************************/
@interface UINavigationBar (CustomNavBarImage)
- (void) setNavBackgroundImage:(UIImage*)bgImage;
- (void) clearNavBackgroundImage;
@end
/************************************************************/
//.m file (Implementaion file)
#import "UINavigationBar+CustomNavBarImage.h"
@implementation UINavigationBar (CustomNavBarImage)
- (void) setNavBackgroundImage:(UIImage*)bgImage{
if (bgImage == NULL)
return;
UIImageView *myImageView= [[UIImageView alloc] initWithImage:bgImage];
myImageView.frame = CGRectMake(0,0,320,44);
[self addSubview:myImageView];
[myImageView release];
// If You want to add some buttons and title go through that
//[myImageView release];
UIButton *addButton = [UIButton buttonWithType: UIButtonTypeRoundedRect];//UIButtonTypeCustom
addButton .frame = CGRectMake(10, 0, 100, 44);
[addButton setTitle:@"Add" forState:UIControlStateNormal];
[addButton addTarget:self action:@selector(clickOnAddButton:) forControlEvents:UIControlEventTouchUpInside];
//Font size of title
addButton.titleLabel.font = [UIFont boldSystemFontOfSize:14];
[myImageView addSubview:addButton];
myImageView.userInteractionEnable = YES;
}
- (void) clearNavBackgroundImage {
NSArray *subviewsArray = [self subviews];
for (int i=0; i<[subviewsArray count]; i++)
{
if ([[subviewsArray objectAtIndex:i] isMemberOfClass:[UIImageView class]])
{
[[subviewsArray objectAtIndex:i] removeFromSuperview];
}
}
}
@end
// Calling
[[self.navigationController navigationBar] performSelectorInBackground:@selector(setNavBackgroundImage:) withObject:bgImage];
Second Simple Way : (Without Categories)
// Set first this : self.NavigationController.navigationBarHidden = YES;
-(void) setCustomNavBar
{
UIImageView *myImage = [[UIImageView alloc] initWithFrame:CGRectMake (0,0,320,44)];
// set your background image name like NavBarImage.png
myImage.image = [UIImage imageNamed:@"yourBGImage"];
myImage.backgroundColor = [UIColor clearColor];
[self.view addSubview: myImage];
UIButton *addButton = [UIButton buttonWithType: UIButtonTypeRoundedRect];//UIButtonTypeCustom
addButton .frame = CGRectMake(10, 0, 100, 44);
[addButton setTitle:@"Add" forState:UIControlStateNormal];
[addButton addTarget:self action:@selector(clickOnAddButton:) forControlEvents:UIControlEventTouchUpInside];
//Font size of title
addButton.titleLabel.font = [UIFont boldSystemFontOfSize:14];
[myImage addSubview:addButton];
myImage.userInteractionEnable = YES;
}
//Called this function on viewdidload or loadView or viewWillAppear (according to your preference).
[self performSelector:@selector(setCustomNavBar)];