I want to save image from NSdata after appending additional bytes to the NSMutableData. Below is the sample code for my requirement.
NSData *sourceData = = UIImageJPEGRepresentation([info objectForKey:#"UIImagePickerControllerOriginalImage"], 1);
NSMutableData *concatenatedData = [NSMutableData data];
[concatenatedData appendData:sourceData];
[concatenatedData appendData:sourceData];
UIImage *myFinalImage = [[UIImage alloc] initWithData:concatenatedData];
UIImageWriteToSavedPhotosAlbum(myFinalImage, self, nil, nil);
I am appending the sourcedata 2 times but my final Image is saving with only one sourceData bytes.
Am I missing something here?
Here is the Sample:
CGSize newSize = CGSizeMake({Here give width}, {Here give height});
UIImage *myFinalImage1 = [[UIImage alloc] initWithData:concatenatedData];
UIImage *myFinalImage2 = [[UIImage alloc] initWithData:concatenatedData];
// Set up width height with values.
CGSize newSize = CGSizeMake(width, height);
UIGraphicsBeginImageContext( newSize );
[myFinalImage1 drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
[myFinalImage2 drawInRect:CGRectMake(newSize.width,newSize.height,newSize.width,newSize.height*2) blendMode:kCGBlendModeNormal alpha:1.0];
UIImage *mergedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Related
I'm trying to save an array of images that I retrieve asynchronously in the cellForRowInIndexPath method of the UITableViewController.
Unfortunately, the array is not fully populated or in incorrect order.
The code within my tableview:cellForRowAtIndexPath method is:
// populate the cell's image
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(queue, ^{
NSURL *url = [NSURL URLWithString:[newsModel url]];
NSData *data = [NSData dataWithContentsOfURL:url];
img = [[UIImage alloc] initWithData:data] ;
[imageArray insertObject:img atIndex:[indexPath row]];
dispatch_sync(dispatch_get_main_queue(), ^{
// make image standard size
CGSize imageSize = CGSizeMake(40, 40);
UIGraphicsBeginImageContext(imageSize);
CGRect imageRect = CGRectMake(0.0, 0.0, imageSize.width, imageSize.height);
[img drawInRect:imageRect];
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[cell setNeedsLayout];
});
});
Both the imageArray (NSMutableArray) and img (UIImage) are of type __bool.
Thanks in advance for your help.
Try to store into dictionary with key inplace of array because no chances to duplication after that insert into array using AllValue of dictionary
For ex:
imageArray =[[dict allValues]mutableCopy];
NSMutableDictionary *dict=[[NSMutableDictionary alloc]init];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(queue, ^{
NSURL *url = [NSURL URLWithString:[newsModel url]];
NSData *data = [NSData dataWithContentsOfURL:url];
img = [[UIImage alloc] initWithData:data] ;
[dict setObject:img forKey:indexPath.row]
dispatch_sync(dispatch_get_main_queue(), ^{
// make image standard size
CGSize imageSize = CGSizeMake(40, 40);
UIGraphicsBeginImageContext(imageSize);
CGRect imageRect = CGRectMake(0.0, 0.0, imageSize.width, imageSize.height);
[img drawInRect:imageRect];
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[cell setNeedsLayout];
});
});
imageArray =[[dict allValues]mutableCopy];
Don't try to modify the cell after the download has completed, you don't know if it's been reused. Just save the image and then ask the table view to reloadData (ensure you ask for the reload on the main thread).
In Instruments it tells me that there is a leak caused by CGBitmapContextCreateImage in my resizedImage method. However after a lot of research and trial and error, I have come to the conclusion that it is caused somewhere else in the call chain.
The call chain is as follows:
takeFoto -> saveFoto -> setImage_bg -> bolly -> resizedImage
Here is all the related code
-(void)takeFoto
{
[stillImageOutput captureStillImageAsynchronouslyFromConnection:self.videoConnection completionHandler:
^(CMSampleBufferRef imageSampleBuffer, NSError *error)
{
NSData* idata = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];//[od copy];
UIImage *image = [UIImage imageWithData:idata];
CGImageRef cgi = [image CGImage];
CGImageRef cgi2 = CGImageCreateWithImageInRect(cgi, CGRectMake(0, 0, CGImageGetWidth(cgi), CGImageGetHeight(cgi));
UIImageOrientation iori;
if(self.devOri==UIInterfaceOrientationLandscapeRight)
{
if([self isFrontCamera]) iori = UIImageOrientationDownMirrored;
else iori = UIImageOrientationUp;
}
else if(self.devOri==UIInterfaceOrientationLandscapeLeft)
{
if([self isFrontCamera]) iori = UIImageOrientationUpMirrored;
else iori = UIImageOrientationDown;
}
else if(self.devOri==UIInterfaceOrientationPortraitUpsideDown)
{
if([self isFrontCamera]) iori = UIImageOrientationRightMirrored;
else iori = UIImageOrientationLeft;
}
else
{
if([self isFrontCamera]) iori = UIImageOrientationLeftMirrored;
else iori = UIImageOrientationRight;
}
UIImage *scaledImage = [[UIImage alloc] initWithCGImage:cgi2 scale:1 orientation:iori];
CGImageRelease(cgi2);
self.foto = scaledImage;
[scaledImage release];
[parent saveFoto];
}];
}
-(void)saveFoto
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[self setImage_bg:captureManager.foto];
[pool release];
}
-(void)setImage_bg:(UIImage*)oimg
{
CGSize sz = savePreview.frame.size;
UIImage* img = [oimg copy];
[savePreview setImage:[filters resizeImage:img size:sz]];
sz = CGSizeMake(64, 64);
UIImage* img2 = [filters resizeImage:img size:sz];
bolPrv.image = [filters bolly:img2];
[img release];
}
//filters bolly
-(UIImage*)bolly:(UIImage*)img
{
CIImage *beginImage = [CIImage imageWithCGImage:img.CGImage];
CIContext *context = [CIContext contextWithOptions:nil];
UIImage* bb = [UIImage fromFile:#"bollywoodBlend3.png"];
UIImage* bb2 = [bb resizedImage:img.size interpolationQuality:kCGInterpolationMedium];
CIFilter *filter = [CIFilter filterWithName:#"CIOverlayBlendMode"
keysAndValues: kCIInputImageKey, beginImage,
#"inputBackgroundImage", [CIImage imageWithCGImage:bb2.CGImage], nil];
CIImage *outputImage = filter.outputImage;
filter = [CIFilter filterWithName:#"CIColorControls"
keysAndValues: kCIInputImageKey, outputImage,
#"inputSaturation", [NSNumber numberWithFloat:1.8],
#"inputBrightness", [NSNumber numberWithFloat:0.1],
#"inputContrast", [NSNumber numberWithFloat:1.5],
nil];
outputImage = filter.outputImage;
CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]];
UIImage *newImg = [UIImage imageWithCGImage:cgimg];
CGImageRelease(cgimg);
return [newImg autorelease];
}
// filters resizeImage (same code used for resizedImage)
- (UIImage *)resizeImage:(UIImage*)img size:(CGSize)newSize
{
CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
CGImageRef imageRef = img.CGImage;
// Build a context that's the same dimensions as the new size
CGColorSpaceRef csr = CGImageGetColorSpace(imageRef);
CGContextRef bitmap = CGBitmapContextCreate(NULL,
newRect.size.width,
newRect.size.height,
CGImageGetBitsPerComponent(imageRef),
4*newRect.size.width,
csr,
CGImageGetBitmapInfo(imageRef));
// Draw into the context; this scales the image
CGContextDrawImage(bitmap, newRect, imageRef);
// CGImageSourceCreateThumbnailAtIndex
// Get the resized image from the context and a UIImage
CGImageRef newImageRef = CGBitmapContextCreateImage(bitmap);
UIImage *newImage = [UIImage imageWithCGImage:newImageRef scale:img.scale orientation:img.imageOrientation];
// Clean up
CGImageRelease(newImageRef);
CGContextRelease(bitmap);
return newImage;
}
- (UIImage *)resizedImage:(CGSize)newSize
transform:(CGAffineTransform)transform
drawTransposed:(BOOL)transpose
interpolationQuality:(CGInterpolationQuality)quality
{
CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
CGRect transposedRect = CGRectMake(0, 0, newRect.size.height, newRect.size.width);
CGImageRef imageRef = self.CGImage;
// Build a context that's the same dimensions as the new size
CGColorSpaceRef csr = CGImageGetColorSpace(imageRef);
CGContextRef bitmap = CGBitmapContextCreate(NULL,
newRect.size.width,
newRect.size.height,
CGImageGetBitsPerComponent(imageRef),
4*newRect.size.width,
csr,
CGImageGetBitmapInfo(imageRef));
// Rotate and/or flip the image if required by its orientation
CGContextConcatCTM(bitmap, transform);
// Set the quality level to use when rescaling
CGContextSetInterpolationQuality(bitmap, quality);
// Draw into the context; this scales the image
CGContextDrawImage(bitmap, transpose ? transposedRect : newRect, imageRef);
// CGImageSourceCreateThumbnailAtIndex
// Get the resized image from the context and a UIImage
CGImageRef newImageRef = CGBitmapContextCreateImage(bitmap);
UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
// Clean up
CGImageRelease(newImageRef);
CGContextRelease(bitmap);
return newImage;
}
// UIImage from file
+(UIImage*)fromFile:(NSString*)fname
{
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
return [UIImage imageWithContentsOfFile:[NSString stringWithFormat:#"%#/%#", bundlePath,fname]];
}
I've been trying to implement a UIMapView Icon like the one in this picture. Does anybody know how this app is creating that thumbnail?
Edit
Attempting to implement this with the following code:
CLLocationCoordinate2D restaurantLocation = CLLocationCoordinate2DMake(Latitude, Longitude);
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(restaurantLocation, 1000, 1000);
_mapView.region = region;
_mapView.hidden = NO;
_annotation = [[MKPointAnnotation alloc] init];
_annotation.coordinate = restaurantLocation;
//annotation.title = _restaurantInformation
[_mapView addAnnotation:_annotation];
UIGraphicsBeginImageContext(_mapView.frame.size);
[_mapView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *mapImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGSize newSize;
newSize.width = 50; // any width u want
newSize.height= 80; // any height u want
UIGraphicsBeginImageContext(newSize);
[mapImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
_mapThumbnail.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Annotation in Mapview with location should be in centre. Now
UIGraphicsBeginImageContext(mapView.frame.size);
[mapView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *mapImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
For creating thumbnail of mapImage resize according
CGSize newSize;
newSize.width = 50; // any width you want
newSize.height= 80; // any height you want
UIGraphicsBeginImageContext(newSize);
[mapImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* thumbnail = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Another Way is
You can try Google Static Maps API
Here's sample code
NSString *urlString = #"http://maps.googleapis.com/maps/api/staticmap?center=Berkeley,CA&zoom=14&size=200x200&sensor=false";
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
UIImage *thumbnail= [UIImage imageWithData:data];
[yourImageView setImage:thumbnail];
Through this you can get static image based on your coordinates.
This code for showing thumbnail of particular location and its working for me
NSString *staticMapUrl = [NSString stringWithFormat:#"http://maps.google.com/maps/api/staticmap?markers=color:red|%f,%f&%#&sensor=true",lat, log,#"zoom=10&size=114x116"];
NSURL *mapUrl = [NSURL URLWithString:[staticMapUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
UIImage *image = [UIImage imageWithData: [NSData dataWithContentsOfURL:mapUrl]];
[imgViewClue setImage:image];
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to release an object declared into a method and passed to another method?
Can you help me fix leaks in this code:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
UIImage *payload = [[UIImage alloc] initWithData:self.activeDownload];
UIImage *picture = [[UIImage alloc] init];
if (payload.size.width != kAppIconHeight && payload.size.height != kAppIconHeight)
{
CGSize itemSize = CGSizeMake(kAppIconHeight, kAppIconHeight);
UIGraphicsBeginImageContext(itemSize);
CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
[payload drawInRect:imageRect];
picture = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
else
{
picture = payload;
}
self.activeDownload = nil;
[payload release];
self.imageConnection = nil;
[delegate ThumbDidLoad:self.indexPathInTableView Image:[picture autorelease]];
}
Thx for helping,
Stephane
When you set picture = UIGraphicsGetImageFromCurrentImageContext() in your if statement or picture = payload in your else statement, you are loosing the pointer to the previously allocated UIImage you assigned in picture in the first lines, but you never released it.
You shouldn't alloc+init a new UIImage for picture, as you never use it and assign a new value to this variable later... but never used and released the previously allocated one.
UIImage *picture = [[UIImage alloc] init]; and picture = UIGraphicsGetImageFromCurrentImageContext();
You should not initialize picture at the beginning of the code. UIGraphicsGetImageFromCurrentImageContext returns a already initialized UIImage (autoreleased).
UIImage *payload = [[UIImage alloc] initWithData:self.activeDownload];, picture = payload;, [payload release];.
You should use [payload autorelease] instead, otherwise you're releasing the image without ever using it.
[delegate ThumbDidLoad:self.indexPathInTableView Image:[picture autorelease]];
You should remove [picture autorelease] and just use picture.
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
UIImage *payload = [[UIImage alloc] initWithData:self.activeDownload];
UIImage *picture;
if (payload.size.width != kAppIconHeight && payload.size.height != kAppIconHeight)
{
CGSize itemSize = CGSizeMake(kAppIconHeight, kAppIconHeight);
UIGraphicsBeginImageContext(itemSize);
CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
[payload drawInRect:imageRect];
picture = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
else
{
picture = payload;
}
[payload autorelease];
self.activeDownload = nil;
self.imageConnection = nil;
[delegate ThumbDidLoad:self.indexPathInTableView Image:picture];
}
in my application images are loaded from rss feed in table cell. they are of variant size how can i fix them to certain size. 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;
you can view my application screen shot click here
Thanks i will be waiting for your response....
I think I understand what your'e asking...
What you want to do is to resize UIImages.
UIImage* resizeImageToSize(UIImage* image, CGSize size)
{
UIGraphicsBeginImageContext(size);
CGContextRef ctx = UIGraphicsGetCurrentContext();
//Account for flipped coordspace
CGContextTranslateCTM(ctx, 0.0, size.height);
CGContextScaleCTM(ctx, 1.0, -1.0);
CGContextDrawImage(ctx,CGRectMake(0.0f, 0.0f, size.width, size.height), image.CGImage);
UIImage* scaled = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaled;
}