Skip to main content
Tibor Szasz
Participating Frequently
February 2, 2011
Question

HTML Canvas security error in AIR

  • February 2, 2011
  • 5 replies
  • 3586 views

Hello,

I run out of ideas: my problem is that I have to download an image from a server in my application an then invert it and I want to do it with JavaScript.

First I download the image (because using a web URL wouldn't work, just like in regular borwsers) to the applicationStorage directory, then I display it in an IMG tag, then an image manipulation library (Pixastic) is loaded. I get the same exception: SECURITY_ERR: DOM Exception 18, like if I used the original URL.

var file = air.File.applicationStorageDirectory;

file = file.resolvePath("test.jpg");

var fileStream = new air.FileStream();

fileStream.open(file, air.FileMode.WRITE);

var request = new air.URLRequest("http://blogs.adobe.com/bobddv/images/waveform.jpg");

var loader = new air.URLLoader();

loader.dataFormat = air.URLLoaderDataFormat.BINARY;

loader.addEventListener(air.Event.COMPLETE, completeHandler); 

loader.load(request);

function completeHandler( event )

{

     $('test').innerHTML = 'Ready: ' + file.url;

     bytes = event.target.data;

     

     fileStream.writeBytes(bytes, 0, bytes.length);

        fileStream.close();

     /**

      *      Do effect on image

      */

     var img = new Image();

     img.onload = function() {

          Pixastic.process(img, "invert", { invertAlpha:true });

     }

     document.getElementById('test').appendChild(img);

     img.src = 'app-storage:/test.jpg';

}

This topic has been closed for replies.

5 replies

Tibor Szasz
Participating Frequently
March 13, 2012

Hello,

I simply did the following:

var loader = new air.Loader();

...in the callback function:

var bitmapData = loader.content.bitmapData;

bitmapData.getPixels( bitmapData.rect );

And then iterated through the pixels. The downside of this is that this method is really slow if you work with large images. By large I mean 800x600. I was lucky because I only needed to manipulate a small image on the canvas element.

Participant
April 11, 2012

I'm trying to get this to work too. Would you be able to provide the complete code that you were able to get to work? Thanks..

Participant
March 12, 2012

Thanks Chris.

See my bug report:

https://bugbase.adobe.com/index.cfm?event=bug&id=3135965

Please vote it up if you would like to see this fixed.

Participant
March 12, 2012

After spending hours fighting this problem, I finally wrote a simple app to test the security allowances of the Canvas element in AIR. It appears that you cannot use getImageData() or toDataURL() (because both are a method to get the pixel data out of a canvas) if the canvas has something drawn on it from anywhere but the ApplicationStorage directory. The ApplicationStorageDirectory and base64 encoded images both cause the same security error.

This is extremely frustrating as the ApplicationStorage directory is read-only to the application itself. In my case I have a little camera utility that will take pictures with my webcam, and I want to apply some filters and effects to a Canvas element that has some of these photos drawn to it. In order to accomplish this, I currently have the webcam utility (which is run via the NativeProcess class) saving files to the ApplicationStorage directory so I can manipulate them afterward. This is less than ideal because the ApplicationStorage directory is not meant to be the dumping ground for files created or maintained while the app is running (hence it being read-only).

So please, please, please, pass this along so someone who might be able to help adjust the Webkit implementation of the Canvas element to allow either base64 encoded data or images stored in the ApplicationStorageDirectory to be drawn to and manipulated (including getImageData() and toDataURL()) on a canvas.

Thanks!

chris.campbell
Legend
March 12, 2012

Alma,

Would you mind putting that info into a new bug/feature request over at bugbase.adobe.com?  If so, please post back with the URL so that others that encounter the same limitation can vote for your report.  Getting enough people to show interest will give this the best shot at being addressed.

Thanks,

Chris

Tibor Szasz
Participating Frequently
February 5, 2011

Thanks!

I'm experimenting right now with displaying the downloaded image data in a Data URI, it seems to be the only way to load external image onto HTML Canvas.

Update:

It works finally!

I used the as3base64 library to convert the image data into base64 string:

img.src = 'data:image/png;base64,' + runtime.com.dynamicflash.util.Base64.encodeByteArray( bytes );

Altough I assume too that the "dom expection: 18" is occuring intentionally, loading an image shouldn't be this hard. It wasn't even possible in Air 2.0, since it didn't supported Data URI format.

It may come handy in cases like this to give a resource in a non-application sandbox an application sandbox right, like I can do it with the Sandbox bridge.

Cheers,

Tibor

chris.campbell
Legend
February 8, 2011

Hi Tibor,

Thanks for following up with the solution that worked for you!

Chris

Tibor Szasz
Participating Frequently
October 9, 2011

Hello Chris,

  Well, my solution is broken in AIR3. I really don't understand why Adobe did "fix" this. How should I load an external image to a html canvas?

Please suggest me something.

Tibor

chris.campbell
Legend
February 5, 2011

Hi Tibor,

I suspect this is probably as designed, but I've forwarded this post along to our Webkit/Javascript team for their review.

Thanks,

Chris