I have these two methods. How do I call them?
//to base 64 string
-(NSString *)getStringFromImage:(UIImage *)image{
if(image){
NSData *dataObj = UIImagePNGRepresentation(image);
return [dataObj base64Encoding];
} else {
return #"";
}
}
//Convert back
// NSData *dataObj = [NSData dataWithBase64EncodedString:beforeStringImage];
// UIImage *beforeImage = [UIImage imageWithData:dataObj];
If you want to call the method from same class, you could call like as follows:
UIImage *image = [UIImage imageNamed:#"someimg.png"];
NSString *str = [self getStringFromImage:image];
Else, if you want call the method from different class, then do as follows:
Assume clInstance be the instance of the class having that method, then
UIImage *image = [UIImage imageNamed:#"someimg.png"];
NSString *str = [clInstance getStringFromImage:image];
Related
As part of syncing phone to server, the phone takes data from API to populate tableview. Local placeholder images appear immediately and are replaced with remote images asynchronously. The problem is that the label for each row does not appear for up to twenty seconds until after the images have all downloaded even the label is a constant. How can I get labels to load more quickly?
-(void)configureCell:(IDItemCell *)cell withItem:(Items *)item {
[cell layoutIfNeeded];
//Label
cell.nameLabel.text = #"TEST LABEL";//does not load for 20 seconds
//image
NSString *picname = item.pic== nil ? #"" : item.pic;
cell.iconView.image = [UIImage imageNamed:#"placeholder.png"];//loads instantly
//remote fetch
if (item.pic !=nil) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* path = [documentsDirectory stringByAppendingPathComponent:
[NSString stringWithString: picname] ];
if ([[NSFileManager defaultManager] fileExistsAtPath:path])
{
cell.iconView.image =[self loadImageNamed:picname];
}
else {
NSString *picURL = [NSString stringWithFormat:#"https://www.~/pics/%#",picname];
dispatch_async(kBgQueue, ^{
NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:picURL]];
if (imgData) {
UIImage *imageFromWeb = [UIImage imageWithData:imgData];
if (imageFromWeb) {
[self saveImage:imageFromWeb asPicName:picname];
dispatch_async(dispatch_get_main_queue(), ^{
cell.iconView.image = imageFromWeb;
[cell setNeedsDisplay];
});
}
}
});
}
}
// Rounding the image view
cell.iconView.layer.cornerRadius = cell.iconView.frame.size.width / 2;
cell.iconView.clipsToBounds = YES;
cell.iconView.contentMode = UIViewContentModeScaleAspectFill;
}
I want to add dynamic values of UIImage in array which initialised in the for loop, So I created a NSMutableArray to set object first in for loop and later tried to retrieve values from that.
Please can you look where I am going wrong and what should be best approch while adding the dynamic values.
NSMutableDictionary * dic= [[NSMutableDictionary alloc]init];
NSMutableArray *cImages = [[NSMutableArray alloc]init];
for(int i=0; i<5; i++) {
NSString * imageKey= [NSString stringWithFormat:#"image%i",i+1];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString: [[results objectAtIndex:i]valueForKey:imageKey]]];
UIImage *imageOne = [UIImage imageWithData:imageData];
[dic setObject:imageOne forKey:imageKey];
}
for (NSString *key in dic) {
NSString *sprite = [dic objectForKey:key];
//adding below to the array
[cImages addObject:sprite];
}
What's wrong with just adding UIImage's to the mutable array?
NSMutableArray *cImages = [[NSMutableArray alloc]init];
for(int i = 0; i < 5; i++)
{
NSString *imageKey= [NSString stringWithFormat:#"image%i", i+1];
UIImage *imageToAdd = [UIImage imageNamed:imageKey];
[cImages addObject:imageToAdd];
}
// Using the images
for (UIImage *image in cImages)
{
// Do whatever u want with each image.
}
If you really need to use a dictionary to access the UIImage's by the names "image1, image2" etc you can do this:
NSDictionary *dict = [[NSDictionary alloc] init];
for (int i = 0; i < 5; i++)
{
NSString *imageKey = [NSString stringWithFormat:#"image%i", i+1];
UIImage *image = [UIImage imageNamed:#"nameOfImageFile.png"];
[dict setObject:image forKey:imageKey];
}
// Now you can access the UIImage values by their names (image1,image2,image3,image4,image5)
UIImage *imageToUse = [dict valueForKey:#"image1"];
(haven't test these, but it's fairly standard).
I want to put defaults images if i don't have images from url feed.
if(![[stories objectAtIndex:storyIndex] valueForKey:#"url"]==nil)
{ NSNumber *numberOfKeyInstances = [stories valueForKey:#"key"];
imageArray=[NSArray arrayWithObjects:[UIImage imageNamed:#"1.png"],nil];
int randomNumber_ = rand ()%19;
UIImage *image = [imageArray objectAtIndex:indexPath.row];
cell.imag=image;
}
else{
if (![[[stories objectAtIndex:storyIndex] valueForKey:#"url"] isEqualToString:#""]) {
[cell.imag setImageWithURL:[NSURL URLWithString:[[stories objectAtIndex:storyIndex] objectForKey:#"url"]] placeholderImage:[UIImage imageNamed:#"Alb.png"]];
}
}
This is my code, but i get [UIImage setContentMode:]: unrecognized selector sent to instance 0x7f908c1dcce0'
How can i solved?
Firstly, imageArray is initialised with only one image. So calling [imageArray objectAtIndex:indexPath.row] is a problem. You dont need an image array for that. Secondly, the argument inside the first if statement doesn't look right.
Also, as #midhun-mp Pointed out, u should be probably using cell.imag.image.
Try this :
if([[stories objectAtIndex:storyIndex] valueForKey:#"url"] == nil)
{
cell.imag.image = [UIImage imageNamed:#"1.png"];
}
else if ([[[stories objectAtIndex:storyIndex] valueForKey:#"url"] isEqualToString:#""])
{
cell.imag.image = [UIImage imageNamed:#"1.png"];
}
else
{
//SET YOUR IMAGE HERE
}
Try to change
UIImage *image = [imageArray objectAtIndex:indexPath.row];
to
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:[imageArray objectAtIndex:indexPath.row]]];
I suspect that cell.imag is a UIImageView not UIImage property.
So you need to change:
cell.imag=image;
to
cell.imag.image = image;
I have a UItableView that is listing number of outlets respectively, each outlet has a logo image. I save those images locally on iPhone, so if any image is found on iPhone it will fetch from there if not then it will send a service call and fetch data. It is working accordingly but when I scroll down on tableview it gets hanged at certain point when the image is being downloaded, as it is downloaded it works fine again. Is there any solution where I can perform this multitasking of downloading images along with representing them either from service call or fetching it locally.
Here is my code..
// downloading images of outlets locally
NSLog(#"Downloading...");
NSString *imageLink = [NSString stringWithFormat:#"http://cf.abc.pk/outlets/l/%#",outs.logo];
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageLink]]];
NSLog(#"%f,%f",image.size.width,image.size.height);
NSString *docDir =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSLog(#"%#",docDir);
NSLog(#"saving png");
NSString *pngFilePath = [NSString stringWithFormat:#"%#/%d.png",docDir,[[arrOutletIds objectAtIndex:webserviceCall] intValue]];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:pngFilePath];
if(!fileExists)
{
NSData *data1 = [NSData dataWithData:UIImagePNGRepresentation(image)];
[data1 writeToFile:pngFilePath atomically:YES];
}
Let's try:
//When you download something, execute in background thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0),
^{
//download some thing
dispatch_async( dispatch_get_main_queue(), ^{
// when download finish execute in main thread to update data
// this function should be called in response of downloading
});
});
Hope this helps you.
Download image in background will solve your problem here
Try this.
if(!fileExists)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *data1 = [NSData dataWithData:UIImagePNGRepresentation(image)];
[data1 writeToFile:pngFilePath atomically:YES];
});
}
You can use this code which integrates ImageCache to download async and cache images. This part of code shows downloading images in UITableView. Or you can check out this project on GitHub SDImageCache
if ([[ImageCache sharedImageCache] DoesExist:photoURL] == true)
{
image = [[ImageCache sharedImageCache] GetImage:photoURL];
cell.imageView.image = image;
}
else
{
cell.imageView.image = [UIImage imageNamed:#"PlaceHolder"];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^(void) {
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:photoURL]];
UIImage* image = [[UIImage alloc] initWithData:imageData];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
if (cell.tag == indexPath.section) {
cell.imageView.image = image;
[cell setNeedsLayout];
[[ImageCache sharedImageCache] AddImage:image imageURL:photoURL];
}
});
}
});
}
Import these files to your project
ImageCache.h
#import <Foundation/Foundation.h>
#interface ImageCache : NSObject
#property (nonatomic, retain) NSCache *imgCache;
#pragma mark - Methods
+ (ImageCache*)sharedImageCache;
- (void) AddImage:(UIImage *)image imageURL:(NSString *)imageURL;
- (UIImage*) GetImage:(NSString *)imageURL;
- (BOOL) DoesExist:(NSString *)imageURL;
#end
ImageCache.m
#import "ImageCache.h"
#implementation ImageCache
#synthesize imgCache;
#pragma mark - Methods
static ImageCache* sharedImageCache = nil;
+(ImageCache*)sharedImageCache
{
#synchronized([ImageCache class])
{
if (!sharedImageCache)
sharedImageCache= [[self alloc] init];
return sharedImageCache;
}
return nil;
}
+(id)alloc
{
#synchronized([ImageCache class])
{
NSAssert(sharedImageCache == nil, #"Attempted to allocate a second instance of a singleton.");
sharedImageCache = [super alloc];
return sharedImageCache;
}
return nil;
}
-(id)init
{
self = [super init];
if (self != nil)
{
imgCache = [[NSCache alloc] init];
}
return self;
}
- (void) AddImage:(UIImage *)image imageURL:(NSString *)imageURL
{
if (image==nil) {
}
else
{
[imgCache setObject:image forKey:imageURL];
}
}
- (NSString*) GetImage:(NSString *)imageURL
{
return [imgCache objectForKey:imageURL];
}
- (BOOL) DoesExist:(NSString *)imageURL
{
if ([imgCache objectForKey:imageURL] == nil)
{
return false;
}
return true;
}
#end
What syntax would make this work?
NSString *curstring = [cur description];
UIImage *weatherimage = [UIImage imageNamed: #"#%.png", curstring];
[weather setImage:weatherimage];
Thanks
You're looking for NSString's stringWithFormat:
UIImage *weatherimage = [UIImage imageNamed:[NSString stringWithFormat:#"#%.png", curstring]];