In my iPhone app, I want the user to be able to take a picture with the camera, then have that image appear in amongst some locally stored HTML in a UIWebView.
So I've got the UIImage object from the UIImagePickerController, now I need to find out how to save it to memory so I can reference it in the UIWebView.
Note that I don't just want the image on it's own in the UIWebView (I want to use the picture as a background-image in some HTML with other images layered on top). I'm also using other images and HTML that are stored in the app, that I'm referencing by setting the baseURL of the UIWebView to the bundle path, like:
NSURL *baseURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
[self.webView loadHTMLString:html baseURL:baseURL];
You definitely have the option of saving the file locally, getting it's absolute path and using that.
Another option I used for a hybrid app once is converting the UIImage to Base64 string and pass that through javascript to the webview to do whatever you want it to do.
To do that that after getting the UIImage encode it (there are various libraries out there to do this:
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
NSString *base64EncodedImage = [Base64 encode:UIImageJPEGRepresentation(image, 0.5)];
Then in your HTML you could have method that is given the base64 images and sets it to some IMG or background or whatever you need:
function cameraCallback(imageData) {
var image = document.getElementById('myImage');
image.src = "data:image/jpeg;base64," + imageData;
}
Or
<img src="data:image/gif;base64, [YOUR BASE64 STRING HERE]" alt="" width="80" height="15" />
Then in the HTML in the webview you would use
[mywebview stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:#"cameraCallback(%#)", base64EncodedImage]];
This is the way I ended up doing this. In the code that handles the image taken using the camera I actually save the file directly to disc:
// Get the image out of the camera
UIImage *image = (UIImage *)[info valueForKey:UIImagePickerControllerOriginalImage];
// Images from the camera are always in landscape, so rotate
UIImage *rotatedImage = scaleAndRotateImage(self.image);
// Save the image to the filesystem
NSData *imageData = UIImagePNGRepresentation(rotatedImage);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString* savePath = [documentsPath stringByAppendingPathComponent:#"CameraPhoto.png"];
BOOL result = [imageData writeToFile:savePath atomically:YES];
The function to rotate the image is copied straight from this blog, http://blog.logichigh.com/2008/06/05/uiimage-fix/.
Then when I want to display this image within the UIWebView, I just do a string replace to reference inject the path to the image. So in my HTML there's like <img src="{CameraPhotoUrl}" /> and then:
// Build the reference to the image we just saved
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *cameraImagePath = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:#"CameraPhoto.png?x=%#", [[NSDate date] description]]];
// Load the HTML into the webview
NSString *htmlFilePath = [[NSBundle mainBundle] pathForResource:#"MyHtmlFile" ofType:#"htm"];
NSString *html = [NSString stringWithContentsOfFile:htmlFilePath encoding:NSUTF8StringEncoding error:nil];
html = [html stringByReplacingOccurrencesOfString:#"{CameraPhotoUrl}" withString:cameraImagePath];
NSURL *baseURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
[self.webView loadHTMLString:html baseURL:baseURL];
Voila! Note that I'm appending a date-based query string parameter to the CameraPhoto.png filename simply to prevent caching.
Related
I want to save displayed UIImageview image in SQL database. I am capturing the image using the camera/albums/library which are displayed in UIImageview. I want to save this image in my SQL database using URL.
Also I need to display this image in another view.
How can I take a path(URL) of my imageview image? How can I store this path(URL) & also store & display into another view?
How to grab the UIImage and write to internal directory:
UIImageView *imageView = "[your image]";
// define your own path and storage for image
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = [paths objectAtIndex:0];
documentPath = [documentPath stringByAppendingPathComponent:#"test.jpg"];
NSData *imageData = UIImageJPEGRepresentation(imageView.image, 1.0);
[imageData writeToFile:documentPath atomically:YES];
How to get the NSURL/NSString for a file path in internal directory:
// specify fileURL as it is an internal file, don't use URLWithString:
NSURL *fileURL = [NSURL fileURLWithPath:documentDirectory];
// store as a string in database
NSString *fileURLString = fileURL.path;
Please take note that the NSURL for local file is different with normal NSURL.
// for normal URL
NSURL *webURL = [NSURL URLWithString:"http://www.google.com/"];
[webURL absoluteString]; // -> http://www.google.com/
// for local file path URL
NSURL *localURL = [NSURL fileURLWithPath:"/User/path/samplefile.ext"];
[localURL absoluteString]; // -> file://User/path/samplefile.ext
[localURL path]; // -> /User/path/samplefile.ext
just save name of your image in database and store image in phone memory...it will be easy or this way try this line
UIImage *img = [UIImage imageWithContentsOfFile:(the file path)];
UIImageView *imgView = [[UIImageView alloc] initWithImage:img];
I have a button called "Download page" at the bottom of my detailView of SplitView app in iPad. I want to download the corresponding html page on the click of the aforementioned button i.e. I need to add the functionality of the "Ctrl+S" for that button so that I could download and save the page. How can I do that ?
You should do this:
//Download data from URL
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"yourstringURL"]];
//use this data to write to any path as documentdirectory path + filename.html
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//create file path
NSString *htmlFilePath = [documentsDirectory stringByAppendingPathComponent:#"file.html"];
//write at file path
BOOL isSucess = [data writeToFile:htmlFilePath atomically:YES];
if (isSucess)
NSLog(#"written");
else
NSLog(#"not written");
You can same htmlFilePath to retrieve html file from document directory
You can get all the html content inside an NSString and then save it, like so
NSString *allHtml = [webView stringByEvaluatingJavaScriptFromString:#"document.documentElement.outerHTML"];
[allHtml writeToFile:#"YourFilePath" atomically:YES encoding:NSUTF8StringEncoding error:NULL];
This will save all the HTML to the path you define
I need to Read a Image from the specific URL .
It works fine with WWW . but it returns a nil when the URL pointing the Local Folder .
// Works
NSString *sampleData = #"http://blogs-images.forbes.com/ericsavitz/files/2011/05/apple-logo2.jpg";
// Returns nil
NSString *sampleData = #"USER/user2/...";
Note :
I am changing the NSString to NSURL and creating the UIImage .
NSURL *url = [NSURL URLWithString: data];
UIImage *image = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];
You are supplying a relative pathname for the file URL. That relative pathname is interpreted relative to the current working directory of the running application, which isn't guaranteed to be anything in particular, and so is almost certainly not what you want.
You can either supply an absolute path - one that starts with '/' - or set your app's current working directory to something explicit, like your user's Documents folder.
you probably should have a look into the NSBundle Class.
Methods like
- (NSURL *)URLForResource:(NSString *)name withExtension:(NSString *)extension subdirectory:(NSString *)subpath
or
- (NSString *)pathForResource:(NSString *)name ofType:(NSString *)extension
is probably what you want
First of all, you can NOT read file from such path you given: "USER/user2/...", the file must in your App bundle or in your App's sandbox.
Second, check your path string if there was some texts need to be encoded in URL. Try:
NSURL *url = [NSURL URLWithString:[data stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
Also, if the url is not nil, you should also check if your [NSData dataWithContentsOfURL:url]; is returning nil. If so, it means your URL is not correct so the method cannot find your file.
P.S., You are mistyping your image create code, you should call alloc before imageWithData:.
You should do something like to get the local url :
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *pngFilePath = [NSString stringWithFormat:#"%#/%#", docDir, nameOfFile];
and finaly, load your image :
UIImage *image = [UIImage imageWithContentsOfFile:pngFilePath];
Try these instead
NSString *path = #"USER/user2/.../xxx.xxx";
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isFileExist = [fileManager fileExistsAtPath:path];
UIImage *image;
if (isFileExist) {
image = [[UIImage alloc] initWithContentsOfFile:path];
}
else {
// do something.<br>
}
I have downloaded a gif image into an NSData object (I've checked the contents of the NSData object and it's definitely populated). Now I want to load that image into my UIWebView. I've tried the following:
[webView loadData:imageData MIMEType:#"image/gif" textEncodingName:nil baseURL:nil];
but I get a blank UIWebView. Loading the image from the same URL directly works fine:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:imageUrl]];
[imageView loadRequest:request];
Do I need to set the textEncodingName to something, or am I doing something else wrong?
I want to load the image manually so I can report progress to the user, but it's an animated gif, so when it's done I want to show it in a UIWebView.
Edit: Perhaps I need to wrap my image in HTML somehow? Is there a way to do this without having to save it to disk?
I tested the code with PNG ("image/png"), JPG ("image/jpeg") and GIF ("image/gif"), and it works as expected:
[webView loadData:imageData MIMEType:imageMIMEType textEncodingName:nil baseURL:nil];
Now, what's wrong with your app?
the imageData is not a well-formed image data. Try opening the file with a web browser or an image editor to check it.
the MIME type is incorrect. Look at the first bytes of the data to determine the actual file type.
webView is not connected in IB, is nil, is hidden, is covered with another view, is off screen, has a CGRectZero frame, etc.
I did not really try to load image to UIWebView but a google search gives me. I think your image string must have a good path and looks like a URL
NSString *imagePath = [[NSBundle mainBundle] resourcePath];
imagePath = [imagePath stringByReplacingOccurrencesOfString:#"/" withString:#"//"];
imagePath = [imagePath stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
NSString *HTMLData = #"
<h1>Hello this is a test</h1>
<img src="sample.jpg" alt="" width="100" height="100" />";
[webView loadHTMLString:HTMLData baseURL:[NSURL URLWithString: [NSString stringWithFormat:#"file:/%#//",imagePath]]];
You can see more details here : Loading local files to UIWebView
UIImage *screenshot= [UIImage imageAtPath:
[[NSBundle mainBundle] pathForResource:#"MfLogo_aboutus" ofType:#"png"]];
NSData *myData = UIImagePNGRepresentation(screenshot);
[vc addAttachmentData:myData mimeType:#"image/png" fileName:#"logo.png"];
You can load urlImage into webview which is not saved locally as shown below code
NSString *str = #"";
str = [str stringByAppendingString:#"http://t3.gstatic.com/images?q=tbn:7agzdcFyZ715EM:http://files.walerian.info/Funny/Animals/funny-pictures-firefox-file-transfer-is-complete.jpg"];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:str]];
[webView loadData:data MIMEType:#"application/jpg" textEncodingName:#"UTF-8" baseURL:[NSURL URLWithString:#"http://google.com"]];
I had the same problem and I found somewhere else that you have to provide a value in the baseURL parameter. I also had encoding set:
textEncodingName:#"UTF-8" baseURL:[NSURL URLWithString:#"http://localhost/"]];
When I had nil in the baseURL parameter it would not load. By putting something that's basically irrelevant in there the MS docs all worked.
You may want to try assigning a delegate to the webview and implementing the method:
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
To see more specifically what error you're getting. If it doesn't get called, implement the method:
- (void)webViewDidFinishLoad:(UIWebView *)webView
as well, just to make sure something is happening, otherwise there might be an issue with UIWebView (assuming you haven't returned NO from webView:shouldStartLoadWithRequest:navigationType:)
To expand on Ed Marty's comment:
The HTML command to put in a base 64 image is:
<img src="data:image/png;base64,##PUT THE BASE64 DATA HERE###" />
I have a category (I'm not sure where it came from, not me...) available on my website that converts NSData to it's Base64 string representation.
Header
Implementation
Easy enough to do, assuming 'imageData' is the NSData variable containing your image:
[imageData base64Encoding] into the above string.
try this code
// 1) Get: Get string from “outline.plist” in the “DrillDownSave”-codesample.
savedUrlString = [item objectForKey: #"itemUrl"];
// 2) Set: The url in string-format, excluding the html-appendix.
NSString *tempUrlString = savedUrlString;
// 3) Set: Format a url-string correctly. The html-file is located locally.
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:tempUrlString ofType:#”html”];
// 4) Set: Set an “NSData”-object of the url-sting.
NSData *htmlData = [NSData dataWithContentsOfFile:htmlFile];
// 5. Gets the path to the main bundle root folder
NSString *imagePath = [[NSBundle mainBundle] resourcePath];
// 6. Need to be double-slashes to work correctly with UIWebView, so change all “/” to “//”
imagePath = [imagePath stringByReplacingOccurrencesOfString:#"/" withString:#"//"];
// 7. Also need to replace all spaces with “%20″
imagePath = [imagePath stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
// Load: Loads the local html-page.
[webView loadData:htmlData MIMEType:#"text/html" textEncodingName:#"UTF-8" baseURL:[NSURL URLWithString:[NSString stringWithFormat:#"file:/%#//",imagePath]]];
Here's an alternative method:
Save the image you downloaded into your documents folder.
Then get that image's url. Then write a simple html file
using that image url in the IMG SRC tag.
NSLog(#"url=%#", fileURL); // fileURL is the image url in doc folder of your app
//get the documents directory:
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//make a file name to write the data to using the documents directory:
NSString *fileName = [NSString stringWithFormat:#"%#/toOpen.html",
documentsDirectory];
//create simple html file and format the url into the IMG SRC tag
NSString *content = [NSString stringWithFormat:#"<html><body><img src=%#></body></html>",fileURL];
//save content to the documents directory
[content writeToFile:fileName
atomically:NO
encoding:NSStringEncodingConversionAllowLossy
error:nil]; // now we have a HTML file in our doc
// open the HTML file we wrote in the webview
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"life.html"];
NSURL *url = [NSURL fileURLWithPath:filePath];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[yourWebView loadRequest:request];
NSString *pathForFile = [[NSBundle mainBundle] pathForResource: #"fireballscopy" ofType: #"gif"];
NSData *dataOfGif = [NSData dataWithContentsOfFile: pathForFile];
[Web_View loadData:dataOfGif MIMEType:#"image/gif" textEncodingName:nil baseURL:nil];
Here is what I'm doing, when I create an image with the path in the bundle:
UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"image" ofType:#"jpg"]];
What I want to do is trying to find the path for my image but without using the extension, without using 'ofType' (because the name of my image and her extension is store in my database) something like that:
UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"image.jpg"]];
But I don't know how to do it.
Best regards,
Why don't you split the string that you get from the DB?
NSString* fullFileName = #"image.jpg";
NSString* fileName = [[fullFileName lastPathComponent] stringByDeletingPathExtension];
NSString* extension = [fullFileName pathExtension];
Now you can simply use:
[[NSBundle mainBundle] pathForResource:fileName ofType:extension]];
You can easily use the NSBundle method without passing the extension, just pass nil for extension.
[[NSBundle mainBundle] pathForResource:#"image.jpg" ofType:nil];
- (NSData *)applicationDataFromFile:(NSString *)fileName {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:fileName];
NSData *myData = [[[NSData alloc] initWithContentsOfFile:appFile] autorelease];
return myData;
}
taken from http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/FilesandNetworking/FilesandNetworking.html#//apple_ref/doc/uid/TP40007072-CH21-SW21
Could be easily adapted if you wanted it to return a UIImage instead of an NSData.
Also, you don't say if you are saving the images to the documents directory, or adding them to your app bundle before compiling. because if it's the latter, you can use [UIImage imageNamed:(NSString *)filename] to get the image. It expects an extension as part of the file-name.
The easiest way is to store the name and file type in your database separately, and retrieve them using the first method.I'm not sure that you can be successful in implementing the latter one.
I found that with an extension of ".jpg" it was necessary to use ofType for the extension for the app to work on an iPod Touch, whereas with an extension of ".png" I could just put "image.png" in pathForResource and say ofType:nil. But all versions worked on the simulator.
The app bundle contains the image file, and I am using:
[[NSBundle mainBundle] pathForResource:#"Auto" ofType:#"jpg"]
to get a path.