I'm trying to get an image from an URL and it doesn't seem to be working for me. Can someone point me in the right direction?
Here is my code:
NSURL *url = [NSURL URLWithString:#"http://myurl/mypic.jpg"];
NSString *newIMAGE = [[NSString alloc] initWithContentsOfURL:url
encoding:NSUTF8StringEncoding error:nil];
cell.image = [UIImage imageNamed:newIMAGE];
When I debug the newIMAGE string is nil so something isn't working there.
What you want is to get the image data, then initialize a UIImage using that data:
NSData * imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: #"http://myurl/mypic.jpg"]];
cell.image = [UIImage imageWithData: imageData];
[imageData release];
As requested, here's an asynchronous version:
dispatch_async(dispatch_get_global_queue(0,0), ^{
NSData * data = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: #"http://myurl/mypic.jpg"]];
if ( data == nil )
return;
dispatch_async(dispatch_get_main_queue(), ^{
// WARNING: is the cell still using the same data by this point??
cell.image = [UIImage imageWithData: data];
});
[data release];
});
Ok there's a couple of things wrong here:
The conversion from URL (url) to NSString (newImage) is incorrect, what the code actually does there is try to load the contents of "http://myurl/mypic.jpg" into the NSString.
The -imageNamed method takes a string that is a path of a local file, not a URL as an argument.
You need to use an NSData object as an intermediary, like in this example:
http://blogs.oreilly.com/digitalmedia/2008/02/creating-an-uiimage-from-a-url.html
the accepted answer asynchronous version worked very slow in my code. an approach using NSOperation worked light years faster. the code provided by Joe Masilotti --> objective - C : Loading image from URL? (and pasted below):
-(void) someMethod {
// set placeholder image
UIImage* memberPhoto = [UIImage imageNamed:#"place_holder_image.png"];
// retrieve image for cell in using NSOperation
NSURL *url = [NSURL URLWithString:group.photo_link[indexPath.row]];
[self loadImage:url];
}
- (void)loadImage:(NSURL *)imageURL
{
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc]
initWithTarget:self
selector:#selector(requestRemoteImage:)
object:imageURL];
[queue addOperation:operation];
}
- (void)requestRemoteImage:(NSURL *)imageURL
{
NSData *imageData = [[NSData alloc] initWithContentsOfURL:imageURL];
UIImage *image = [[UIImage alloc] initWithData:imageData];
[self performSelectorOnMainThread:#selector(placeImageInUI:) withObject:image waitUntilDone:YES];
}
- (void)placeImageInUI:(UIImage *)image
{
[self.memberPhotoImage setImage:image];
}
In Swift 3 and 4
let theURL = URL(string:"https://exampleURL.com")
let imagedData = NSData(contentsOf: theURL!)!
let theImage = UIImage(data: imagedData as Data)
cell.theImageView.image = theImage
This will be done in the main thread.
And to perform the same in asynchronous/background thread
DispatchQueue.main.async(){
let theURL = URL(string:"https://exampleURL.com")
let imagedData = NSData(contentsOf: theURL!)!
let theImage = UIImage(data: imagedData as Data)
}
cell.theImageView.image = theImage
Updating upon Jim dovey answer,[data release] is no longer required because in the updated apple guidelines. Memory management is done automatically by ARC (Automatic counting reference) ,
Here is the updated asynchronous call,
dispatch_async(dispatch_get_global_queue(0,0), ^{
NSData * data = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: #"your_URL"]];
if ( data == nil )
return;
dispatch_async(dispatch_get_main_queue(), ^{
self.your_UIimage.image = [UIImage imageWithData: data];
});
});
Related
Please try to understand my question.
i am picking images from phone library and saving into Documents Directory. But When I pick large number of images the utilised memory increases gradually and reach above of 400 mb then my app crash. Please if anybody can solve my problem what should I do? I'm new comer to Objective C. Any response will be appreciated.
here is my code
when Picker finish picking
- (void)agImagePickerController:(AGImagePickerController *)picker didFinishPickingMediaWithInfo:(NSArray *)info {
[self ShowLoadingView:#"Files Are Loading...."];
[self performSelectorInBackground:#selector(saveAllSelectedImages:) withObject:info];}
and then I save images to Directory
-(void) saveAllSelectedImages:(NSArray*)imagesArray{
for (int i=0; i<imagesArray.count; i++) {
ALAsset *asset = [imagesArray objectAtIndex:i];
ALAssetRepresentation *alassetRep = [asset defaultRepresentation];
NSDate *currentDate = [NSDate date];
NSString* DucPath = [[AppDelegate GetDocumentDirectoryPath] stringByAppendingPathComponent:#"Media"];
if (![[NSFileManager defaultManager] fileExistsAtPath:DucPath])
[[NSFileManager defaultManager] createDirectoryAtPath:DucPath withIntermediateDirectories:NO attributes:nil error:nil];
if ([[asset valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypeVideo])
{
long long DataSize = [alassetRep size];
Byte *buffer = (Byte*)malloc(DataSize);
NSUInteger buffered = (NSUInteger)[alassetRep getBytes:buffer fromOffset:0.0 length:alassetRep.size error:nil];
NSData *videoData = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
NSString* newVideoName = [NSString stringWithFormat:#"video_%d_%d.mov",(int)currentDate,i];
NSString* newVideoPath = [DucPath stringByAppendingPathComponent:newVideoName];
[videoData writeToFile:newVideoPath atomically:YES];
[pImageMediaArray addObject:newVideoName];
}
else
{
UIImage *image = [UIImage imageWithCGImage:[alassetRep fullResolutionImage]];
/************************************Full Resolution Images ******************************************/
NSData *imageData = UIImageJPEGRepresentation(image, 0.8);
image = nil;
NSString *originalPath = [NSString stringWithFormat:#"IMAGE_%d_%d.jpg",(int)currentDate,i];
NSString* pImagePath = [DucPath stringByAppendingPathComponent:originalPath];
[imageData writeToFile:pImagePath atomically:YES];
[pImageMediaArray addObject:originalPath];
}
/************************************Low Resolution Images ******************************************/
UIImage *image = [UIImage imageWithCGImage:[alassetRep fullResolutionImage]];
UIImage *thumbImage = [self imageWithImage:image scaledToSize:CGSizeMake(50, 50)];
NSData *thumbImageData = UIImageJPEGRepresentation(thumbImage, 0.8);
NSString *thumbOriginalPath = [NSString stringWithFormat:#"SMALL_IMAGE_%d_%d.jpg",(int)currentDate,i];
NSString* thumbImagePath = [DucPath stringByAppendingPathComponent:thumbOriginalPath];
NSLog(#"Image path At Save Time:%#",thumbImagePath);
[thumbImageData writeToFile:thumbImagePath atomically:YES];
[pMediaArray addObject:thumbOriginalPath];
}
[appDelegate setPMediaArray:pImageMediaArray];
[pGridView reloadData];
imagesArray = nil;
[imagesArray release];
[pImageMediaArray release];
[self performSelectorOnMainThread:#selector(closeLoadindView) withObject:nil waitUntilDone:YES];}
Byte *buffer = (Byte*)malloc(DataSize);
is not being freed?
I had the same exact same issue. What worked for me was to use an autorelease pool block when you save the image. This will free up the retain count and the garbage collection will release the memory appropriately instead of retaining those objects in memory until the containing loop is finished running.
Example: In the method that you are using to save the images add code that looks like this:
#autoreleasepool {
NSString *filePath = [[NSArray arrayWithObjects:self.imagePath, #"/", GUID, #".png", nil] componentsJoinedByString:#""];
NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(image)];
BOOL res = [imageData writeToFile:filePath atomically:YES];
imageData = nil;
}
You need to add the autoreleasepool for task that perform in the background. In the above code content of the saveAllSelectedImages should be written inside autoreleasepool, Otherwise memory won't be released.
I am using this for reference: Getting thumbnail from a video url or data in IPhone SDK
The method is using the MPMoviePlayerController class instead of the AVFoundation, and I think I want to use that as well because the people said that MPMoviePlayer way is faster than the AVFoundation way.
The problem is, the method used to create the thumbnails, [player thumbnailImageAtTime:1.0 timeOption:MPMovieTimeOptionNearestKeyFrame] is deprecated in iOS 7.0.
By looking at the apple docs, the remaining supported ways to create thumbnails are by the methods (void)requestThumbnailImagesAtTimes:(NSArray *)playbackTimes timeOption:(MPMovieTimeOption)option and (void)cancelAllThumbnailImageRequests. But, as the method signatures dictate, these methods return nothing. So how do I access the UIImage thumbnail created by these methods?
If it helps, this is what I have so far in terms of code:
self.videoURL = info[UIImagePickerControllerMediaURL];
NSData *videoData = [NSData dataWithContentsOfURL:self.videoURL];
//Create thumbnail image
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:self.videoURL];
[player requestThumbnailImagesAtTimes:#[#1] timeOption:MPMovieTimeOptionNearestKeyFrame];
//UIImage *thumbnail = ???
How do I get a UIImage reference to the thumbnail?
EDIT
I figured out how to create a notification for the thumbnail image request (using this question as reference). However, I realise that this method works asynchronously from the main thread, and so my notification handler method doesn't seem to ever be called.
This is what I have now.
self.videoURL = info[UIImagePickerControllerMediaURL];
NSData *videoData = [NSData dataWithContentsOfURL:self.videoURL];
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:self.videoURL];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleThumbnailImageRequestFinishNotification:) name:MPMoviePlayerThumbnailImageRequestDidFinishNotification object:player];
[player requestThumbnailImagesAtTimes:#[#1] timeOption:MPMovieTimeOptionNearestKeyFrame];
And then my handler method:
-(void)handleThumbnailImageRequestFinishNotification:(NSNotification*)notification
{
NSDictionary *userinfo = [notification userInfo];
NSError* value = [userinfo objectForKey:MPMoviePlayerThumbnailErrorKey];
if (value != nil)
{
NSLog(#"Error creating video thumbnail image. Details: %#", [value debugDescription]);
}
else
{
UIImage *thumbnail = [userinfo valueForKey:MPMoviePlayerThumbnailImageKey];
}
But the handler never gets called (or so it appears).
Try this way.
import AVFoundation framework
in *.h
#import <AVFoundation/AVFoundation.h>
in *.m
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:self.urlForConevW options:nil];
AVAssetImageGenerator *generateImg = [[AVAssetImageGenerator alloc] initWithAsset:asset];
NSError *error = NULL;
CMTime time = CMTimeMake(1, 65);
CGImageRef refImg = [generateImg copyCGImageAtTime:time actualTime:NULL error:&error];
NSLog(#"error==%#, Refimage==%#", error, refImg);
UIImage *FrameImage= [[UIImage alloc] initWithCGImage:refImg];
Here is a code to make a thumbnail of the video and save the images to the DocumentDirectory..
//pass the video_path to NSURL
NSURL *videoURL = [NSURL fileURLWithPath:strVideoPath];
AVURLAsset *asset1 = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset1];
generator.appliesPreferredTrackTransform = YES;
//Set the time and size of thumbnail for image
NSError *err = NULL;
CMTime thumbTime = CMTimeMakeWithSeconds(0,30);
CGSize maxSize = CGSizeMake(425,355);
generator.maximumSize = maxSize;
CGImageRef imgRef = [generator copyCGImageAtTime:thumbTime actualTime:NULL error:&err];
UIImage *thumbnail = [[UIImage alloc] initWithCGImage:imgRef];
//And you can save the image to the DocumentDirectory
NSData *data = UIImagePNGRepresentation(thumbnail);
//Path for the documentDirectory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
[data writeToFile:[documentsDirectory stringByAppendingPathComponent:currentFileName] atomically:YES];
If your URL is to an HTTP live stream, then it won't return anything, per the docs. For a file URL, I found that I had to start the request after playing the movie, or it would never get called.
I want image on view by fetching it from some url. I want changing in given code..
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
UIImage *image = [[UIImage imageNamed:<#(NSString *)name#>
NSString * mediaUrl = [[[self appDelegate]currentlySelectedBlogItem]mediaUrl];
[[self image]setImage:[UIImage imageNamed:#"unknown.jpg"]];
if(nil != mediaUrl){
NSData* imageData;
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
#try {
imageData = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:mediaUrl]];
}
#catch (NSException * e) {
//Some error while downloading data
}
#finally {
UIImage * imageFromImageData = [[UIImage alloc] initWithData:imageData];
[[self image]setImage:imageFromImageData];
[imageData release];
[imageFromImageData release];
}
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
self.titleTextView.text = [[[self appDelegate] currentlySelectedBlogItem]title];
self.descriptionTextView.text = [[[self appDelegate] currentlySelectedBlogItem]description];
}
Using this will give you a solution
NSURL *url = [NSURL URLWithString:#"ENTER YOUR URL HAVING THE IMAGE"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
I have used the following:
NSString *url=[NSString stringWithFormat:#"Your URL"];
//NSLog(#"URL=%#",url);
UIImage *myImage=[[UIImage alloc] initWithData:[NSData UIImage *myImage=[[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString: url]]];
NSLog(#"%d byte of data", [[NSData dataWithContentsOfURL: [NSURL URLWithString: url]] length]);
if (myImage)
{
//THIS CODE WILL STORE IMAGE DOCUMENT DIRECTORY
NSString *jpegFilePath = [NSString stringWithFormat:#"%#/%#.jpg",[self pathForDocumentDirectory],[self.idOfImagesToDownload objectAtIndex:i]];
NSData *data1 = [NSData dataWithData:UIImageJPEGRepresentation(myImage, 1.0f)];//1.0f = 100% quality
[data1 writeToFile:jpegFilePath atomically:YES];
}
NOTE:[self pathForDocumentDirectory] is method returning path of document directory.
Can anybody tell me excatly how I should execute this method on an NSURL object?
URLByResolvingSymlinksInPath
Compiler says that the method can't be found when I execute it.
Thanks a lot.
This is where I am trying to implement the code:
- (void)data
{
NSURL *url = [[NSURL alloc] initWithString: [[user data] objectAtIndex: 5]];
NSURL * url2 = [[NSURL alloc] init];
url2 = [url URLByResolvingSymlinksInPath];
NSData *newImage = [[NSData alloc] initWithContentsOfURL:url2];
NSImage *image = [[NSImage alloc] initWithData:newImage];
imageView.layer.masksToBounds = YES;
imageView.layer.cornerRadius = 3.0;
[imageView setImage:image];
[user autorelease];
}
Assuming that you have NSURL named something like myURLWithSymlinks, you would do something like:
NSURL * myURLWithoutSymlinks = [myURLWithSymlinks URLByResolvingSymlinksInPath];
Note that according to the docs, URLByResolvingSymlinksInPath is only available in iOS4.0 or above and MacOSX 10.6. If you are using an older version of iOS (or MacOSX), that could be the cause of your problem.
i have a stupid question...sometimes i see developers use the following code...
NSString *newURL = [_parameters objectForKey:#"url"];
when i use this i get error... here what is _parameters and how to declare it??
i can provide more example..
NSLog(#"SaveImage Called");
//google code for turning base64 into uiimage
NSURL *url = [NSURL URLWithString:[self._parameters objectForKey:#"imageData"]];
NSData *imageData = [NSData dataWithContentsOfURL:url];
UIImage *img = [UIImage imageWithData:imageData];
/*
if(img != nil) {
UIImageWriteToSavedPhotosAlbum(img, self, nil, nil);
}
*/
_parameters is a NSDictionary that seems to be defined previously in the code, e.g.
NSDictionary _parameters = [NSDictionary dictionaryWithObjects:#"foo", #"bar", nil
forKeys:#"url", #"host", nil];
What exactly is your question? How is this related to JavaScript (edit: question was tagged as javascript)? You know that the language you use is Objective-C ?