iPhone/iPad Base64->NSData->PDF how to? - iphone

Obj-C or Monotouch.Net C# answers are fine.
I have a Base64 string that is a PDF document received over a web service. I can get the NSData.
How do I take the NSData and save it as a PDF?
-- I get the NSData this way --
byte[] encodedDataAsBytes = System.Convert.FromBase64String (myBase64String);
string decoded = System.Text.Encoding.Unicode.GetString (encodedDataAsBytes);
NSData data = NSData.FromString (decoded, NSStringEncoding.ASCIIStringEncoding);

The simplest way to save it is probably to use NSData's writeToFile:options:error: method.

I found that using the .NET framework works better than trying to use the iOS framework for this problem. This will take any file and convert it to it's original then save it to the iPhone/iPad device. "path" is just a folder on the dev ice.
using (var f = System.IO.File.Create (path))
{
byte[] encodedDataAsBytes = System.Convert.FromBase64String (Base64PDFString);
f.Write (encodedDataAsBytes, 0, encodedDataAsBytes.Length);
}

I'm working on a project where I recently had to accomplish the same thing you are describing. I get base64 encoded PDF files as strings from a .NET web service which need to be decoded to their original and saved as PDF files in the applications documents directory.
My solution was:
Use ASIHTTPRequest to communicate with the web service.
I then use TBXML to parse incoming xml and get the base64 as an NSString.
To decode the string I use a method from QSUtilities library called decodeBase64WithString.
Finally I save the result with NSData's writeToFile.
I have tested and successfully used this method with PDF files that are up to 25mb. I also had a couple of test runs with a 48mb file but that file made the decodeBase64WithString method take up too much memory and my app crashed. Haven't found a solution to this yet..
If you are working with multiple large files be sure to free up your memory once in a while. I got all my files in one loop in which I had to use my own nsautorelease pool and drain it at the end of the loop to free up any autoreleased objects.

Related

Perl Image::Magick get in-memory contents

I'm using Image::Magick to modify my images. I am then using an HTTP::Request to send the image content to an API.
HTTP::Request has a content method which allows you to set the content for the request, but obviously this requires that you have the content in memory.
I know that I can read the content of the image into a variable by opening a file and reading it. However, since Image::Magick already has the content of the image in memory, is there any way that I can get it via my Image::Magick object? Thanks!
Image::Magick keeps the image in a custom format in memory to make it more simple and efficient to manipulate. It has to compress the data to JPEG, PNG, or whatever format you request before it is written to a file, so you cannot just access the image in memory as it stands.
However, the module's ImageToBlob method will provide an in-memory copy of the data it would have written to disk, to save you writing it out and reading it back again.
Note that it returns a list of images to allow for an object that contains more than one frame, so if you have only a single frame you must write
my #blobs = $image->ImageToBlob;
$request->content($blobs[0]);
or
my ($blob) = $image->ImageToBlob;
$request->content($blob);

JPEG encoder super slow, how to Optimize it?

I'm building an App with actionscript 3.0 in my Flash builder. This is a followup question this question.
I need to upload the bytearray to my server, but the function i use to convert the bitmapdata to a ByteArray is super slow, so slow it freezes up my mobile device. My code is as follows:
var jpgenc:JPEGEncoder = new JPEGEncoder(50);
trace('encode');
//encode the bitmapdata object and keep the encoded ByteArray
var imgByteArray:ByteArray = jpgenc.encode(bitmap);
temp2 = File.applicationStorageDirectory.resolvePath("snapshot.jpg");
var fs:FileStream = new FileStream();
trace('fs');
try{
//open file in write mode
fs.open(temp2,FileMode.WRITE);
//write bytes from the byte array
fs.writeBytes(imgByteArray);
//close the file
fs.close();
}catch(e:Error){
Is there a different way to convert it to a byteArray? Is there a better way?
Try to use blooddy library: http://www.blooddy.by . But i didn't test it on mobile devices. Comment if you will have success.
Use BitmapData.encode(), it's faster by orders of magnitude on mobile http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html#encode%28%29
You should try to find a JPEG encoder that is capable of encoding asynchronously. That way the app can still be used while the image is being compressed. I haven't tried any of the libraries, but this one looks promising:
http://segfaultlabs.com/devlogs/alchemy-asynchronous-jpeg-encoding-2
It uses Alchemy, which should make it faster than the JPEGEncoder from as3corelib (which I guess is the one you're using at the moment.)
A native JPEG encoder is ideal, asynchronous would be good, but possibly still slow (just not blocking). Another option:
var pixels:ByteArray = bitmapData.getPixels(bitmapData.rect);
pixels.compress();
I'm not sure of native performance, and performance definitely depends on what kind of images you have.
The answer from Ilya was what did it for me. I downloaded the library and there is an example of how to use it inside. I have been working on getting the CameraUI in flashbuilder to take a picture, encode / compress it, then send it over via a web service to my server (the data was sent as a compressed byte array). I did this:
by.blooddy.crypto.image.JPEGEncoder.encode( bmp, 30 );
Where bmp is my bitmap data. The encode took under 3 seconds and was easily able to fit into my flow of control synchronously. I tried async methods but they ultimately took a really long time and were difficult to track for things like when a user moved from cell service to wifi or from tower to tower while an upload was going on.
Comment here if you need more details.

iPhone how to send a large image along with a JSON file? Should I embed it within the JSON or send separately?

I'm trying to create a way to save the interface of my app in a JSON file. While static elements I can define by their frames and/or center points, the interface does include a single image selected from the photo library. Because some iPhones have 8MP cameras, I can anticipate that some images would be very large.
I would like to be able to save this interface and send it over by email, so another app user can re-open the file and see the same interface with the image included.
Currently I'm using JSONKit to save my data into a JSON object. This means that the email will contain a single JSON file containing both the layout parameters and the image. I've never worked with such large JSON files, so the question is - will having several megs of image data within JSON present parsing issues? Or should I select some other file container that would have : first part JSON file, second part raw image data and then separate that file into a JSON string and a raw data string?
This is what I'm using currently to get a JSON file. After adding NSData to JSON, the convert to json method returns nil
NSString* currentURL = webView.request.mainDocumentURL.absoluteString;
[dictionary setValue:currentURL forKey:#"webViewAddress"];
//this call correctly returns the json string
NSLog(#"%#", [dictionary JSONString]);
NSLog(#"+++++++++++++++++++++++++++++++++++++");
NSData* imageData = UIImagePNGRepresentation(arOverlayView.image);
//after this call, the json returns nil
[dictionary setValue:imageData forKey:kimageData];
NSLog(#"%#", [dictionary JSONString]);
If you are using email as a transport mechanism, your binary data will have to end up as something like Base64 encoded at some point in its life. There is no "raw" format for email, there is only text.
At best you could implement Base85 encoding which is more efficient than Base64
So you are going to have to suck up the large file sizes unless you invent your own transport mechanism - such as a point to point TCP/IP based link.

How do I read a big SQL query string from a file?

I'm writing a database project on the iPhone and I'd like to store some big SQL queries in a separate, project-included file.
Then, I'd like to read this query into an NSString * (or, well, const char * is also ok) reference, and then perform it with an sqlite3.
I'm a newbie to iPhone developing, and I have never worked with files, neither I know any details of their storage.
Could you please give me a hint on:
The appropriate file format to store the strings.
How do I store it into the iPhone;
How do I read from it.
Thanks a lot!
You can use:
Any simple character based (text) file would be more than enough
Just put it in a folder in your project, it will get deployed with your Application
Use NSString class.
For issue #3 you can use:
NSString *sqlString =
[NSString
stringWithContentsOfFile:#"yourqueryfile.sql"
encoding:NSUTF8StringEncoding
errors:nil //unless yuo are interested in errors.
];

How can I read bytes from a file in iphone application, chunk by chunk?

I am trying to implement an iphone application which can read some fixed amount of bytes from a file and store in another file. this process will go on up to the end of the file. I am very new to iphone application so please help me on that . Is there any parent classes out there for this specific type of implementation?
I had a very large file which couldn't be read with NSData methods, so I used the following (per TechZen's suggestion for fine grain control).
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:filePath];
[fileHandle seekToFileOffset:offset];
NSData *data = [fileHandle readDataOfLength:length];
If you just want to copy the file, use NSFileManager's copy functions.
If you just want specific bytes in a file, you can load the file using NSData's file methods then you can get specific blocks of bytes and write them to file.
If you want more fine grain control, use NSFileHandler.
Edit01:
This page has examples for close to what you want. I don't have anything on hand.