In my iOS Application, I want to show a Gif image in my tableViewCell. Download this Gif image by SDWebImage, and use FLAnimatedImageView to show this image.
But now I have a problem, SDWebImage return a images ,but the FLAnimatedImageView want a NSData.
How to convert images of gif to NSData?
Forgive my poor English.
[[SDWebImageManager sharedManager] downloadImageWithURL:url options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (image.images.count > 0)//gif
{
// how to get the data
FLAnimatedImage *animatedImage = [FLAnimatedImage animatedImageWithGIFData:data];
_chatGIFImage.animatedImage = animatedImage1;
}
}];
If you have the URL of the image you can directly use the following to convert it to NSData
NSData *data = [NSData dataWithContentsOfURL: imageURL];
You can do something like below:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSError* error = nil;
NSData* ImageData = [NSData dataWithContentsOfURL:yourIMGUrl options:NSDataReadingUncached error:&error];
if (error) {
NSLog(#"%#", [error localizedDescription]);
} else {
NSLog(#"successfull.");
dispatch_sync(dispatch_get_main_queue(), ^{
FLAnimatedImage *animatedImage = [FLAnimatedImage animatedImageWithGIFData:ImageData];
_chatGIFImage.animatedImage = animatedImage1;
});
}
});
You can simply use
// UIImageJPEGRepresentation(<#UIImage * _Nonnull image#>, <#CGFloat compressionQuality#>)
NSData *data = UIImageJPEGRepresentation(image, 1.0);
Compression quality can be between 0.0 (high compression, low quality) and 1.0 (low compression, high quality)
Related
I am unable to download the image in Objective c Using SDWebImage 4.4.5 version., I tried the following , nothing worked.
Try 1:
[self.thumbnailImageView sd_setImageWithURL:[NSURL URLWithString:thumbnailURLString] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
}];
Try 2:
[self.thumbnailImageView sd_setImageWithURL:[NSURL URLWithString:thumbnailURLString] placeholderImage:nil options:SDWebImageRefreshCached completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { if(image != nil){
self.thumbnailImageView.image = image;
} else {
NSLog(#"Photo Not Available, fetch");
[self.thumbnailImageView sd_setImageWithURL:[NSURL URLWithString:thumbnailURLString] placeholderImage:nil options:SDWebImageRefreshCached completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if(image != nil) { NSLog(#"Lo Res Image Loaded by %ld from '%#'", (long)cacheType, imageURL);
self.thumbnailImageView.image = image;
} else {
self.thumbnailImageView.image = nil;
} }];
} }];
Try 3:
[[SDWebImageDownloader sharedDownloader] downloadImageWithURL:[NSURL URLWithString:thumbnailURLString] options:SDWebImageDownloaderUseNSURLCache progress:nil completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
}];
Try 4:
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager loadImageWithURL:[NSURL URLWithString:thumbnailURLString] options:SDWebImageDelayPlaceholder progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
} completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
}];
Try 5:
SDWebImageDownloader *manager = [SDWebImageManager sharedManager].imageDownloader;
[manager setValue:#"application/vnd.learning.events.v1+json" forHTTPHeaderField:#"Accept"];
[manager setValue:#"en-US" forHTTPHeaderField:#"Accept-Language"];
[manager setValue:#"application/json; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
//[manager setValue:savedEmail forHTTPHeaderField:#"Email"];
[manager setValue:savedToken forHTTPHeaderField:#"Authorization"];
[manager downloadImageWithURL:[NSURL URLWithString:thumbnailURLString] options:SDWebImageDownloaderHighPriority progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
} completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) {
self.thumbnailImageView.image = image;
}];
In all the above cases, getting the following error:
Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLStringKey=https://thisisnotcorrecturl.net/api/BAImage?ActionFlagId=97&id=615, NSErrorFailingURLKey=https://thisisnotcorrecturl.net/api/BAImage?ActionFlagId=97&id=615, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <92586538-B07D-46FB-8694-3B29AA3F0CB4>.<7>"
), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <92586538-B07D-46FB-8694-3B29AA3F0CB4>.<7>, NSLocalizedDescription=cancelled}
Earlier, we used v3.5.4 version used, able to download the image with the following code. It's working good.
[self.thumbnailImageView setImageWithURL:[NSURL URLWithString:thumbnailURLString]
placeholderImage:nil
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
if (image != nil){
self.thumbnailImageView.image = [self imageResizingToAspetRatio:image];
}
}];
Kindly let me know if did any mistake, or any suggestions.
Update 1:
Tried to download the image using post man. Kindly check the image.
The same image URL is working on SDWebImage v3.5.4 after i upgraded to SDWebImage v4.4.5, it is not lodging the image.
Is there any configurations am i missing? Installed pod 'SDWebImage/WebP' also, added SD_WEBP=1 in Build settings -> Preprocessor macros.
Error: Error Domain=SDWebImageErrorDomain Code=0 "Downloaded image has 0 pixels" UserInfo={NSLocalizedDescription=Downloaded image has 0 pixels}
http://testingurl.net/api/Image?ActionFlagId=20&id=864
Authorization:
Email: kkk1#ler.com ,
Token: A-BE3D-WER3-847F-ER6YG5678G
Basically, SDWebImage has no issue for downloading them from any URL if the URL contains an image.
But in your case, you have tried to get an image from JSON. Your server API returns a JSON object that contains the image as base64String. When you get the JSON response then you need to get the base64String from json and then create an image from the base64String.
You can use this method for decoding string to image using Objective C.
- (UIImage *)decodeBase64ToImage:(NSString *)strEncodeData {
NSData *data = [[NSData alloc]initWithBase64EncodedString:strEncodeData options:NSDataBase64DecodingIgnoreUnknownCharacters];
return [UIImage imageWithData:data];
}
First, update pod and try SDWebImage pod version 3.8.2.
And the second thing is to check your image URL. because I personally test image download with this pod version and downloading functionality is working.
I faced the same issue and I was trying webP images. I realised later that I need to add webP coder to SDImageCodersManager. Something like
SDImageCodersManager.shared.addCoder(SDImageWebPCoder.shared)
I did this in AppDelegate.
If you are suffering such type issue from SDWebImage library you can go with other one as well which are supporting base64 string object
One of best library I found is "Kingfisher"
Hope you like this and it will solve your issue.
I am getting image as url from dictionary on ViewController A and I have passed that dictionary to ViewController B.I want that if the user has updated the image then it shows the updated image else it shows the previous image and I am doing the following code for it .Kindly check and tell why is it not working as desired and showing the previous image only in every case.
-(void)showUserImage:(NSURL*)imgUrl
{
[ConnectionManager setSharedCacheForImages];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:imgUrl];
NSURLSession *session = [ConnectionManager prepareSessionForRequest];
NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
if (cachedResponse.data) {
UIImage *downloadedImage = [UIImage imageWithData:cachedResponse.data];
dispatch_async(dispatch_get_main_queue(), ^{
_profileImageView.image = downloadedImage;
});
} else {
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
if(res.statusCode == 200){
dispatch_async(dispatch_get_main_queue(), ^{
_profileImageView.image = [UIImage imageWithData:data];
});
}
}];
[task resume];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
if(_profileImageView.image == [_detailsDictionary valueForKey:#"ProfilePictureUrl"]) {
NSLog(#"Th url of image is %#",[_detailsDictionary valueForKey:#"ProfilePictureUrl"]);
}
else {
_profileImageView.image = image;
UIImage *updatedImage = _profileImageView.image;
NSData *imageData = UIImageJPEGRepresentation(updatedImage, 100);
NSString *strEncoded = [imageData base64EncodedStringWithOptions:0];
[_detailsDictionary setObject:strEncoded forKey:#"ProfilePictureUrl"];
[self dismissViewControllerAnimated:YES completion:nil];
}
}
#Dirtydanee, He is absolutely correct, you are doing incompatible comparison between Url and UIImage. So please correct this with following code.
NSData *data1 = UIImagePNGRepresentation(previousImage);
NSData *data2 = UIImagePNGRepresentation(currentImage);
if([data1 isEqualToData:data2]) {
//Do something
} else {
//Do something
}
Convert images into NSData and compare the data.
If you want bit-by-bit comparison Please look at the following link:
Generate hash from UIImage
The problem seems to be in this line:
if(_profileImageView.image == [_detailsDictionary valueForKey:#"ProfilePictureUrl"]) {
You are trying to compare the _profileImageView.image, what is UIImage, with [_detailsDictionary valueForKey:#"ProfilePictureUrl"], what is NSURL instance, coming from the dictionary.
What you could do instead, is checking if the picked image and the profileImage is the same.
if(_profileImageView.image == image) {
// etc..
To clear previously cached images, just call:
[[NSURLCache sharedURLCache] removeAllCachedResponses];
Hope this helps!
I have some code that gets an image from a web page and displays it in an ImageView. But the image loads very slowly for some reason I don't really understand! Through my logging I can see that all the data for the image (base64 string) arrives pretty instantly, yet it takes about 12 - 15 seconds for the image to appear in the ImageView.
I find this very strange because I used an NSStream to get the data for the image in a different method and the image loaded as soon as all the data arrived. But with this URLSession method its taking longer for the image to load. This doesn't really make sense! This method shouldn't affect how the ImageView loads that data.
Has anybody any ideas why this might be happening?
heres the code:
- (void)postMethod:(NSDictionary *)numDict
{
NSURL *url = [NSURL URLWithString:#"http://theWebAddress.com/aPage.php"]; // add url to page
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
request.HTTPMethod = #"POST";
NSError *error = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:numDict options:kNilOptions error:&error];
NSLog(#"%#", numDict);
if (!error)
{
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSDictionary *diction = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
for (id key in diction)
{
if ([key isEqualToString:#"text"])
{
NSLog(#"data is text");
self.messageLabel.text = diction[#"text"];
break;
}
else if ([key isEqualToString:#"image"])
{
NSLog(#"data is an image");
// gets the base64 string pretty instantly but takes 12 - 15 seconds to pop up in the imageView
NSData *ImgData = [[NSData alloc] init];
ImgData = [[NSData alloc] initWithBase64EncodedString:diction[#"image"] options:1];
self.ImageView.image = [UIImage imageWithData:ImgData];
break;
}
}
}];
[uploadTask resume];
}
}
many thanks!
Your completion handler might be operating on a background thread. UI updates should always work on the main thread. Put a break point at
self.ImageView.image = [UIImage imageWithData:ImgData];
and see if it is on the main thread. If not, dispatch it to the main thread before you set the ImageView.image:
dispatch_async(dispatch_get_main_queue(), ^{
self.ImageView.image = [UIImage imageWithData:ImgData];
});
You can try to use SDWebImage https://github.com/rs/SDWebImage and all you need is to set the image in imageView like this:
[cell.imageView setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
You are firstly downloading image and then showing image.You can download image by using lazy loading.
For this you can use EgoImageView not uiimageview.
self.ImageView.imageURL=[NSURL URLWithString:
here self.ImageView is of egoimageview type.
you can get this class from github.
https://github.com/enormego/EGOImageLoading
Like we set image in UIImageview using SDWebImage
[imageview.setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {... completion code here ...}];
Is there any way to use SDWebImage in UIWebview in <img> tag
NSString *htmlString =#"<html lang=\"en\"><img src='http://cdn.tutsplus.com/mobile/uploads/legacy/iOS-SDK_UIView-Animation/Animate-Icon.png' /> </div><div id=\"content\"><div>BlahBlahBlah LoremIpsum</div><br></body>"
[WebView loadHTMLString:descriptionHT baseURL:nil];
Thanks in advance :)
First cache your image:
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadWithURL:[NSURL URLWithString:#"http://cdn.tutsplus.com/mobile/uploads/legacy/iOS-SDK_UIView-Animation/Animate-Icon.png"]
options:
0 progress : ^(NSInteger receivedSize, NSInteger expectedSize) {
// progression tracking code
}
completed:
^(UIImage * image, NSError * error, SDImageCacheType cacheType, BOOL finished) {
if (image && finished) {
[[SDImageCache sharedImageCache] storeImage:image forKey:#"icon"];
}
}];
Then when you need the image
__block NSString *imageSource;
__block NSData *imageData = [NSData data];
SDImageCache *imageCache = [SDImageCache sharedImageCache];
[imageCache queryDiskCacheForKey:#"icon" done:^(UIImage * image, SDImageCacheType cacheType) {
imageData = UIImagePNGRepresentation(image);
if (image) {
imageSource = [NSString stringWithFormat:#"data:image/png;base64,%#", [imageData base64Encoding]];
} else {
//start download of image
}
}];
Then in your html:
NSString *htmlString = [NSString stringWithFormat:#"<html lang=\"en\"><img src=\"%#\"/> </div><div id=\"content\"><div>BlahBlahBlah LoremIpsum</div><br></body>", imageSource];
[WebView loadHTMLString:htmlString baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
You don't have to use a key when caching the image, I just thought it made things a little easier.
I have saved image data to core data, the key is binary data format. After I saved to the core data, I displaying the image in a UIImageView using valueForKey: . But After I launch the simulator again, everything is still saved, but the image data is gone, when I NSLog the key's data description, it's null.
NSDictionary *show = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:nil];
Summary *summary = [NSEntityDescription insertNewObjectForEntityForName:#"Summary" inManagedObjectContext:weakSelf.managedObjectContext];
summary.title = show[#"title"];
summary.poster = show[#"images"][#"poster"];
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadWithURL:[NSURL URLWithString:summary.poster] options:SDWebImageProgressiveDownload progress:^(NSUInteger receivedSize, long long expectedSize) {
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) {
NSData *data = UIImageJPEGRepresentation(image, 0.5);
summary.posterImageData = data;
}];
[weakSelf.managedObjectContext dct_saveWithCompletionHandler:^(BOOL success, NSError *error) {
if (success) {
} else {
NSLog(#"%#", error);
}
}];
I think your current code, the downloadWithURL's completed block is being called after dct_saveWithCompletionHandler , try:
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadWithURL:[NSURL URLWithString:summary.poster] options:SDWebImageProgressiveDownload progress:^(NSUInteger receivedSize, long long expectedSize) {
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) {
NSData *data = UIImageJPEGRepresentation(image, 0.5);
summary.posterImageData = data;
[weakSelf.managedObjectContext dct_saveWithCompletionHandler:^(BOOL success, NSError *error) {
if (success) {
} else {
NSLog(#"%#", error);
}
}];
}];
Make sure that you're actually saving the managed object context. Doublecheck that you've set the concurrency type for your MOCs correctly, too.