# Importing base-64 encoded Canvas element into Mathematica

The aim of this code is to transfer a web image into webMathematica for image manipulation. Since the question here failed to resolve direct URL loading, I tried a different method of extraction involving converting the image to a Base-64 string and passing the data directly to the webMathematica jsp.

Attempting to import a canvas image element Base-64 string into Mathematica fails, with it giving the error

Import::fmterr: Cannot import data as PNG format

The base-64 text string was exported using the Javascript function:

function convertImageToCanvas(image) {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext("2d").drawImage(image, 0, 0);
return canvas;
}
var canv  = convertImageToCanvas(document.getElementById("image"));
var dataUrl = canv.toDataURL();


The beginning segment of the data imported is shown:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAAA6CAYAAAD1AhaMAAAgAElEQVR4nKydd3hUZf63n/SemWTSe0iFACGUAIGQMqEjrl3sq64uurqru/7cn1ssYKdKUVBAUVB670iVjrQgINLSe51Mn3Pu948zmZkkoLvv+851fa5hgmZmzjn3+Xzb8yBubv0D1K4DuZ5ff0jd5PqwgmyCul3odxfD7mhFeyJhb4RTh

-
What do you mean "failed to resolve"? Your other question is merely 2 hours old... –  The Toad Apr 4 '13 at 16:32

There is no problem importing base-64 encoded images into Mathematica. Here is an example:

a = Import["ExampleData/rose.gif"];
Export["a.b64", a, {"Base64", "PNG"}];
Import["a.b64", "Base64"]


The data that you create with your JavaScript function are in the form of a URL that then gets translated by a browser to a displayed PNG image. You have to strip away the URL prefix from the string that you seem to have exported in your example. This would best be done before even exporting this as a file, because that file with the prefix data:image/png;base64, is simply not a valid base-64 file. The valid code is everything that follows that prefix.

It's easy to strip this off within Mathematica, but I'll not include this here because, as I said, you should do this at an earlier stage.

-
Merely stripping the data: section does not work. I have tried removing the tag by a substring, which failed with the same error. Apparently Mathematica's Export function gives completely different data. Using turtle.jpg, the Javascript Canvas base-64 encode gives data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAAA6 –  March Ho Apr 4 '13 at 17:53
I've used this extensively, e.g., in this answer. So I see no reason why it shouldn't work for you. Something must be wrong on the JS side of your program, but that's beyond the scope of this list because you're generating the base-64 file incorrectly, but not in Mathematica. –  Jens Apr 4 '13 at 18:00
I just had one additional thought: maybe it has to do with line breaks in your exported file. But since I don't have your exported file, I can't say more. –  Jens Apr 4 '13 at 18:03
I tried out both methods, and the first segments of JS base-64 encode alert(dataUrl) gives iVBORw0KGgoAAAANSUhEUgAAAMgAAAA5CAYAAABzlmQiAAAgA while the Mathematica base-64 encode ExportString[picture, {"Base64","PNG"}] gives iVBORw0KGgoAAAANSUhEUgAAAMgAAAA5CAIAAAD89PN1A which is a completely different string. Why is this so? –  March Ho Apr 4 '13 at 19:35
I can't make a blind guess. How are you exporting the JS code? Can you see the image in the browser if you call window.open(dataURL,'','left=0,top=10,width=500,height=600,toolbar=0,location=0‌​,resizable=0');? –  Jens Apr 4 '13 at 20:11

Given dataUrl, the output of canv.toDataURL(), this works:

ImportString[
StringDrop[dataUrl, StringLength["data:image/png;base64,"]],
"Base64"]


You can specify {"Base64", "PNG"} instead if you like, ImportString seems to auto-detect the type anyway.

Within Mathematica, you can get a test dataUrl value here, by clicking "Show in textarea" and copy/paste: http://tutorials.jenkov.com/html5-canvas/todataurl.html

-