objective c - How to convert nsdata to byte array [duplicate] - iphone

This question already has answers here:
How to convert NSData to byte array in iPhone?
(6 answers)
Closed 9 years ago.
I am working with UIImage conversion to NSData. And I want to convert NsData to Byte Array and post that Byte array to server with the help of json Parser.
If i am passing following type of static string to server it accept and store. Following is just example string syntax. i want follwoing type of byte array to post data to server.
[255,216,255,224,0,16,74,70,73,70,0,1,1,1,0,96,0,96,0,0,255,219,0,67,0,8,6,6,7,6,5,8,7,7,7,9,9,8,10,12,...]
For above result i am converting image to data as following:
UIImage *image = [UIImage imageNamed:#"image.png"];
NSData *data = UIImagePNGRepresentation(image);
Now i want to convert NSdata to byte array for that i am using following code:
NSUInteger len = [data length];
Byte *byteData = (Byte*)malloc(len);
memcpy(byteData, [data bytes], len);
free(byteData)
and i also store this to NSdata. but cant get about result.
I also typed about code with looping but every time it gives aPNG as result.
Am i doing any thing wrong in the above code?
Please provide me some help and also request to provide any help for this.
Thanks in advance.

I'm not 100% sure this is what you are looking for or not. Try:
UIImage *image = [UIImage imageNamed:#"image.png"];
NSData *data = UIImagePNGRepresentation(image);
NSUInteger len = data.length;
uint8_t *bytes = (uint8_t *)[data bytes];
NSMutableString *result = [NSMutableString stringWithCapacity:len * 3];
[result appendString:#"["];
for (NSUInteger i = 0; i < len; i++) {
if (i) {
[result appendString:#","];
}
[result appendFormat:#"%d", bytes[i]];
}
[result appendString:#"]"];
Is this what you need?

Related

How to read bytes from NSData

Can anyone suggest a method to read bytes from NSData (like read function in #interface NSInputStream : NSStream)
How to read binary bytes in NSData? may help you:
NSString *path = #"…put the path to your file here…";
NSData * fileData = [NSData dataWithContentsOfFile: path];
const char* fileBytes = (const char*)[fileData bytes];
NSUInteger length = [fileData length];
NSUInteger index;
for (index = 0; index<length; index++) {
char aByte = fileBytes[index];
//Do something with each byte
}
You can also create an NSInputStream from an NSData object, if you need the read interface:
NSData *data = ...;
NSInputStream *readData = [[NSInputStream alloc] initWithData:data];
[readData open];
However, you should be aware that initWithData copies the contents of data.
One of the simplest ways is to use NSData getBytes:range:.
NSData *data = ...;
char buffer[numberOfBytes];
[data getBytes:buffer range:NSMakeRange(position, numberOfBytes)];
where position and length is the position you want to read from in NSData and the length is how many bytes you want to read. No need to copy.
Alex already mentioned NSData getBytes:range: but there is also NSData getBytes:length: which starts from the first byte.
NSData *data = ...;
char buffer[numberOfBytes];
[data getBytes:buffer length:numberOfBytes];
May way of doing that..
do not forget to free byte array after usage.
NSData* dat = //your code
NSLog(#"Receive from Peripheral: %#",dat);
NSUInteger len = [dat length];
Byte *bytedata = (Byte*)malloc(len);
[dat getBytes:bytedata length:len];
int p = 0;
while(p < len)
{
printf("%02x",bytedata[p]);
if(p!=len-1)
{
printf("-");
}//printf("%c",bytedata[p]);
p++;
}
printf("\n");
// byte array manipulation
free(bytedata);

iphone - How do I get the 1st and 2nd byte in a NSData object?

I have a NSData object which is supposed to work like a byte array.
I need to get the 1st and 2nd bytes in the NSData, but don't know how.
If I have a byte array in Java, I can easily get those via barray[0] and barray[1], but how do I do it for NSData?
Thanks
NSData *data = [NSData dataWithBytes:"abc" length:3];
const unsigned char* bytes = [data bytes];
NSLog(#"%c %c",bytes[0],bytes[1]);
You can use this code,
NSUInteger len = [data length];
Byte *byteData = (Byte*)malloc(len);
memcpy(byteData, [data bytes], len);
now byteData[0] will work.

NSData to byte array (or array of integers)

I am working with a webservice which gives me an image as an array of integers. I have managed to convert this array into an NSData object and then into a UIImage using the code below.
Now I am in doubt how I will convert an image into a similar array.
The array looks like this:
[255,216,255,224,0,16,74,70,73,70,0,1,1,1,0,96,0,96,0,0,255,219,0,67,0,8,6,6,7,6,5,8,7,7,7,9,9,8,10,12,...]
This is the code I use to convert the above array to a UIImage.
+ (UIImage *)imageFromBytes:(NSArray *)bytes
{
unsigned char *buffer = (unsigned char *) malloc(bytes.count);
int i = 0;
for (NSDecimalNumber *num in bytes)
buffer[i++] = num.intValue;
NSData *data = [NSData dataWithBytes:buffer length:bytes.count];
free(buffer);
return [UIImage imageWithData:data];
}
So, I need to convert a UIImage into an array of integers (a byte array).
Can anybody point me in the right direction?
You can get the data for an image with:
UIImage *image = [UIImage imageNamed:#"image.png"];
NSData *data = UIImagePNGRepresentation(image);
If you use a JPG you can use UIImageJPEGRepresentation.
And then, extract the array of bytes:
NSUInteger len = [data length];
Byte *byteData = (Byte*)malloc(len);
memcpy(byteData, [data bytes], len);
free(byteData)
You can use also the method (void)getBytes:(void *)buffer length:(NSUInteger)length from NSData:
[data getBytes:&byteData length:len];

Error during insert binary data in Ultralite database iPhone

Hi I am writing a iphone application where I need to store binary data i.e.; image in the Ultralite database.
I am using following code for this purpose.
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"file_name" ofType:#"png"];
NSData *data = [NSData dataWithContentsOfFile:filePath];
NSUInteger len = [data length];
ul_binary *byteData = (ul_binary*)malloc(len);
memcpy(byteData, [data bytes], len);
ULTable *table = connection->OpenTable("NAMES");
if(table->InsertBegin()){
table->SetInt(1, (maxId+1));
table->SetString(2, [name UTF8String]);
table->SetBinary(3, byteData);
table->Insert();
table->Close();
connection->Commit();
}
This code is giving error 'EXC_BAD_ERROR' on line::
table->SetBinary(3, byteData);
This code works fine if i comment this line.
Any help would be appreciated!
Thanks
The definition of ul_binary is this:
typedef struct ul_binary {
/// The number of bytes in the value.
ul_length len;
/// The actual data to be set (for insert) or that was fetched (for select).
ul_byte data[ MAX_UL_BINARY ];
} ul_binary, * p_ul_binary;
So it's a struct. By simply doing the memcpy as you do, you also overwrite the len field and everythings messed up. So here's how you should do it (as far as I can see):
ul_binary *byteData = (ul_binary *)malloc(sizeof(ul_binary));
memcpy(&byteData->data, [data bytes], len);
byteData->len = len;
You also need to check that len <= MAX_UL_BINARY before you try to allocate the memory. And don't forget to free(byteData);.

NSData to NString conversion problem

I'm getting an HTML file as NSData and need to extract some parts of it. For that I need to convert it to NSString with UTF8 encoding. The thing is that this conversion fails, probably because the NSData contains bytes that are invalid for UTF8. I have tried to get the byte array of the data and go over it, but each time I come across non ASCII character (hebrew letters for example) I get jibrish.
Help will be appreciated.
UPDATE:
To Gordon - the NSData generated like that:
NSData *theData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&theResponse error:&theError];
When I say that the conversion fails I mean that
[[NSString alloc] initWithData:temp encoding:NSUTF8StringEncoding]
returns nil
To Ed - Here is my code (I got the Byte array from NSData, found what I need, and constructed another Byte array from that - turned it to NSData and then attempted to convert it to NSString... sounds kinda complicated...)
-(NSString *)UTF8StringFromData:(NSData *)theData{
Byte *arr = [theData bytes];
NSUInteger begin1 = [self findIndexOf:#"<li>" bArr:arr size:[theData length]]+4;
NSUInteger end1 = [self findIndexOf:#"</li></ol>" bArr:arr size:[theData length]];
Byte *arr1 = (Byte *)malloc(sizeof(Byte)*((end1-begin1+1)));
NSLog(#"%d %d",begin1, end1);
int j = 0;
for (int i = begin1; i < end1; i++){
arr1[j] = arr[i];
j++;
}
arr1[j]='\0';
NSData *temp = [NSData dataWithBytes:arr1 length:j];
return [[NSString alloc] initWithData:temp encoding:NSUTF8StringEncoding];
}
I know this is an old topic but it came up when I was looking for the solution today. I've solved it now so I'm just posting it for others who might run into this page looking for a solution.
Here's what I do in an asynchronous request:
I first store the text encoding name in connection:didReceiveResponse using
encodingName = [[NSString alloc] initWithString:[response textEncodingName]];
Then later in my connectionDidFinishLoading method I used
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((CFStringRef) encodingName));
NSString *payloadAsString = [[NSString alloc] initWithData:receivedData encoding:encoding];
To Gordon - the NSData generated like that:
NSData *theData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&theResponse error:&theError];
When I say that the conversion fails I mean that
[[NSString alloc] initWithData:temp encoding:NSUTF8StringEncoding]
returns nil
To Ed - Here is my code (I got the Byte array from NSData, found what I need, and constructed another Byte array from that - turned it to NSData and then attempted to convert it to NSString... sounds kinda complicated...)
-(NSString *)UTF8StringFromData:(NSData *)theData{
Byte *arr = [theData bytes];
NSUInteger begin1 = [self findIndexOf:#"<li>" bArr:arr size:[theData length]]+4;
NSUInteger end1 = [self findIndexOf:#"</li></ol>" bArr:arr size:[theData length]];
Byte *arr1 = (Byte *)malloc(sizeof(Byte)*((end1-begin1+1)));
NSLog(#"%d %d",begin1, end1);
int j = 0;
for (int i = begin1; i < end1; i++){
arr1[j] = arr[i];
j++;
}
arr1[j]='\0';
NSData *temp = [NSData dataWithBytes:arr1 length:j];
return [[NSString alloc] initWithData:temp encoding:NSUTF8StringEncoding];
}
have you checked the charset= in the HTTP headers and/or the document itself? The most likely reason for the conversion to fail is because the bytes don't represent a valid UTF-8 string.
I'm not sure if you're aware, you don't really need to copy the array to another array before putting it into the new NSData object.
-(NSString *)UTF8StringFromData:(NSData *)theData {
Byte *arr = [theData bytes];
NSUInteger begin1 = [self findIndexOf:#"<li>" bArr:arr size:[theData length]]+4;
NSUInteger end1 = [self findIndexOf:#"</li></ol>" bArr:arr size:[theData length]];
Byte *arr1 = arr + begin1;
NSData *temp = [NSData dataWithBytes:arr1 length:end1 - begin1];
return [[NSString alloc] initWithData:temp encoding:NSUTF8StringEncoding];
}
As for your particular problem, I would try looking through the data manually using the debugger. Put a breakpoint after you have your array (arr1). When you hit it, open up the GDB console and try this:
print (char *)arr1
With your code, it should print out the string you're trying to get. (With the code I gave above, it won't stop after the . It'll just keep going).
If the result is not what you expect, then there's something wrong with the data, or perhaps with your begin1 and end1 boundaries.