Make UIImage from ByteArray getting from .Net WebService - iphone

My problem is same as Converting byte array coming from Web service to UIImage iPhone
.Now I am storing these bytes in NSMutableArray.But the method:
NSData *data = [NSData dataWithBytes:YOUR_BYTE_ARRAY length:ARRAY_LENGTH];
takes arrayOfBytes as parameter.So can anyone tell me that how to convert this array in byte array. I searched a lot but unable to find relevant contents.

Not sure how you're getting the mutable array to begin with. If you're using NSURLConnection, the delegate will get NSData, so you needn't use a mutable array. Consider getting the data using the connection asynch block method like this ...
NSURLRequest *myRequest = // the request you've already got working to get image data
[NSURLConnection sendAsynchronousRequest:myRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (!error) {
// image from data with no intermediate mutable array or byte array
UIImage *image = [UIImage imageWithData:data];
}
}];

Thanks for your co-operation. But it does not help me. After a long research i found my solution. I am sharing my information so that others can get right answer.
NSArray *byteArray = [[NSArray alloc]init]; //strore all data here coming from server in byte formate
unsigned c = [byteArray count];
uint8_t *bytes = malloc(sizeof(*bytes) * c);
unsigned i;
for (i = 0; i < c; i++)
{
NSString *str = [byteArray objectAtIndex:i];
int byte = [str intValue];
bytes[i] = (uint8_t)byte;
}
NSData *data = [[NSData alloc]initWithBytes:bytes length:c];
UIImage *image = [UIImage imageWithData:data];
NSLog(#"image %#",image);

Related

How to concatenate 3 NSData variables

How to concatenate 3 NSData variables ?
NSData *iv;
NSData *salt;
NSData *encryptedData;
I need to join these to a single variable. Can any one show me a way.
use an NSMutableData object and the method -(void)appendData:(NSData *)otherData
Edited to add example :
NSMutableData *concatenatedData = [NSMutableData data];
[concatenatedData appendData:iv];
[concatenatedData appendData:salt];
[concatenatedData appendData:encryptedData];
// and now you have all of the data in the single variable "concatenatedData"
For those who coding for iOS5 and later.
I'd like to show some real good concatenation. Why are those answers aren't good enough? Because they are involves extra memory usage for copied data. Let's see the answer:
NSMutableData *concatenatedData = [NSMutableData data];
[concatenatedData appendData:iv];
[concatenatedData appendData:salt];
[concatenatedData appendData:encryptedData];
here we have memory allocated for iv, salt and encryptedData
also each time we append one of them to our mutable concatenation we are obviously copy it to mutable data again. Do we want this extra expenses while dealing with large data? Me not.
There is a way to avoid this unnecessary expense of memory - dispatch_data
I'm not going to explain how it works, you can google it if you want.
I just give you a code that works:
NSData *iv = [#"some data" dataUsingEncoding:NSUTF8StringEncoding];
NSData *salt = [#"even more data" dataUsingEncoding:NSUTF8StringEncoding];
NSData *encryptedData = [#"and one more" dataUsingEncoding:NSUTF8StringEncoding];
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_data_t dispatch_data_iv = dispatch_data_create([iv bytes], [iv length], queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
dispatch_data_t dispatch_data_salt = dispatch_data_create([salt bytes], [salt length], queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
dispatch_data_t dispatch_data_encrypted = dispatch_data_create([encryptedData bytes], [encryptedData length], queue, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
iv = nil; salt = nil; encryptedData = nil; // free all parts, we dont need it anymore
dispatch_data_t dispatch_data_concat = dispatch_data_create_concat( dispatch_data_create_concat(dispatch_data_iv, dispatch_data_salt), dispatch_data_encrypted);
NSData *concatenatedNSData = DataFromDispatchData(dispatch_data_concat);
// lets check now if the concatenation works properly
NSString *stringFromConcatenatedNSData = [[NSString alloc]initWithData:concatenatedNSData encoding:NSUTF8StringEncoding];
NSLog(#"%#",stringFromConcatenatedNSData);
don't forget about the helper-converter
NSData *DataFromDispatchData(dispatch_data_t data)
{
NSMutableData *result = [NSMutableData dataWithCapacity: dispatch_data_get_size(data)];
dispatch_data_apply(data, ^(dispatch_data_t region, size_t offset, const void *buffer, size_t size) {
[result appendBytes:buffer length:size];
return (_Bool)true;
});
return result;
}
You could use NSMutableData's -appendData method:
NSMutableData *result = [NSMutableData data];
[result appendData:iv];
[result appendData:salt];
[result appendData:encryptedData];
// result now has what you need.
This comes at the overhead of using mutable data, which can be slower & use more memory, so use with care. Generally speaking you don't want large NSData's floating around.
First create two NSObjects and use this method
-(void)appendData:(NSData *)otherData
and put in one NSData later with 3rd NSData also concatenate with the same method.

Converting byte array coming from Web service to UIImage iPhone

I am new to this technology.
I searched a lot but cant find any relevant.
In my application,I am receiving byte array from web service, my byte array which I receive from web service is
[137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,1,195,0,0,1,195,8,2,0,0,0,215,2... ]
and I want to convert this byte array into UIImage for showing it in UIImageView.
Use below constructor for UIImage.
+ (UIImage *)imageWithData:(NSData *)data;
NSData *data = [NSData dataWithBytes:YOUR_BYTE_ARRAY length:ARRAY_LENGTH];
UIImage *img = [UIImage imageWithData:data];
UIImageView *imgView = [[UIImageView alloc]initWithImage:img];
The first 8 bytes in the byte array above, \211 P N G \r \n \032 \n (or 137,80,78,71,13,10,26,10 in decimal), reveal this to be a PNG file.
At the very least, you should be able to just save your entire byte sequence to a file, and load it using + (UIImage *)imageNamed:(NSString *)name or + (UIImage *)imageWithContentsOfFile:(NSString *)path. For example:
UIImage *myImage = [UIImage imageNamed:#"myfile.png"]
// myfile.png should be in the main bundle
(Apurv's method is more direct, and better for this reason. But since you are having such difficulty with it, I thought I'd suggest a slightly different approach.)
You need to Base64 decode the data first. Data that is returned from many SOAP web services is base 64 encoded as well as sometimes raw data embedded in websites. It is pretty simple to do but just easiest to use a library to someone else has created.
Start by including this in your project and including the .h in this file: https://github.com/nicklockwood/Base64
NSString *base64String = #"**YOUR BYE ARRAY HERE**";
UIImage *imageOrig = [UIImage imageWithData:[NSData dataFromBase64String:base64String]];
UIImageView *imageView = [[UIImageView alloc]initWithImage:imageOrig];
That should do it. In my previous experiences I just put what ever data blob I get over the webservice into a string then create the image using this method and it works great there is a great discussion on the details of Base64 encoding and decoding here : http://cocoadev.com/wiki/BaseSixtyFour which is what I used to create my class but Nick's code on gitHub is much better as its ARC compliant.
From Webservice we get array of NSNumber. We will have to convert it to NSData like this:
NSMutableData *data = [[NSMutableData alloc] initWithCapacity: [strings count]];
for( NSNumber *number in strings) {
char byte = [number charValue];
[data appendBytes: &byte length: 1];
}
Covert NSData to UIImage:
UIImage *imageOrig = [UIImage imageWithData:data];
We get JSON also out of NSData.
NSError *error1 = nil;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error1];
if (error1 != nil) {
NSLog(#"Error parsing JSON.");
} else {
NSLog(#"Array: %#", jsonArray);
}
//Use this
CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB();
CGContextRef bitmapContext=CGBitmapContextCreate(YOUR_BYTE_ARRAY, w, h, 8, 4*w, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault);
CFRelease(colorSpace);
free(YOUR_BYTE_ARRAY);
CGImageRef cgImage=CGBitmapContextCreateImage(bitmapContext);
CGContextRelease(bitmapContext);
UIImage *newimage = [UIImage imageWithCGImage:cgImage];
[yourImageView setImage:newimage];
CGImageRelease(cgImage);
May be it will help you...
#import "NSDataAdditions.h"
NSData *dataObj = [NSData dataWithBase64EncodedString:StringImage];
UIImage *Image = [UIImage imageWithData:dataObj];

problem with converting NSData to NSArray

Hi
I have a problem with converting NSData to NSArray
my code is:
NSData *data = [[NSData alloc] initWithBytes:(const void *)buf length:len];
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:data];
can any one help me to do it.
I have no idea what is inside your byte buffer. This code works for a simple buffer of character bytes.
Try:
char buf[]="123456";
NSData *bufObj=[NSData dataWithBytes:(const void *)buf length:sizeof buf];
if(bufObj==nil)
NSLog(#"failed to create obj");
else {
NSMutableArray *marr=[NSMutableArray array];
[marr addObject:bufObj];
NSArray *arr=[NSArray arrayWithObject:bufObj];
NSLog(#"test:\n\tbufObj: %#\n\tmarr: %#\n\tarr: %#",bufObj,marr,arr);
}
Use +[NSPropertyListSerialization dataWithPropertyList:format:options:error:] to convert the data, then check if the result -isKindOfClass:[NSArray class].
It will work :)

Downloading and writing images from an array of urls crashing iPad

I am writing images to the directory of my app using the following code in a separate thread
for (int j =0; j<[sorted count]; j++) {
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[sorted objectAtIndex:j]]];
UIImage *image = [UIImage imageWithData:data];
if (image!=nil) {
NSLog(#"%#",[sorted objectAtIndex:j]);
[images addObject:image];
}
}
and
for (int k=0;k<[images count];k++)
{
NSString *temp = [[sorted objectAtIndex:k]lastPathComponent];
NSString *imagePath = [dataPath stringByAppendingPathComponent:temp];
NSData *data = UIImageJPEGRepresentation([images objectAtIndex:k], 1.0f);
[data writeToFile:imagePath atomically:YES];
}
But a weird thing is last two images are not getting written
I've tried everything but it doesn't seem to work.
Anyone have any idea about this?
Not sure what could be causing your issue, but UIKit is not thread safe, so this could be the cause. You could try and execute your code on the main thread just to troubleshoot it (and check that it is correct), then, if my guess is right, look for a workaround.
In looking for a workaround, possibly performSelector:onMainThread: could help.

Race Condition (?) In iPhone Temp File Writing

I'm creating some temporary files in the iPad simulator. To test my file creation, I create the file and then read it back. Here's some code to show this:
-(NSString *) writeToTempFile:(UIImage*) image{
NSString *path = [self createTemporaryFile];
NSLog(#"path: %#", path);
NSData *data = UIImageJPEGRepresentation(image, 1);
[data writeToFile:path atomically:YES];
free(data);
return path;
}
-(UIImage *) readTempFile:(NSString *) path{
NSData *data = [[NSData alloc] initWithContentsOfFile:path];
UIImage *image = [[UIImage alloc] initWithData:data];
return image;
}
I call these methods one after another, before a final function writes out the UIImage to the photo album.
UIImageWriteToSavedPhotosAlbum(image2, self, nil, nil);
The problem is, this always crashes my app on the third time it is executed. First and second time it successfully does all of this and stores to the album. Third time it crashes to Home. Any ideas?
NSData *data = UIImageJPEGRepresentation(image, 1);
[data writeToFile:path atomically:YES];
free(data);
The NSData returned from UIImageJPEGRepresentation is -autoreleased. There is no need to free() it. And it is wrong to free() any Objective-C objects — send a -release message instead.
Please read through the Memory Management Programming Guide.