NSString *imgvalue=[[NSString alloc]initWithString:item.imgItem];
printf("\n img1 value is %s",[imgvalue UTF8String]);
cell.imageView.image=[UIImage imageNamed:#"unknown.jpg"];
if (imgvalue !=nil)
{
NSData *imageData;
#try
{
printf("\n image value in image data is %s",[imgvalue UTF8String]);
imageData = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:imgvalue]];
printf("\n imageData Length is %d",[imageData length]);
}
#catch (NSException * e)
{
//printf("Exception message is %s",[e);
}
#finally
{
UIImage * imageFromImageData = [[UIImage alloc] initWithData:imageData];
//[image setImage:imageFromImageData];
cell.imageView.image=imageFromImageData;
[imageData release];
[imageFromImageData release];
}
}
After getting the imgValue I copied that url and when I checked in the browser it shows me the image but it didn't store into NSData.Please help me
I checked your code and everything seems to be working.
Please check imageData with
NSLog(#"%u", [imageData length]);
Change this line
NSString *imgvalue=[[NSString alloc]initWithString:item.imgItem];
to
NSString *imgvalue=#"http://animals.catchsmile.com/cat-3/";
using this i got data in log..
i have used static string and tested you can use item.imgItem value as well..
Related
We are facing problem while creating compressed file at iOS Device Document Directory, .tgz file is in Hex string transferring from pin-pad device to iPad iOS App at TCP socket layer. We used below HexToString function to convert that hex string and make file with .tgz. but at the end file is corrupted.
Can anyone please help us here, how to create compress file at iOS level with below hex string ? Please suggest us any code changes.
Note :- we had tried multiple NSStringEncoding technique, like ASCII, Unicode, Utf8, etc.
HEX String:-
1F8B08003058A8620203EDCA3B0A80301045D1594A5660265FB7E036065422A8453282CB57B4B2B112419CD3DCE2BD6966DD8F54925E4A975B62D22551EE741A2A5E199E80BBE8F1681DFDA5270BC6DB60D1398735A0092E0650082F580A53566A6F36F7BFFBFDA39A01841042FCD0062C8057FA00080000
we are using Xcode Version:13.1 and IOS Version 15.1 and above.
//Below function we used for creating .tgz file
//fileName here is abc.tgz which is compress file type
//content here is hex string mention aboved
+ (void)writeToLogFile:(NSString*)content fileName:(NSString*)fileNameString{
content = [NSString stringWithFormat:#"%#",content];
NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:fileNameString];
NSData *fileOriginalString = [self HextoString:content];
NSData *fileData = [fileOriginalString dataUsingEncoding:NSASCIIStringEncoding];
***//In alternative we also tried direct hex string to NSData type by calling below commentented method but it still failing
//NSData *fileData = [self dataFromHexString:content];***
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSError *error = nil;
[fileData writeToFile:fileName options:NSDataWritingAtomic error:&error];
NSLog(#"Write returned error: %#", [error localizedDescription]);
});
}
//Below function we used for Hex to String conversion
+(NSString*)HextoString:(NSString*)string{
#try{
NSMutableString * StrResult = [[NSMutableString alloc] init];
int i = 0;
while (i < [string length]){
NSString * hexChar = [string substringWithRange: NSMakeRange(i, 2)];
int value = 0;
sscanf([hexChar cStringUsingEncoding:NSASCIIStringEncoding], "%x", &value);
[StrResult appendFormat:#"%c", (char)value];
i+=2;
}
return StrResult;
}
#catch (NSException *exception){
[AELoggerManager info:[NSString stringWithFormat:#" %s EXCEPTION ::%#",__FUNCTION__,exception]];
}
}
+ (NSData *)dataFromHexString:(NSString *) string {
if([string length] % 2 == 1){
string = [#"0"stringByAppendingString:string];
}
const char *chars = [string UTF8String];
int i = 0, len = (int)[string length];
NSMutableData *data = [NSMutableData dataWithCapacity:len / 2];
char byteChars[3] = {'\0','\0','\0'};
unsigned long wholeByte;
while (i < len) {
byteChars[0] = chars[i++];
byteChars[1] = chars[i++];
wholeByte = strtoul(byteChars, NULL, 16);
[data appendBytes:&wholeByte length:2];
}
return data;
}
My server is giving me my jpg image in the following NSData format:
/9j/4AAQSkZJRgABAQAASABIAAD/4QBMRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQA
AAABAAAAJgAAAAAAAqACAAQAAAABAAAGqKADAAQAAAABAAAI4AAAAAD/7QA4UGhvdG9zaG9wIDMu
MAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs+EJ+/8AAEQgI4AaoAwERAAIR
AQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAAB
fQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5/
I am saving it to a file, and while reading that file, the img object in my code below is giving me nil, although imgData object is holding the saved data.
- (void)selectedAttachedFiledownloadedSuccessfully
{
NSLog(#"\nFile has downloaded\n");
NSData *imgData = [NSData dataWithContentsOfFile:[self pathOfTheImage]];
NSString * imageExt = [self contentTypeForImageData:imgData];
UIImage *img = [UIImage imageWithData:imgData];
self.imgView.image = img;
}
Checking NSData for the image formats, it's not matching any and my code below is returning me nil
- (NSString *)contentTypeForImageData:(NSData *)data {
uint8_t c;
[data getBytes:&c length:1];
switch (c) {
case 0xFF:
return #"image/jpeg";
case 0x89:
return #"image/png";
case 0x47:
return #"image/gif";
case 0x49:
case 0x4D:
return #"image/tiff";
}
return nil;
}
I don't know what I am doing wrong over here. Can any one guide me through this plz?
You might have used the wrong encoding (such as NSUTF8StringEncoding) when storing the data.
NSUTF32StringEncoding should be used for image data.
The NSData which you are getting back from server might be corrupted. If the data is not in proper format it will not give you back the proper image
Use + (instancetype)dataWithContentsOfFile:(NSString *)path options:(NSDataReadingOptions)mask error:(NSError * _Nullable *)errorPtr to read your image back from file and check the value of errorPtr
Refer this link for explanation for the above method https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/#//apple_ref/occ/clm/NSData/dataWithContentsOfFile:options:error:
The server was sending my the image in base64Binary string format. I changed it to NSData as:
NSData *data = [[NSData alloc] initWithBase64EncodedString:output[1] options:NSDataBase64DecodingIgnoreUnknownCharacters];
I save this data to my image file as:
[data writeToFile:filePath atomically:YES];
Read it to show it on image view as:
- (void)showImage
{
NSData *imgData = [NSData dataWithContentsOfFile:[self pathOfTheImage]];
UIImage *img = [UIImage imageWithData:imgData];
self.imgView.image = img;
}
It's working fine now.
I'm building an app that allows users to select photos and videos from their device and upload them to the server. Trying to get the file size (in bytes) of each item select, can anyone help me out?
if ([dict objectForKey:UIImagePickerControllerMediaType] == ALAssetTypePhoto){ // image file
if ([dict objectForKey:UIImagePickerControllerOriginalImage]){
NSURL* urlPath=[dict objectForKey:#"UIImagePickerControllerReferenceURL"];
item = [BundleItem itemWithPath:urlPath AndDescription:nil];
item.itemImage = [dict objectForKeyedSubscript:UIImagePickerControllerOriginalImage];
item.itemType = 1; // image
item.itemSize = // what do I need here??
[m_items addObject:item];
}
} else if ([dict objectForKey:UIImagePickerControllerMediaType] == ALAssetTypeVideo){ // video file
if ([dict objectForKey:UIImagePickerControllerOriginalImage]){
NSURL* urlPath=[dict objectForKey:#"UIImagePickerControllerReferenceURL"];
item = [BundleItem itemWithPath:urlPath AndDescription:nil];
item.itemImage = [dict objectForKeyedSubscript:UIImagePickerControllerOriginalImage];
item.itemType = 2; // video
item.itemSize = // what do I need here??
[m_items addObject:item];
}
}
EDIT
Getting NSCocaoErrorDomain 256 with videos:
NSURL* urlPath=[dict objectForKey:#"UIImagePickerControllerReferenceURL"];
item = [BundleItem itemWithPath:urlPath AndDescription:nil];
item.itemImage = [dict objectForKeyedSubscript:UIImagePickerControllerOriginalImage];
item.itemType = 2; // video
//Error Container
NSError *attributesError;
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[urlPath path] error:&attributesError];
NSNumber *fileSizeNumber = [fileAttributes objectForKey:NSFileSize];
long fileSize = [fileSizeNumber longValue];
item.itemSize = fileSize;
[m_items addObject:item];
For only image data selection:
item.itemImage = (UIImage*)[info valueForKey:UIImagePickerControllerOriginalImage];
NSData *imgData = UIImageJPEGRepresentation(item.itemImage, 1); //1 it represents the quality of the image.
NSLog(#"Size of Image(bytes):%d",[imgData length]);
Hope this will help you.
Below method is generalize, it will work for both image and video:
Something like this should take care finding the file size of a selected image or video returned from the UIImagePickerController
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSURL *videoUrl=(NSURL*)[info objectForKey:UIImagePickerControllerMediaURL];
//Error Container
NSError *attributesError;
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[videoUrl path] error:&attributesError];
NSNumber *fileSizeNumber = [fileAttributes objectForKey:NSFileSize];
long long fileSize = [fileSizeNumber longLongValue];
}
Hey I use this method to return NSData.
-(NSData*)getPersonPicture:(NSDictionary *)person {
NSData *imageData = nil;
if (![person valueForKey:FIELD_PERSON_IMAGEDATA]) {
return imageData;
}
if ([[[person valueForKey:FIELD_PERSON_IMAGEDATA] description]containSubString:#"http"]) {
return [NSData dataWithContentsOfURL:[NSURL URLWithString:[person valueForKey:FIELD_PERSON_IMAGEDATA]]];
} else {
ABRecordRef _person = ABAddressBookGetPersonWithRecordID(_aBook,[[person valueForKey:FIELD_PERSON_IMAGEDATA] integerValue]);
imageData = (__bridge NSData*)ABPersonCopyImageDataWithFormat(_person, kABPersonImageFormatThumbnail);
return imageData;
}
}
I can't figure when I need to release this imageData. I can't leave it like this , right?
If you are using ARC, then ARC need to take ownership of the Core Foundation object - which means, ARC will become responsible for it. You can accomplish this with macro CFBridgingRelease:
imageData = CFBridgingRelease(ABPersonCopyImageDataWithFormat(_person, kABPersonImageFormatThumbnail));
return imageData;
Using non-ARC:
(note: usually, we should leveraging ARC!)
-(NSData*)getPersonPicture:(NSDictionary *)person {
NSData *imageData = nil;
if (![person valueForKey:FIELD_PERSON_IMAGEDATA]) {
return imageData;
}
if ([[[person valueForKey:FIELD_PERSON_IMAGEDATA] description]containSubString:#"http"]) {
return [NSData dataWithContentsOfURL:[NSURL URLWithString:[person valueForKey:FIELD_PERSON_IMAGEDATA]]];
} else {
ABRecordRef _person = ABAddressBookGetPersonWithRecordID(_aBook,[[person valueForKey:FIELD_PERSON_IMAGEDATA] integerValue]);
CFDataRef cfData = ABPersonCopyImageDataWithFormat(_person, kABPersonImageFormatThumbnail);
imageData = [[(NSData*)cfData retain] autorelease];
return imageData;
}
}
I Want to save the image in Database and fetch the image in database.i am convert the image in NSData and the image is store successfully in database but when i fetch that image from database then it crash.it give this warning
Warning :- -[__NSCFString bytes]: unrecognized selector sent to instance 0x7916000
Below code For save the image in Database
NSData *dataImage1 = UIImagePNGRepresentation(image3.image);
NSString *str = [NSString stringWithFormat:#"Insert into Gallery(ImageName) VALUES ('%#')",dataImage1];
[Database executeQuery:str];
//Database.m
+(NSString* )getDatabasePath{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:#"Database"];
return writableDBPath;
}
+(NSMutableArray *)executeQuery:(NSString*)str{
sqlite3_stmt *statement= nil;
sqlite3 *database;
NSString *strPath = [self getDatabasePath];
NSMutableArray *allDataArray = [[NSMutableArray alloc] init];
if (sqlite3_open([strPath UTF8String],&database) == SQLITE_OK) {
if (sqlite3_prepare_v2(database, [str UTF8String], -1, &statement, NULL) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
NSInteger i = 0;
NSInteger iColumnCount = sqlite3_column_count(statement);
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
while (i< iColumnCount) {
NSString *str = [self encodedString:(const unsigned char*)sqlite3_column_text(statement, i)];
NSString *strFieldName = [self encodedString:(const unsigned char*)sqlite3_column_name(statement, i)];
[dict setObject:str forKey:strFieldName];
i++;
}
[allDataArray addObject:dict];
[dict release];
}
}
sqlite3_finalize(statement);
}
sqlite3_close(database);
return allDataArray;
}
//Fetch image
NSString *str =[NSString stringWithFormat:#"Select * from Gallery where id = 1"];
NSMutableArray *arra =[Database executeQuery:str];
NSData *d =[[arra objectAtIndex:0] valueForKey:#"ImageName"];
UIImage *img = [[UIImage alloc] initWithData:d];
NSLog(#"%#",img);
Thanks in Advance
Your problem is that you cannot insert binary data by building a SQL statement with a stringWithFormat. You're inserting the NSData (binary data) into a field called ImageName, and you cannot use stringWithFormat to build that SQL statement.
Did you really mean to insert the image itself? In that case you'd use SQL like below, with a ? placeholder, and then use sqlite3_bind_blob for column number 1 with your NSData before you call sqlite3_step. Thus, the SQL would look like:
Insert into Gallery(ImageName) VALUES (?)
(As an aside, I'm not a fan of the choice of ImageName for the actual data of the image. I'd either use Image for the actual image data, or ImageName for the name of the image.)
And then, after preparing your SQL, you'd then call:
sqlite3_bind_blob(statement, 1, [dataImage1 bytes], [dataImage1 length], SQLITE_TRANSIENT);
You can then invoke sqlite3_step, like normal, to execute the SQL to insert the data.
When retrieving the data, after you successfully sqlite3_step, you'd use the appropriate sqlite3_column_blob functions:
const void *bytes = sqlite3_column_blob(statement, 0);
int len = sqlite3_column_bytes(statement, 0);
NSData *data = [NSData dataWithBytes:bytes length:len];
UIImage *image = [UIImage imageWithData:data];
Having said that, SQLite is notoriously inefficient in storing large blob data. You might want to store the image in the Documents folder and then just store the filename in your ImageName field.
i think you are getting bytes in string type in
[[arra objectAtIndex:0] valueForKey:#"ImageName"];
so first get string and then convert it to data.
try like this:
NSData* data = [[[arra objectAtIndex:0] valueForKey:#"ImageName"] dataUsingEncoding:NSUTF8StringEncoding];