the screen image link,the savePic image link,You can find the different between screenImg and savePic.
I set the backgroundImageView a very small png. and i want save the backgroundimageview to a Picture。
In the iPhone Simulator Screen, the edge of image is normal, but the edge of savePic is not clear. Anybody can tell me how to save a high definition picture.
- (void)viewDidLoad
{
[super viewDidLoad];
//_backImgView 320*480
self.backImgView.image = [UIImage imageNamed:#"Purple.png"];
[self performSelector:#selector(savePic) withObject:nil afterDelay:0.1];
}
- (void)savePic
{
BOOL isDir;
NSString *dirPath = [NSHomeDirectory() stringByAppendingPathComponent:#"/Documents/Pic"];
NSFileManager *fm = [NSFileManager defaultManager];
if(![fm fileExistsAtPath:dirPath isDirectory:&isDir]){
BOOL bo = [fm createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:nil];
if(!bo){
NSLog(#"-->Create CardSlide Dir Fail!!!");
return;
}
}
UIGraphicsBeginImageContext(_backImgView.bounds.size);
//UIGraphicsBeginImageContextWithOptions(_backImgView.bounds.size, _backImgView.opaque, 2.0);
CGContextSetAllowsAntialiasing(UIGraphicsGetCurrentContext(), YES);
[_backImgView drawRect:_backImgView.bounds];
//[_backImgView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *bgImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSString *path = [NSString stringWithFormat:#"save_%#.jpg", #"demo"];
NSString *jpgPath = [dirPath stringByAppendingPathComponent:path];
BOOL isSucc = [UIImageJPEGRepresentation(bgImg, 1.0) writeToFile:jpgPath atomically:YES];
NSLog(#"%# write photo %#!", jpgPath, isSucc?#"SUCC":#"FAIL");
}
Using a small image, is impossible to scale it the correct way to a bigger image, you will always go through blurry, noisy images BUT if you image could have stretchable repetitive parts, you can stretch the interior of the image without creating a new one. There are two API in UIImage called:
– resizableImageWithCapInsets: (Only ios5)
– stretchableImageWithLeftCapWidth:topCapHeight: (Deprecated in iOS 5.0)
If you find the correct inset you can avoid to create a new image, basically is the same system used to create the bubble in message application. The balloon is really small but it has a stretchable area that maintain the aspect ratio.
Since the image is really simple you could also think to draw it using Quartz functions creating a rect path, paths are "almost" res independent just need to scale them the correct size.
Related
I'm developing an application where I need to capture multiple images and store them in a folder. The application crashes when the images exceed.Also while taking images IPhone slows down a bit. Please anyone can help me with this.
code fo capturing image
UIImagePickerController *picker=[[UIImagePickerController alloc]init];
picker.delegate=self;
picker.sourceType=UIImagePickerControllerSourceTypeCamera;
[self.navigationController presentModalViewController:picker animated:YES];
Code for adding images into file
NSString *pngImagePath =
[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES) lastObject]
stringByAppendingPathComponent:[NSString
stringWithFormat:#"%#.png",imageName]];
[dataImage writeToFile:pngImagePath atomically:YES];
Here, take this code as example to resize images before you show them on the screen:
+ (UIImage*)imageWithImage:(UIImage*)image
scaledToSize:(CGSize)newSize;
{
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Notice that you should also reduce the images before you save them to the disk:
UIImage *image = YOUR_IMAGE;
NSData *imageData = UIImageJPEGRepresentation(image, .06); // Here's the level of compression
Just try with #autoreleasepool once, may be its due to some memory leaks. #autoreleasepool with maintain upto some extent..
#autoreleasepool
{
// any allocation for UIImage if u have just bring inside the autoreleasepool
NSString *pngImagePath =
[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES) lastObject]
stringByAppendingPathComponent:[NSString
stringWithFormat:#"%#.png",imageName]];
[dataImage writeToFile:pngImagePath atomically:YES];
}
I am new to this and have searched a lot this week. I am trying to set a background image from a file I have downloaded from a url. I need to save the image for later. Specially if I am not connected to the internet I can still show this image.
I have validated by printing out the contents of the directory that the file exists. This is one of many code that I have tried to make the image appear in the background.
nNSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *documentPath = [docDir stringByAppendingFormat:#"/mainback.png"];
// If you go to the folder below, you will find those pictures
NSLog(#"%#",documentPath);
if ([[NSFileManager defaultManager]fileExistsAtPath:documentPath]) {
NSData *data = [NSData dataWithContentsOfFile:documentPath];
UIImage *image = [[UIImage alloc] initWithData:data];
NSLog(#"WHAT - %f,%f",image.size.width,image.size.height);
UIColor *background = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:documentPath]];
self.view.backgroundColor = background;
[background release];
}
The code finds the image in the directory but I cannot set the image to the background. Please help.
Thanks
Use a UIImageView (Apple documentation linked) instead of doing what you are trying to do with UIColor.
It'll be a lot more straightforward and less problematic.
There seems to be a scatter of info on this topic, but it seems rather a muddle, so I hoe you don't mind me asking.
I have a UIImagePickerController working, letting me either take a photo or pick on from the library and then set a UIImageView of my choice to show that image taken/selected.
However, how can I firstly save the image, then load it back in when the application is reopened? Also, I will be saving multiple images so they need to be uniquely identified.
Any help will be massively appreciated, thanks.
I don't know of a way to get the Photo from the Photo Album a Second time. There does not seem to be a way to retrieve it again. We do a few things to save the Image internally.
We either convert the Image to NSData and save it in CoreData, or we save it off to our sandbox.
here is a snip of code that we use, this is doing one of a few things, I'm getting the Image from a ScreenShot, though its the same once you have the UIImage.
// go get our screenshot
UIImage* screenShot = [self createScreenShotThumbnailWithWidth:200];
// Save screen shot as a png in the documents directory with the UUID of the IoCDScreen
// Saving to Sandbox
[self saveImage:screenShot withName:currentScreen.itemUUID];
// save image to Photo Album - though you can't get a ref back to it
UIImageWriteToSavedPhotosAlbum(screenShot, self, nil, nil);
//convert our screen shot PNG to NSData and store it in a CoreData Managed Object
currentScreen.screenImageDevelopment = [NSData dataWithData: UIImagePNGRepresentation( screenShot )];
Helper Functions used above
//--------------------------------------------------------------------------------------------------------
// saveImage:withName:
// Description: Save the Image with the name to the Documents folder
//
//--------------------------------------------------------------------------------------------------------
- (void)saveImage:(UIImage *)image withName:(NSString *)name {
//grab the data from our image
NSData *data = UIImageJPEGRepresentation(image, 1.0);
//get a path to the documents Directory
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// Add out name to the end of the path with .PNG
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.png", name]];
//Save the file, over write existing if exists.
[fileManager createFileAtPath:fullPath contents:data attributes:nil];
}
//--------------------------------------------------------------------------------------------------------
// createScreenShotThumbnailWithWidth
// Description: Grab a screen shot and then scale it to the width supplied
//
//--------------------------------------------------------------------------------------------------------
-(UIImage *) createScreenShotThumbnailWithWidth:(CGFloat)width{
// Size of our View
CGSize size = self.view.bounds.size;
//First Grab our Screen Shot at Full Resolution
UIGraphicsBeginImageContext(size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//Calculate the scal ratio of the image with the width supplied.
CGFloat ratio = 0;
if (size.width > size.height) {
ratio = width / size.width;
} else {
ratio = width / size.height;
}
//Setup our rect to draw the Screen shot into
CGRect rect = CGRectMake(0.0, 0.0, ratio * size.width, ratio * size.height);
//Scale the screenshot and save it back into itself
UIGraphicsBeginImageContext(rect.size);
[screenShot drawInRect:rect];
screenShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//Send back our screen shot
return screenShot;
}
I'm using a UITableView to show 2 to 3 images as thumbnail in each table view cell. The images which I'm showing it in the tableview are huge in size. If I'm using those images directly without any size reduction then the tableview may lose some images if I move back and forth between TableView and other view controllers.
So, I thought of size reduction code which reduces the size of the images. The code given below works great and the previous issue was fixed. But the tableview looses its smooth scrolling because the size reduction code uses a lot of memory. Every time when a new tableview cell is shown, it processes (reduces the size) the images in the particular tableview cell.
There may be a simple solution for this. Thanks in Advance.
//Size Reduction Code
CGSize newSize=CGSizeMake(_new_width, _new_height);
UIGraphicsBeginImageContext( newSize );
[sd._image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
scene_image_preview.image =newImage;
On top of reducing the image you can store the resulting newImage as a file in the documents folder of your app.
NSData *imageData = UIImagePNGRepresentation([UIImage imageWithCGImage:newImage]);
CGImageRelease(newImage);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [NSString stringWithFormat:#"%#/%#%d_%d.png",documentsDirectory, prefix, x, y];
[imageData writeToFile:path atomically:NO];
Depending on how many images you have, you can just keep all the reduced-size images in an NSMutableDictionary that's a property of your class.
In other words:
In your header
#property (nonatomic, retain) NSMutableDictionary *sizedImages;
Then in your cellForRowAtIndexPath: code
UIImage *sizedImage = [sizedImages objectForKey:[NSNumber numberWithInt:indexPath.row]];
//Or you could use the filename as the key
if (!sizedImage) {
sizedImage = [self sizeImage];(your sizing method)
[sizedImages setObject:sizedImage forKey:[NSNumber numberWithInt:indexPath.row]];
}
A few possible options
Perform the resizing in the background so it doesn't hold up the main thread.
Cache the resized image after doing it so there is only a delay the first time (this could be used in conjunction with doing it in the background so there is no delay on the scrolling)
Are you downloading the images? If so, download a thumbnail first and display that. Then if the image is selected, display the thumbnail scaled up to full screen which will look blocky, but then download the full-size image in the background and display that when it has loaded.
If you aren't downloading the images, but they are included in the app, just include thumbnails as well and display them instead
drawing images usually takes time.i think you can try to place the images in imageView by giving the frame sizes as desired.i doesn't make difference in look of the images.
add the imageviews to the cell and add the images to the imageView
These two links are very useful
http://www.fieryrobot.com/blog/2008/10/01/glassy-scrolling-with-uitableview/
and his follow up post
http://www.fieryrobot.com/blog/2008/10/08/more-glassy-scrolling-with-uitableview/
The first link is a few best practices. The second link will eb more useful to you; render your whole table view cell to an image and use that instead - this can be cached to disk to free memory & can be used between runs of the app.
- (void)saveImage:(UIImage *)image withName:(NSString *)name {
[myArray addObject:name];
//save image
NSData *data = UIImageJPEGRepresentation(image, 1.0);
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:name];
[fileManager createFileAtPath:fullPath contents:data attributes:nil];
}
- (UIImage *)loadImage:(NSString *)name {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:name];
UIImage *res = [UIImage imageWithContentsOfFile:fullPath];
return res;
}
Finally, I got a solution to load number of large sized images simultaneously. First, I reduced the size of the image using the size reduction code above and I saved those sized images to documents directory for the first time and then I loaded the saved images from the documents directory using these saveImage and loadImage functions.
Thanks for all the comments and suggestions to solve this.
I am attempting to save and load a UIImage to and from the iPhone documents directory after the image is picked from the iPhone Photo Library. It is able to do so, but for some reason, when I load the image, it rotates it 90 degrees counterclockwise. Here is my saveImage and loadImage methods:
Save Image:
- (void)saveImage: (UIImage*)image{
if (image != nil)
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* path = [documentsDirectory stringByAppendingPathComponent:
[NSString stringWithString: #"lePhoto.png"] ];
//NSData* data = UIImagePNGRepresentation(image);
//[data writeToFile:path atomically:YES];
[UIImagePNGRepresentation(image) writeToFile:path atomically:YES];
}
}
Load Image:
- (NSData*)loadImage{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* path = [documentsDirectory stringByAppendingPathComponent:
[NSString stringWithString: #"lePhoto.png"] ];
NSData *data = [[NSData alloc] initWithContentsOfFile:path];
//UIImage *image = [[UIImage alloc] initWithData:data]; //my second try
//UIImage* image = [UIImage imageWithContentsOfFile:path]; //first try
//return image;
return data;
[data release];
}
And I am now loading the image like this, to see if it would, for some crazy reason, solve my problem (it didn't, obviously):
UIImage* theImage = [[UIImage alloc] initWithData:[self loadImage]];
I have done some testing where I have two UIImageViews side-by-side, one on the left that doesn't save and load the image before display (it just straight-up shows the image once a photo is picked from the ImagePicker), and one on the right that displays AFTER the save load occurs. The one on the right is the only one rotating 90 degrees CCW; the non Save/Load picture is displaying correctly. This only occurs on the actual iPhone. The simulator shows both images correctly. I have spent many, many hours attempting to figure it out, but to no avail. Any ideas as to what could be causing this?
EDIT: It should also be known that the image always says it's oriented up, even when it obviously isn't! It only rotates after ALL of the code has been run. I've tried doing a force redraw in between my code to see if that changes things, but it doesn't (though it is possible I'm even doing that wrong. Who knows, anymore).
Also, it will not autorotate photos that have been screenshot from the iPhone. Only photos that have been taken by the camera. [I haven't tried downloaded photos.] It's the weirdest thing...
And if you're wondering exactly how I'm pulling my picture, here's the method that will at least shed light on what I'm doing (it's not every method needed to do this function, obviously, but it gives insight on how I've written my code):
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
theimageView.image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
[self saveImage:[info objectForKey:#"UIImagePickerControllerOriginalImage"]];
[picker dismissModalViewControllerAnimated:YES];
}
Any advice is greatly appreciated. And I do know this much: if there's a way to do something crazy to get some stupid, never-before-heard-of problem, chances are, I'll find it, apparently :P
Ok. I figured it out. Apparently when you save things with PNG representation, and not JPEG representation, the image orientation information is not saved with it. Because of this, every image loaded will default to showing orientation up. So, the easiest way is to do this:
NSData* data = UIImageJPEGRepresentation(image,0.0);
[data writeToFile:path atomically:YES];
instead of this:
[UIImagePNGRepresentation(image) writeToFile:path atomically:YES];
And, of course, changing all the picture names from .png to .jpg. The 0.0 part of the code above is to control Alpha levels, which is required of jpegs. Hope this helps people in the future!
I assume you're using the Assets Library Framework to get the image. If so, you'll want to get the orientation of the image in your results block, and manipulate the UIImage to adjust. I have something like the following:
ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset)
{
ALAssetRepresentation* rep = [asset defaultRepresentation];
_orientation = rep.orientation;
...
}
Aside: What a great type name, huh? Holy moly, does Objective-C need namespaces!
Thanks so much...
This code has worked and saved several hours of work for me.
NSData* data = UIImageJPEGRepresentation(image,0.0);
[data writeToFile:path atomically:YES];
in the place of
[UIImagePNGRepresentation(image) writeToFile:path atomically:YES];