Error when compressing jpeg data using - iphone-sdk-3.0

I get the following error when trying to compress some jpeg data using UIImageJPEGRepresentation(image, 0.5f);
<Error>: Unsupported pixel description - 4 components, 8 bits-per-component, 32 bits-per-pixel
<Error>: CGBitmapContextCreateWithDictionary: failed to create delegate.
<Error>: CGImageDestinationAddImage image could not be converted to destination format.
<Error>: CGImageDestinationFinalize image destination does not have enough images
Here is the code snippet where I download and compress the data...
ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:object.largeimage]];
[request startSynchronous];
NSData *imageData = [request responseData];
UIImage *image = [[UIImage alloc] initWithData:imageData];
NSData *compressedImageData = UIImageJPEGRepresentation(image, 0.5f);
//If the data was compressed properly...
if(compressedImageData) [compressedImageData writeToFile:filePath atomically:YES];
//If it wasn't...
else [imageData writeToFile:filePath atomically:YES];
[image release];
if(request.responseStatusCode == 200)
object.fullImageFilename = filePath;
[request release];
[request release];
Thanks in advance for any help :)

Still not sure of the "proper answer", but I managed to find a workaround for anyone who's interested :)
ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:object.largeimage]];
[request startSynchronous];
NSData *imageData = [request responseData];
UIImage *image = [[UIImage alloc] initWithData:imageData];
NSData *compressedImageData = UIImageJPEGRepresentation(image, 0.5f);
//If the data was compressed properly...
if(compressedImageData) [compressedImageData writeToFile:filePath atomically:NO];
//If it wasn't...
else
{
UIGraphicsBeginImageContext(image.size);
[image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
compressedImageData = UIImageJPEGRepresentation(newImage, 0.5f);
[compressedImageData writeToFile:filePath atomically:NO];
[newImage release];
}
[image release];
if(request.responseStatusCode == 200)
object.fullImageFilename = filePath;
[request release];

Related

Can't get resized image to save at new size

I have the following code
if (! [url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&error]) {
// handle error
}
else if (! [isValidDirectory boolValue]) {
// No error and it’s not a directory; do something with the file
NSString* outP = [url absoluteString];
NSString* extension = [outP substringFromIndex: outP.length-3];
NSString* img = #"png";
if([extension isEqualToString:img]){
NSImage *original = [[NSImage alloc] initWithContentsOfURL: url];
NSSize sizes = NSMakeSize(240, 240);
NSImage *small =original;
[small setSize:sizes];
NSArray* representations = [small representations];
NSInteger* total = [substrings count];
NSData* bitmapData = [NSBitmapImageRep representationOfImageRepsInArray: representations usingType: NSPNGFileType properties:nil];
[bitmapData writeToFile:#"/Users/testuser/downloads/test/test_tn.png" atomically:NO];
}
when I run it it does not resize the image it just gives me a straight copy of the image with the name test_tn.png instead of a smaller image. I'm not sure what I'm doing wrong, this is a mac app also. There is some unused code in there that is for later. Is the problem how I'm passing the NSImage to the NSData after i resize?
edit: ok so i converted the NSData back into an NSImage and it appears the NSData is not getting the sized data but the original data.
edit 2: so this works
ok so this works
if([extension isEqualToString:img]){
NSImage *image = [[NSImage alloc] initWithContentsOfURL: url];
NSData *sourcedata =[image TIFFRepresentation];
NSSize newSize;
newSize.height = 160;
newSize.width = 120;
NSImage *sourceImage =[[NSImage alloc] initWithData: sourcedata];
NSImage *resizedImage = [[NSImage alloc] initWithSize: NSMakeSize(240, 240)];
NSSize originalSize = [sourceImage size];
[resizedImage lockFocus];
[sourceImage drawInRect: NSMakeRect(0, 0, 240, 240) fromRect: NSMakeRect(0, 0, originalSize.width, originalSize.height) operation: NSCompositeSourceOver fraction: 1.0];
[resizedImage unlockFocus];
NSData *resizedData = [resizedImage TIFFRepresentation];
NSData *resizedPreviewData = [resizedImage TIFFRepresentation];
NSBitmapImageRep *resizedCaptureImageBitmapRep = [[NSBitmapImageRep alloc] initWithData:resizedPreviewData];
NSData* saveData = [resizedCaptureImageBitmapRep representationUsingType:NSPNGFileType properties:nil];
[saveData writeToFile:#"/Users/testuser/downloads/test/test_tn.png" atomically:YES];
count++;
}
This works for me. I am using this code to layer images on top of each other, but it should be easily adapted to your purposes:
CGSize destinationSize = smallSize;
UIGraphicsBeginImageContext(original.size);
[Original1 drawInRect:CGRectMake(0, 0, original.size.width, original.size.height)];
[Original2 drawInRect:CGRectMake(0, 0, original.size.width, original.size.height)];
UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIGraphicsBeginImageContext(destinationSize);
[returnImage drawInRect:CGRectMake(0,0,destinationSize.width,destinationSize.height)];
UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

GIFs don't animate when using NSThread

I'm writing an application in Objective C and Cocoa for Mac OS X that loads GIFs from an external source and displays them on screen. The user searches for a term, GIFs are downloaded and placed into NSImageViews, and then those views are displayed in a scroll view.
Earlier, the GIFs were animated as expected. I then tried to use an NSThread to do the loading of the GIFs and adding to the scroll view separate from the main thread. Here is the method that is called in the thread:
- (void)threading:(id)obj
{
NSURL *url = [NSURL URLWithString: #"URL HERE"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setURL:url];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSError *error;
NSURLResponse *response;
NSDictionary *data = [NSJSONSerialization JSONObjectWithData:[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error] options:NSJSONReadingMutableLeaves error:nil];
NSArray *gifs = [data objectForKey:#"data"];
for (int i = 0; i < 1; i++) { // try to load 1 gif
NSString *currentGifURL = #"whatever";
NSImageView *imgView = [[NSImageView alloc] initWithFrame:CGRectMake(10, 1820-100*i, 150, 120)];
// I tried using these 2 lines, still didn't work
//[imgView setAnimates:YES]; [imgView setImageScaling:NSScaleNone];
NSURL *imageURL = [NSURL URLWithString:currentGifURL];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
NSImage *image = [[NSImage alloc] initWithData:imageData];
imgView.image = image;
[_scrollView.documentView addSubview:imgView];
}
[_progressIndicator stopAnimation:self];
}
I later call
[NSThread detachNewThreadSelector:#selector(threading:) toTarget:self withObject:nil];
To create the thread. The images appear on screen, but only the first frame is displayed—they're not animated. Literally replacing the thread initialization with the code from inside the thread renders the same view, except the GIFs are animated. Is there something about threads that would prevent the GIFs from animating?
Thanks!
NSImageView is not threadsafe. use - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
- (void)threading:(id)obj
{
NSURL *url = [NSURL URLWithString: #"URL HERE"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setURL:url];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSError *error;
NSURLResponse *response;
NSDictionary *data = [NSJSONSerialization JSONObjectWithData:[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error] options:NSJSONReadingMutableLeaves error:nil];
NSArray *gifs = [data objectForKey:#"data"];
for (int i = 0; i < 1; i++) { // try to load 1 gif
NSString *currentGifURL = #"whatever";
// I tried using these 2 lines, still didn't work
//[imgView setAnimates:YES]; [imgView setImageScaling:NSScaleNone];
NSURL *imageURL = [NSURL URLWithString:currentGifURL];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
NSImage *image = [[NSImage alloc] initWithData:imageData];
[self performSelectorOnMainThread:#selector(LoadImageView:) withObject:image waitUntilDone:NO];
}
[_progressIndicator stopAnimation:self];
}
-(void)LoadImageView : (NSImage *)image
{
NSImageView *imgView = [[NSImageView alloc] initWithFrame:CGRectMake(10, 1820-100*i, 150, 120)];
imgView.image = image;
[_scrollView.documentView addSubview:imgView];
}

Nothing displayed after splitting a list of image URLs

I have six image URLs in a string named aux. I split it with component separated by newlines. I want to pick images one by one from aux and display each in an ImageView. My code is:
aux = [_homeText.text stringByAppendingString:[NSString stringWithFormat:#" %# ",item.shortDescription]];
[_homeText setText:aux];
NSString *list =aux;
NSArray *listItems = [list componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
[listItems count];
if ([listItems objectAtIndex:0]) {
NSURL *url = [NSURL URLWithString:aux];
/*UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"hai" message:aux delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil];
[alert show];
[alert release];*/
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [[UIImage alloc] initWithData:data];
[_homeImage setImage:image];
}
else if ([listItems objectAtIndex:1])
{
NSURL *url = [NSURL URLWithString:aux];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [[UIImage alloc] initWithData:data];
[_homeImage setImage:image];
}
There is no error but I get no image. Why? How do I fix this?
If both data and image not nil, you may try to correctly initialize _homeImage.
I don'w know why, but I think what you created _homeImage like this:
_homeImage = [[UIImageView alloc] init];
Try to do something like this:
CGSize imageSize = [image size];
[_homeImage setFrame:CGRectMake([_homeImage frame].origin.x,
[_homeImage frame].origin.y,
imageSize.width, imageSize.height)];
[_homeImage setImage:image];
[image release], image = nil;

fetch image by using url

I want image on view by fetching it from some url. I want changing in given code..
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
UIImage *image = [[UIImage imageNamed:<#(NSString *)name#>
NSString * mediaUrl = [[[self appDelegate]currentlySelectedBlogItem]mediaUrl];
[[self image]setImage:[UIImage imageNamed:#"unknown.jpg"]];
if(nil != mediaUrl){
NSData* imageData;
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
#try {
imageData = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:mediaUrl]];
}
#catch (NSException * e) {
//Some error while downloading data
}
#finally {
UIImage * imageFromImageData = [[UIImage alloc] initWithData:imageData];
[[self image]setImage:imageFromImageData];
[imageData release];
[imageFromImageData release];
}
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
self.titleTextView.text = [[[self appDelegate] currentlySelectedBlogItem]title];
self.descriptionTextView.text = [[[self appDelegate] currentlySelectedBlogItem]description];
}
Using this will give you a solution
NSURL *url = [NSURL URLWithString:#"ENTER YOUR URL HAVING THE IMAGE"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
I have used the following:
NSString *url=[NSString stringWithFormat:#"Your URL"];
//NSLog(#"URL=%#",url);
UIImage *myImage=[[UIImage alloc] initWithData:[NSData UIImage *myImage=[[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString: url]]];
NSLog(#"%d byte of data", [[NSData dataWithContentsOfURL: [NSURL URLWithString: url]] length]);
if (myImage)
{
//THIS CODE WILL STORE IMAGE DOCUMENT DIRECTORY
NSString *jpegFilePath = [NSString stringWithFormat:#"%#/%#.jpg",[self pathForDocumentDirectory],[self.idOfImagesToDownload objectAtIndex:i]];
NSData *data1 = [NSData dataWithData:UIImageJPEGRepresentation(myImage, 1.0f)];//1.0f = 100% quality
[data1 writeToFile:jpegFilePath atomically:YES];
}
NOTE:[self pathForDocumentDirectory] is method returning path of document directory.

how to compress image programmatically

I am receiving images from xml feed they are very large in size how can i compress them before displaying them in table-cell.
my code is
int blogEntryIndex1 = [indexPath indexAtPosition: [indexPath length] -1];
imgstring=[[blogEntries objectAtIndex: blogEntryIndex1] objectForKey: #"image"];
NSURL *url = [NSURL URLWithString:imgstring];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
cell.imageView.image=[img autorelease];
please help me if you can.....
I've got this utility method that will scale an image :
- (UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize {
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Use it like this :
int blogEntryIndex1 = [indexPath indexAtPosition: [indexPath length] -1];
imgstring=[[blogEntries objectAtIndex: blogEntryIndex1] objectForKey: #"image"];
NSURL *url = [NSURL URLWithString:imgstring];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [self imageWithImage:[UIImage imageWithData:data] scaledToSize:CGSizeMake(20, 20)]; // Scale it to 20x20px
cell.imageView.image=[img autorelease];
NB I can't for the life of me remember where I got it from but it's served me well in the past
Simple to use:-
-(UIImage *)fireYourImageForCompression:(UIImage *)imgComing{
NSData *dataImgBefore = [[NSData alloc] initWithData:UIImageJPEGRepresentation((imgComing), 1.0)];//.1 BEFORE COMPRESSION
int imageSizeBefore = (int)dataImgBefore.length;
NSLog(#"SIZE OF IMAGE: %i ", imageSizeBefore);
NSLog(#"SIZE OF IMAGE in Kb: %i ", imageSizeBefore/1024);
NSData *dataCompressedImage = UIImageJPEGRepresentation(imgComing, .1); //.1 is low quality
int sizeCompressedImage = (int)dataCompressedImage.length;
NSLog(#"SIZE AFTER COMPRESSION OF IMAGE: %i ", sizeCompressedImage);
NSLog(#"SIZE AFTER COMPRESSION OF IMAGE in Kb: %i ", sizeCompressedImage/1024); //AFTER
//now change your image from compressed data
imgComing = [UIImage imageWithData:dataCompressedImage];
return imgComing;}