Convert array of image path into base64 encoded string.? - ios

I want to convert array of Image Paths which are in document directory into Encoded baSE 64 string.
Here is my code
NSArray *recipeImages = [savedImagePath valueForKey:#"Image"];
this array contains path of the images (MULTIPLE IMAGES).
This is how array looks in Logs.
Saved Images == (
"/Users/ZAL02M/Library/Developer/CoreSimulator/Devices/F1F3C01E-8686-4367-82FB-80B003E2F416/data/Containers/Data/Application/694494B1-0DCA-497A-B8B0-586276EEF240/Documents/cached0.png",
"/Users/ZAL02M/Library/Developer/CoreSimulator/Devices/F1F3C01E-8686-4367-82FB-80B003E2F416/data/Containers/Data/Application/694494B1-0DCA-497A-B8B0-586276EEF240/Documents/cached1.png"
)
How to make base64 string ???

Try this to cycle all your images and save each encoded string into a new array:
NSMutableArray *encodedImages = [NSMutableArray new];
for (NSString *path in recipeImages)
{
UIImage *image = [UIImage imageWithContentsOfFile:path];
NSData *imageData = UIImagePNGRepresentation(image);
NSString *dataString = [imageData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
[encodedImages addObject:dataString];
}

Convert your ImagePaths (Strings) to NSData and from NSData back to string via base64EncodedStringWithOptions:
Here the code:
NSArray *recipeImages = [savedImagePath valueForKey:#"Image"];
NSMutableArray *mutableBase64StringsArray = #[].mutableCopy;
for (NSString *imagePath in recipeImages)
{
NSData *imagePathData = [imagePath dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64ImagePath = [imagePathData base64EncodedStringWithOptions:0];
[mutableBase64StringsArray addObject:base64ImagePath];
}
In the mutableBase64StringsArray you have all imagePaths as base64 encoded strings.
Look at this post from SO for more explanations: Base64 Decoding in iOS 7+

you can try this
Encoding :
- (NSString *)encodeToBase64String:(UIImage *)image {
return [UIImagePNGRepresentation(image) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
}
Decoding :
- (UIImage *)decodeBase64ToImage:(NSString *)strEncodeData {
NSData *data = [[NSData alloc]initWithBase64EncodedString:strEncodeData options:NSDataBase64DecodingIgnoreUnknownCharacters];
return [UIImage imageWithData:data];
}
To get image from your path you can use this code
NSString* imagePath = [recipeImages objectAtIndex:i];
UIImage *image = [[UIImage alloc] initWithContentsOfFile:imagePath];
Then add encoded content to your array.
Hope it helps.

Related

I am trying to save to and retrieve from NSMutableDictionary

Hello everyone !, I have an app that requires saving multiple Images. I want to save these images in a NSMutableDictionary as they may be accessed at another time..
I have a NSDictionaryFile class that looks like this set up as
#interface NSDictionaryFile : NSMutableDictionary
-(NSMutableDictionary *) mutDict {
mutDict = [[NSMutableDictionary alloc]initWithCapacity:24];
return mutDict;
}
-(void) addToDictionary : (NSData *) nsData : (NSString *) key {
NSString *tempStringKey = [NSString stringWithFormat:#"%#",key];
[mutDict setObject:[NSData dataWithData:nsData] forKey:tempStringKey];
NSLog(#"The Key is %# And The nsData has this %#",key,nsData);
}
-(NSData *) getFromDict : (NSData *) getNSData : (NSString *) getKey {
NSString *tempStringKey = [NSString stringWithFormat:#"%#",getKey];
NSData *tempData = [mutDict objectForKey:tempStringKey];
getNSData = [NSData dataWithData:tempData];
return getNSData;
}
I am saving to the above class from
#interface PhotoViewController : UIViewController<UIImagePickerControllerDelegate,UINavigationControllerDelegate>
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
image = [info valueForKey:UIImagePickerControllerOriginalImage];
NSData *imgData = UIImagePNGRepresentation(image);
NSString *imageString;
num = 1;
imageString = [NSString stringWithFormat:#"imageKey%i",num];
[[NSDictionaryFile sharedDictionary] addToDictionary:imgData :imageString];
And I am retrieving it like this in the View Did Load like so,
-(void)viewDidLoad {
NSData *tempData;
NSData *imageData;
_num = 1;
imageString = [NSString stringWithFormat:#"imageKey%i",_num];
[[NSDictionaryFile sharedDictionary]getFromDict:tempData :imageString];
self.imageView.image = [UIImage imageWithData:imageData];
}
When the data is being saved to the NSDictionaryFie.m I know it is going because I am NSLog(#"The Image Data is %#",nsData); and my print out is , as would be expected.
89504e47 0d0a1a0a 0000000d 49484452 00000215 00000155 08020000 00d7368a d8000000 01735247 4200aece 1ce90000 001c6944 4f540000 00020000 00000000 00ab0000 00280000 00ab0000 00aa0003 41798433 c89e0000 40004944 41547801 a4bd079c 2547752f 7c677636 2a2192f1 b3fd6c63 3f6cb009 42486857 4802990c 1212b2c0 809f6d6c 30185bc0 27139456 bbda202d ca5aadb4 2badc2ae 36e79d0d b3333b39 e77c676e cef9debe b7730ef5 fed53d33 5a09f8de 07dffdd5 afe77475 d5a953a7
So , when the PickerdidFinisPicking , the image shows in my imageView, but when I try to retrieve it i get null.
If someone can tell me where I am going wrong it is much appreciated.
Regards
JZ
I think the error is pretty simple:
you are not using the return value from getFromDict, but an uninitialized variable imageData.
I think you should call your method and use the return value, like this
-(void)viewDidLoad {
NSData *tempData;
NSData *imageData;
_num = 1;
imageString = [NSString stringWithFormat:#"imageKey%i",_num];
imageData=[[NSDictionaryFile sharedDictionary]getFromDict:tempData :imageString];
self.imageView.image = [UIImage imageWithData:imageData];
}
Besides the getter methods seems overly complicated to me:
-(NSData *) getFromDict : (NSData *) getNSData : (NSString *) getKey {
NSString *tempStringKey = [NSString stringWithFormat:#"%#",getKey];
NSData *tempData = [mutDict objectForKey:tempStringKey];
getNSData = [NSData dataWithData:tempData];
return getNSData;
}
You pass the method an NSData which you just use to store a value and pass it back to the caller. It' useless to pass such a parameter.
Have you tried a slimmer method?
-(NSData *) getFromDict : (NSString *) getKey {
return[mutDict objectForKey:getKey];
}

Converting from JSON string to UIImage always gives null?

I Get this kind of JSON:
NOTE: I put dots in "content" because it is too long byte array abd just to explain the situation.
{
"id":"53abc6a7975a9c10c292f670",
"nfcId":"testse",
"company":"TESt",
"qrId":"testvalue",
"address":"ajs;ldfh",
"mimeType":"IMAGE",
"url":"",
"content":"iVBORw0KGgoAAAANSUhEUgAA....."
}
And im trying to get this Json and diplay this information
the "content" field has a Byte array converted on the server from Image to byte array.
I use this code in xCode to convert those bytes to NSData, then to UIImage to be able to display it in UIImageView:
NSData *dataImage = [jsonArray[key] dataUsingEncoding:NSUTF8StringEncoding];
NSLog(#"data = %#", dataImage);
UIImage *img = [UIImage imageWithData:dataImage];
NSLog(#"img = %#", img);
The image is always gives me null.Although, data give me array of data.
I tried all kinds of encodings as a NSData parameters also:
dataUsingEncoding:NSASCIIStringEncoding
dataUsingEncoding:NSUTF8StringEncoding
dataUsingEncoding:NSUTF16StringEncoding
dataUsingEncoding:NSUTF32StringEncoding
I've used code like this before
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"data:image/png;base64,%#",jsonArray[key]]];
NSData *imageData = [NSData dataWithContentsOfURL:url];
UIImage *img = [UIImage imageWithData:imageData];
Note that initWithBase64EncodedString is only available from iOS7 onwards
I tried this code just right now and it works:
NSData* dataImage = [[NSData alloc] initWithBase64EncodedString:jsonArray[key] options:0];
UIImage *img = [UIImage imageWithData:dataImage];
The "content" encoded by Base64 String type.

UIImage Object Not Formed Using NSData

I am getting the following response from a server:
{
"userId": "72e823ebc0c07fa99f279d6435e2c6ce",
"userHash": null,
"md5": "e993b7e9ec74bcdc1b1b7baec7d1cdd2",
"highres": null,
"thumbnail": "/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0
Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAyADIDASIAAhEBAxEB/
8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2Jygg
kKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytL
T1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJ
BUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZa
XmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD0CfRbZY3IzuAyOak0nTLOW0UzBt+e
cGpppcxvg87ajt76Cw0R7uVC3lgtj1rREMvtpVijo6q+5fu81Wu/EGmeFFMlwTiTkgHmnadqqanYwXqL5ayDIU9q8C8ceILq+8QXUU0haOFyqgelVo9xHu1v8U9BuLhIlM
g3fxHGBXWf2pYmAzLdRMgXdw4NfImmQXN1bNIHKQbsbj616DpdvcQ6RHsnLfNyc1jNpbGqi+p6+fHOmgkbJePaivMvN9jRWPOyuU6Rb9ZbaTyn3Ng4Feaaj48utIuNQ0
+6gaaOZNiKT/q/etvSPEEN1qr2dsoMAXcJMdTXJ61aaLe+K7v+2b1rSIAbSozmutbmD2Lnhzxvq2h26me1e6tZB+7JPCCuauBHqGvTXV04hjuHL4Pato+CdcvlWTSZGn0w/
wCpdmxkV01v8IIZbWOa51NhPtyybhhT6U7Kw07M56xvbGK3NpFGrpuyYx39627PXoJrmSwtYgFij35Hc+ldX4L8IDStMvoryxtpk2vtuHYbhxxXiVrcTaZ4gujAxk3uynJ6DN
YOkbqonY7I+KLgEj+zz+dFZWQeTIaKz9ia3j3I9F1+8e2ElrDArg5cnj5awdfli1PUJbqR/vDtWTBev9i+zKSOc5FUHDocFifxrpujiOoj8b6vDpkelQymOCIbUKNg4qEajrcoBW/
uMe8hrnIpPLmRm6A1urq8JRRtORTTBov2q+JtRlFtb6jcDdxgykA1txfC3xRBKks3kruIO5nxmsrRdVd7sKgwi/MD7ivZ/C+taV490waVq8rRX0XKurbQQOlS2UkcaPh5reB+
9tf+/gor0j/hVqZ4upsf9dDRSuOx8q2v3z9KJetFFBmyCTotSRfdNFFNF9Do/DvR/oa2vCrMPEdphiP346H3oopD6H1un+rX6CiiipGf/9k="
}
Thumbnail is a byte array and I want to convert that into NSData, then into an UIImage.
When I do the following, I end up with nil:
NSData *pictureData = [NSData dataWithBytes:[updatedData objectForKey:#"thumbnail"]];
UIImage *img = [[UIImage alloc] initWithData:pictureData];
How can I fix this?
This is not a "byte array". This is a NSString which contains a Base64 encoded image.
iOS7 has built in support for Base64 encoded data, for older versions you have to roll your own code. There are plenty of implementations available
This works on iOS7:
// NSString *base64String = [updatedData objectForKey:#"thumbnail"];
NSString *base64String = #"/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAyADIDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD0CfRbZY3IzuAyOak0nTLOW0UzBt+ecGpppcxvg87ajt76Cw0R7uVC3lgtj1rREMvtpVijo6q+5fu81Wu/EGmeFFMlwTiTkgHmnadqqanYwXqL5ayDIU9q8C8ceILq+8QXUU0haOFyqgelVo9xHu1v8U9BuLhIlMg3fxHGBXWf2pYmAzLdRMgXdw4NfImmQXN1bNIHKQbsbj616DpdvcQ6RHsnLfNyc1jNpbGqi+p6+fHOmgkbJePaivMvN9jRWPOyuU6Rb9ZbaTyn3Ng4Feaaj48utIuNQ0+6gaaOZNiKT/q/etvSPEEN1qr2dsoMAXcJMdTXJ61aaLe+K7v+2b1rSIAbSozmutbmD2Lnhzxvq2h26me1e6tZB+7JPCCuauBHqGvTXV04hjuHL4Pato+CdcvlWTSZGn0w/wCpdmxkV01v8IIZbWOa51NhPtyybhhT6U7Kw07M56xvbGK3NpFGrpuyYx39627PXoJrmSwtYgFij35Hc+ldX4L8IDStMvoryxtpk2vtuHYbhxxXiVrcTaZ4gujAxk3uynJ6DNYOkbqonY7I+KLgEj+zz+dFZWQeTIaKz9ia3j3I9F1+8e2ElrDArg5cnj5awdfli1PUJbqR/vDtWTBev9i+zKSOc5FUHDocFifxrpujiOoj8b6vDpkelQymOCIbUKNg4qEajrcoBW/uMe8hrnIpPLmRm6A1urq8JRRtORTTBov2q+JtRlFtb6jcDdxgykA1txfC3xRBKks3kruIO5nxmsrRdVd7sKgwi/MD7ivZ/C+taV490waVq8rRX0XKurbQQOlS2UkcaPh5reB+9tf+/gor0j/hVqZ4upsf9dDRSuOx8q2v3z9KJetFFBmyCTotSRfdNFFNF9Do/DvR/oa2vCrMPEdphiP346H3oopD6H1un+rX6CiiipGf/9k=";
NSData *data = [[NSData alloc] initWithBase64EncodedString:base64String options:NSDataBase64DecodingIgnoreUnknownCharacters];
UIImage *image = [UIImage imageWithData:data];
And that's your image:

object inside NSMutableArray

I've a tableview which has list of images and image thumbnail (image list and thumbnails are parsed from JSON object), I'm adding image data objects to imagesArray like this -
ImageData *imageDataObject = [[ImageData alloc]initWithImageId:[[imageListArray
objectAtIndex:indexPath.row] imageId] imageData:imageData];
[imagesArray addObject:imageDataObject];
ImageData object
#property (nonatomic, strong) NSString* imageId;
#property (nonatomic, strong) NSData* imageData;
allImagesArray like this
[ImageData object1,ImageData object2,....]
I want to assign imageData of the object from this array based on selectedImageId to
UIImage* image =[[UIImage alloc] initWithData:........];
I'm not able to think of a way to get to that imageData based on selectedImageId
Please help.
Update -
Thank you all for the help, I could do it.
One of the possible way will be, iterate through the array, find your selectedImageId from the dictionary and use it.
Example:
ImageData *imageDataObject = nil;
for(int i=0; i<allImagesArray.count;i++){
NSDictionary *dict= allImagesArray[i];
imageDataObject = [dict objectForKey:selectedImageId];
if(imageDataObject != nil){
UIImage* image =[[UIImage alloc] initWithData:........];
//do whatever
break;
}
}
As per your EDIT:
What you have is an array of ImageData objects [ImageData1,ImageData2,...]. For each ImageData object, you have imageId and imageData property and what you want is simply compare the selectedImageId with this imageId and get the imageData from that.
So for that, in your PPImageViewController, you can iterate the allImagesArray like this and get the imageData.
for(ImageData* imgDataObj in self.allImagesArray){
if([imgDataObj.imageId isEqualToString:self.selectedImageId]){
UIImage* image =[[UIImage alloc] initWithData:imgDataObj.imageData];
}
}
So you have:
NSArray* allImagesArray = #[#{#"some_image_id_in_NSString_1":#"the data in NSData 1"}, #{#"some_image_id_in_NSString_2":#"the data in NSData 2"}];
As a property of PPImageViewController.
Assuming the imageid is an NSString and imagedata is NSData, you can create a method something like this on PPImageViewController:
- (UIImage*) findSelectedImage
{
UIImage* selectedImage;
for(NSDictionary* d in allImagesArray)
{
NSString* currentKey = [[d allKeys] objectAtIndex:0];
if([currentKey isEqualToString:[self selectedImageId]])
{
NSData* imageData = [d objectForKey:currentKey];
selectedImage = [UIImage imageWithData:imageData];
break;
}
}
return selectedImage;
}
Then call it like this, maybe on your viewDidLoad method:
UIImage* selectedImage = [self findSelectedImage];
Hope it help.
I see you are adding ImageData objects directly into the Array. You could have just used a NSDictionary instead. The key can be imageID (assuming it to be unique) and value will be the imageData object. Then pass the dictionary instead of array to PPImageViewController.
NSMutableDictionary *imageData = [NSMutableDictionary dictionary];
ImageData *imageDataObject = [[ImageData alloc]initWithImageId:[[imageListArray
objectAtIndex:indexPath.row] imageId] imageData:imageData];
[imageData setObject:imageDataObject forKey:imageId];
And then within PPImageViewController, you can easily get the imageDataObject based on selected imageID like this:
ImageData *imageDataObject = allImagesDictionary[selectedImageID];
EDIT:
NSArray *imageIndexes = [allImagesDictionary allKeys];
// Now use imageIndexes to populate your table. This will guarantee the order
// Fetch the imageId
selectedImageID = imageIndexes[indexPath.row];
// Fetch the imageData
ImageData *imageDataObject = allImagesDictionary[selectedImageID];

Save and load image from SQL database

I'm trying to display an image from my Database.
This part works nicely.
I save the image in the DB like this :
UIImage *resizedImg = [Generics scaleImage:self.photo.image toResolution:self.photo.frame.size.width and:self.photo.frame.size.height];
NSData *imgData = UIImageJPEGRepresentation(resizedImg, 0.9);
NSString *stringDataImage = [NSString stringWithFormat:#"%#",imgData];
[dict setObject:stringDataImage for key#"image"];
// POST Request to save the image in DB ...
Now when I try to load the image and set it into my UIImageView I do this way :
NSData *data = [[[MyUser sharedUser] picture] dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO];
self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageWithData:data]];
Or
NSData *data = [[[MyUser sharedUser] picture] dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO];
self.imageView.image = [UIImage withData:data];
But this doesn't work.
data is not equal to imgData, I think it's the encoding but I can find the good one.
And [UIImage withData:data] return nil;
Can you help me?
EDIT :
Convert and save
UIImage *resizedImg = [Generics scaleImage:self.photo.image toResolution:self.photo.frame.size.width and:self.photo.frame.size.height];
NSData *imgData = UIImageJPEGRepresentation(resizedImg, 0.9);
[dict setObject:[imgData base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength] forKey:#"image"];
Load the image
NSData *data = [[NSData alloc] initWithBase64EncodedData:[[MyUser sharedUser] picture] options:kNilOptions];
NSLog(#"%#", data);
self.image.image = [UIImage imageWithData:data];
You are converting the NSData to a string and saving that to your database. Two issues:
Your choice of using the stringWithFormat construct is an inefficient string representation of your data (resulting in string representation that is roughly twice the size). You probably want to use base64 (for which the string representation is only 33% larger).
You are saving your string representation, but never converting it back to binary format after retrieving it. You could write a routine to do this, but it's better to just use established base64 formats.
If you want to save the image as a string in your database, you should use base64. Historically we would have directed you to one of the many third party libraries (see How do I do base64 encoding on iphone-sdk?) for converting from binary data to base64 string (and back), or, iOS 7 now has native base 64 encoding (and exposes the private iOS 4 method, in case you need to support earlier versions of iOS).
Thus to convert NSData to NSString base64 representation:
NSString *string;
if ([data respondsToSelector:#selector(base64EncodedStringWithOptions:)]) {
string = [data base64EncodedStringWithOptions:kNilOptions]; // iOS 7+
} else {
string = [data base64Encoding]; // pre iOS7
}
And to convert base64 string back to NSData:
NSData *data;
if ([NSData instancesRespondToSelector:#selector(initWithBase64EncodedString:options:)]) {
data = [[NSData alloc] initWithBase64EncodedString:string options:kNilOptions]; // iOS 7+
} else {
data = [[NSData alloc] initWithBase64Encoding:string]; // pre iOS7
}
If you really want to turn binary data into a string you should be using base64 encoding. Luckily for you, NSData now supports Base64 natively
So you could get your string from data with:
NSString *stringDataImage = [imgData base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];
And you could turn this back into NSData with:
NSData *imgData = [[NSData alloc] initWithBase64EncodedString:stringDataImage options:kNilOptions];

Resources