draw CGPaths to UIView then save view as Png - ios4

In the drawrect function of a UIView I use CGContext to draw some shapes. This Works fine, I can see my shapes.
Now I'm trying to save what has been drawn on the view as a png on disk. I've read various docs / articles but nothing gets saved. Im testing on the simulator for ios 4.3.
Edit 1
I changed my code and uncommented the context part. I can save the png but it is blank.
- (void)drawRect:(CGRect)rect
{
CGContextRef ctx= UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(ctx, 0, 0, 0, .5);
CGContextBeginPath(ctx);
CGContextAddPath(ctx, mutatablepath);
//CGContextStrokePath(ctx);
CGContextFillPath(ctx);
CFRelease(mutatablepath);
NSString *path0;
NSArray *paths0=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
path0=[[paths0 objectAtIndex:0]stringByAppendingPathComponent:#"images"];
NSError *error;
if (![[NSFileManager defaultManager]fileExistsAtPath:path0]) {
if(![[NSFileManager defaultManager]createDirectoryAtPath:path0 withIntermediateDirectories:NO attributes:nil error:&error])
{
NSLog(#"Create directory error %#",error);
}
}
UIGraphicsBeginImageContext(self.bounds.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *imagedata=UIImagePNGRepresentation(image);
NSString *namepath=[NSString stringWithFormat:#"%#.png",#"test"];
NSString *path;
NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
path=[[paths objectAtIndex:0]stringByAppendingPathComponent:#"images"];
NSString *savepath=[NSString stringWithFormat:#"%#/%#",path,namepath ];
// NSError
NSLog(#"%#",savepath);
[imagedata writeToFile:savepath atomically:YES];
}

You can do so by taking the image saving code out of your drawRect method, since the renderInContext method implicitly calls drawRect as necessary:
UIView *myView = [[MyViewClass alloc] initWithFrame:CGRectMake(/*...*/)];
UIGraphicsBeginImageContext(myView.bounds.size);
[myView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Source: http://pastie.org/244916

Related

How can I save a user selected image (Zbar Scanner) inside apps Documents folder

So I have 2 views, one of them is a UITableVew where a user can populate cells by adding them. The second view is the information when they add them (Name, date, company and a place to scan a barcode.). Well when they scan that image, they can see the image of what they scanned (Done with Zbar barcode scanner). So the main question is how can I exactly save different images in each different cell that the user adds?
Code:
Zbar:
- (IBAction)cameraButtonTapped:(id)sender
{
// Check for camera
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == YES) {
// Create image picker controller
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
// Set source to the camera
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
// Delegate is self
imagePicker.delegate = self;
// Show image picker
[self presentModalViewController:imagePicker animated:YES];
}
}
- (void) imagePickerController: (UIImagePickerController*)reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
// ADD: get the decode results
id<NSFastEnumeration> results =
[info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
// EXAMPLE: just grab the first barcode
break;
// EXAMPLE: do something useful with the barcode data
resultText.text = symbol.data;
// EXAMPLE: do something useful with the barcode image
resultImage.image =
[info objectForKey: UIImagePickerControllerOriginalImage];
// ADD: dismiss the controller (NB dismiss from the *reader*!)
[reader dismissModalViewControllerAnimated:YES];
}
-(UIView*)CommomOverlay{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,480)];
UIImageView *TopBar = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,58)];
[TopBar setImage:[UIImage imageNamed:#""]];
[view addSubview:TopBar];
UILabel *Toplabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 9, 300, 30)];
[Toplabel setFont:[UIFont fontWithName:#"Heiti TC light" size:22]];
[Toplabel setTextAlignment:UITextAlignmentCenter];
[Toplabel setBackgroundColor:[UIColor clearColor]];
[Toplabel setTextColor:[UIColor lightGrayColor]];
[Toplabel setNumberOfLines:1];
[Toplabel setText:#"Turn your device sideways to scan"];
[TopBar addSubview:Toplabel];
UIImageView *FrameImg = [[UIImageView alloc] initWithFrame:CGRectMake(40,50,240,370)];
[FrameImg setImage:[UIImage imageNamed:#"scanImage.png"]];
[view addSubview:FrameImg];
return view;
}
- (IBAction) scanButtonTapped
{
// ADD: present a barcode reader that scans from the camera feed
ZBarReaderViewController *reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
reader.supportedOrientationsMask = ZBarOrientationMaskAll;
ZBarImageScanner *scanner = reader.scanner;
// TODO: (optional) additional reader configuration here
// EXAMPLE: disable rarely used I2/5 to improve performance
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
// present and release the controller
reader.cameraOverlayView = [self CommomOverlay];
[self presentModalViewController: reader
animated: YES];
}
I did think using core data but i cant find a tutorial anywhere. Then I thought saving it in the apps Documents folder and i think that would be the bes way for me. I am new to this so descriptive code would help :)
Update:
- (IBAction)save:(id)sender {
NSManagedObjectContext *context = [self managedObjectContext];
UIImage *image = resultImage.image;
NSData *imageData = UIImagePNGRepresentation(image); //convert image into .png format.
NSFileManager *fileManager = [NSFileManager defaultManager];//create instance of NSFileManager
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it
NSString *documentsDirectory = [paths objectAtIndex:0]; //create NSString object, that holds our exact path to the documents directory
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"/%#KYRO Receipts Images/Barcode.png", resultImage]]; //add our image to the path
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil]; //finally save the path (image)
NSLog(#"image saved");
if (self.device) {
// Update existing device
[self.device setValue:self.nameOfItem.text forKey:#"name"];
[self.device setValue:self.dateOfPurchase.text forKey:#"date"];
[self.device setValue:self.companyOfItem.text forKey:#"company"];
} else {
//
NSManagedObject *newDevice = [NSEntityDescription insertNewObjectForEntityForName:#"Receipt" inManagedObjectContext:context];
[newDevice setValue:self.nameOfItem.text forKey:#"name"];
[newDevice setValue:self.dateOfPurchase.text forKey:#"date"];
[newDevice setValue:self.companyOfItem.text forKey:#"company"];
}
NSError *error = nil;
// Save the object to persistent store
if (![context save:&error]) {
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
[WTStatusBar setStatusText:#"Saving data..." animated:YES];
[self performSelector:#selector(setTextStatusProgress3) withObject:nil afterDelay:0.1];
[self.navigationController popViewControllerAnimated:YES];
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
If you're already using Core Data, then depending on the size of the images you could either convert them to NSData and save them directly within Core Data (if they're small) or you can save them within the documents directory and save the file name within Core Data.
Since a full Core Data tutorial is beyond the scope here, I'll just go over saving the image to the documents directory under a unique name. Note that some of the code below was adapted from "iOS Programming: The Big Nerd Ranch Guide".
// Method to save your image file. Returns the file name for you to save in Core Data or elsewhere.
- (NSString *)saveImage:(UIImage *)image {
// Generate a unique key to name the image file
CFUUIDRef newUniqueID = CFUUIDCreate(kCFAllocatorDefault);
CFStringRef newUniqueIDString = CFUUIDCreateString(kCFAllocatorDefault, newUniqueID);
NSString *imgkey = (__bridge NSString *)newUniqueIDString;
// Get a path for the image file in the documents directory
NSString *imagePath = [self imagePathForKey:imgkey];
// Convert the UIImage into NSData and save it to the documents directory
NSData *imageData = UIImageJPEGRepresentation(img, 0.5);
[imageData writeToFile:imagePath atomically:YES];
// Clean up
CFRelease(newUniqueIDString);
CFRelease(newUniqueID);
return imgkey;
}
// Method to provide the image path for saving/retrieving the image
- (NSString *)imagePathForKey:(NSString *)key {
NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [documentDirectories objectAtIndex:0];
return [documentDirectory stringByAppendingPathComponent:key];
}
The following method retrieves the image:
- (UIImage *)imageForKey:(NSString *)imgkey {
result = [UIImage imageWithContentsOfFile:[self imagePathForKey:imgkey thumbnail:FALSE]];
if (!result) {
// File not found - add code here as needed (to return default image or whatever)
}
return result;
}
Note that if you are planning to display multiple images in the table at the same time, you must be careful to ensure they are small, otherwise you may run into memory issues. In this case you would want to convert them into a thumbnail form for the table view, then display the full size image only in the detail view (how to generate a thumbnail would be a separate question).

loading images from documents directory into an array

I have some jpg images I am saving to the documents directory from camera shots. I want to find all the jpg images in the documents directory and load them into an array so they can be in a overflow view.
Here is my code to find and sort the jpg images in the documents directory.
NSString *extension = #"jpg";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSArray *contents = [fileManager contentsOfDirectoryAtPath:documentsDirectory error:nil];
NSMutableArray *jpegFiles = [NSMutableArray arrayWithCapacity: [contents count]];
NSString *filename;
for (filename in contents)
{
if ([[filename pathExtension] isEqualToString:extension])
{
[jpegFiles addObject:[UIImage imageNamed:[documentsDirectory stringByAppendingPathComponent:filename]]];
}
}
// Add the coverflow view
coverflow = [[TKCoverflowView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
coverflow.coverflowDelegate = self;
coverflow.dataSource = self;
[self.view addSubview:coverflow];
[coverflow setNumberOfCovers:6];
- (void) coverflowView:(TKCoverflowView*)coverflowView coverAtIndexWasBroughtToFront:(int)index{
NSLog(#"Front %d",index);
}
- (TKCoverflowCoverView*) coverflowView:(TKCoverflowView*)coverflowView coverAtIndex:(int)index{
TKCoverflowCoverView *cover = [coverflowView dequeueReusableCoverView];
if(cover == nil){
// Change the covers size here
cover = [[TKCoverflowCoverView alloc] initWithFrame:CGRectMake(0, 0, 280, 210)]; // 224
cover.baseline = 200;
}
cover.image = [covers objectAtIndex:index % [covers count]];
return cover;
}
I have tried everything I can think of and nothing works.
It has been suggested that I load each image by getting the path to the image from the array of pathnames, and use the method imageWithContentsOfFile to load the image.
I have looked this up and did searches for how to do this but with no luck. Could someone show me how to do this.
You should do it as below,
if ([[filename pathExtension] isEqualToString:extension])
{
[jpegFiles addObject:[UIImage imageWithContentsOfFile:[documentsDirectory stringByAppendingPathComponent:filename]]];
}

UITextView text does not get cleared

I have a small UIView that I hide/show in to show a message to the user. The message itself is in a UITextView that I add to the small UIView that gets shown.
The sliding-in and sliding-out works fine - but the prior messages are not cleared. I have spent enough time to fix the problem - but to no avail. Can someone lend me their eyes!!
Here is how the UITextField is created programatically:
#interface MessageVC : UIViewController {
UITextView *messageTV;
}
#property (nonatomic, retain) UITextView *messageTV;
- (id)init;
- (void)showMsg:(NSString *)title;
#end
and
- (id)init {
if (self = [super init]) {
self.view = [[[UIView alloc] initWithFrame:CGRectMake(0, 380, 320, 100)] autorelease];
[self.view setBackgroundColor:[UIColor blackColor]];
}
return self;
}
- (void)showMsg:(NSString *)title {
[self setMessageTV : [[UITextView alloc] initWithFrame:CGRectMake(5, 5, 315, 90 )]];
[[self messageTV] setBackgroundColor : [UIColor greenColor]];
[[self messageTV] setTextColor : [UIColor whiteColor]];
[[self messageTV] setText:#""]; <<<<<<<< - does not clear the text
[[self messageTV] setText : title];
[self.view addSubview : [self messageTV]];
[self.view setHidden:NO];
}
- (void) hideMessage {
[self.view setHidden:YES]
}
I'll go out on a limb and ask why you're using a UITextView. I honestly have never needed to use a UITextView. Try changing it to a UILabel and see if the problem is specific to the UITextView. If you absolutely need a UITextView, let me know in a comment, but I have a suspicion that a UILabel is what you're after.
It appears that you are adding it as a subview every time. So you're actually creating multiple UITextViews and adding them on top of each other. You would either need to removeFromSuperview or just set the text of the instance variable.
Take these two lines out of showMsg and put them in viewDidLoad:
[self setMessageTV : [[UITextView alloc] initWithFrame:CGRectMake(5, 5, 315, 90 )]];
[self.view addSubview : [self messageTV]];

How to save .jpg image as .png or .jpeg in iphone

I am saving images in my doc dir..I dont have the problem with .png or .jpeg images.I am able to display them properly in iphone.But coming to .jpg,i am not able to display.Please help me in this.THANKS IN ADVANCE
+(void)DownloadImage:(NSString*)ImagePath{
if ([ImagePath isEqualToString:#""]) {
return;
}
UIImage *dimage = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://1xyz/uploads/%#",ImagePath]]]];
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSLog(#"pathIMAGEPATHS:::::::%#",ImagePath);
NSLog(#"path:::::::%#",docDir);
NSArray *patharr=[ImagePath componentsSeparatedByString:#"."];
NSString* Ext=[NSString stringWithFormat: #"%#",[patharr objectAtIndex:1]];
NSString *FilePath = [NSString stringWithFormat: [NSString stringWithFormat:#"%#/%#",docDir,ImagePath]];
NSLog(#"%#/%#",docDir,ImagePath);
if([Ext isEqualToString:#"png"])
{
NSLog(#"saving png");
NSData *data1 = [NSData dataWithData:UIImagePNGRepresentation(dimage)];
[data1 writeToFile:FilePath atomically:YES];
}
else if([Ext isEqualToString:#"jpeg"])
{
NSLog(#"saving jpeg");
NSData *data2 = [NSData dataWithData:UIImageJPEGRepresentation(dimage, 1.0f)];//1.0f = 100% quality
[data2 writeToFile:FilePath atomically:YES];
}
else
{
NSData *data3 = [NSData dataWithData:UIImageJPEGRepresentation(dimage, 1.0f)];
[data3 writeToFile:FilePath atomically:YES];
}
NSLog(#"saving image done");
[dimage release];
}
You can use UIImagePNGRepresentation. First create an UIImage with your original JPG and them use this class method to save it as PNG.
UIImage *image = [UIImage imageNamed:#"yourImage.jpg"]
NSData *imageData = UIImagePNGRepresentation(image);
Once you have the data you can save to disk by calling writeToURL:.

why I have got such kind of BarButton one upon other?

Hi!I have used UIBarButton Image but i have got such kind of issue.i mean Image+button on backside.for that i have written code below.
UIBarButtonItem *btnMap = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"mapbutton.png"] style:UIBarButtonItemStylePlain target:self action:#selector(btnMapClicked:)];
self.navigationItem.rightBarButtonItem = btnMap;
[btnMap release];
Use initWithCustomView and set a UIButton as the customView instead:
UIButton *subBtn = [UIButton buttonWithType:UIButtonTypeCustom];
subBtn.frame = CGRectMake(0, 0, 50, 40); //adjust as needed
[subBtn setImage:[UIImage imageNamed:#"mapbutton.png"] forState:UIControlStateNormal];
[subBtn addTarget:self action:#selector(btnMapClicked:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *btnMap = [[UIBarButtonItem alloc] initWithCustomView:subBtn];
self.navigationItem.rightBarButtonItem = btnMap;
[btnMap release];
Note that the sender in btnMapClicked: will now be a UIButton instead of a UIBarButtonItem.

Resources