mrk
mrk

Reputation: 5117

Load app:/ images into HTMLLoader in Adobe Air Flex4.5?

I'm building an app with Adobe AIR that contains a browsing component with mx:HTML. This browser will be used to load external content (publicly-accessible URLs like http://google.com, for example) and after the external content loads, I'm injecting CSS and JS into the HTMLLoader to provide other UI components for my app.

That part works just fine. My JS code is executed by WebKit; my CSS rules are used by WebKit. With the UI components I'm creating with CSS and JS, I'd like to have some images used. So far, I have had success with rendering images in HTMLLoader via the data URI scheme, but this forces me to make base64-encoded copies (added to the CSS rules) of images in assets/ folder.

I'd like to be able to load external URLs with HTMLLoader, and then add CSS, JS, and Images to create UI components in the same HTMLLoader. I am aware of the HTMLLoader property, placeLoadStringContentInApplicationSandbox, but if that what I would use to load local images from my assets/ into HTMLLoader, what would the HTML content of an IMG tag look like, ie how to reference the image?

Any other ideas on how to load local images into the content of an HTMLLoader object?

UPDATE

I've tried the first commentator's idea, using src="app:/path/to/image.png" with no luck.

Here's what I did:

<mx:HTML id="browser"/> 
<fx:Script>
<![CDATA[
browser.addEventListener(Event.COMPLETE,browserEventCompleteHandler);    
browser.htmlLoader.placeLoadStringContentInApplicationSandbox = true; // have set to true and false with no difference.
....initiate browser load....
private function browserEventCompleteHandler(event:Event):void 
{
    var img:* = browser.domWindow.document.createElement('IMG');
    img.src = "app:/assets/arrow_refresh.png";
    img.width="300";
    img.height="300";
    browser.domWindow.document.getElementsByTagName('body')[0].appendChild(img);
}
]]>
</fx:Script>

Running the above code, I see that the IMG element is added to the external content with width and height of 300px, but the PNG image itself doesn't render. Just see an empty 300px square for the IMG element.

FINAL UPDATE

The answer solved my problem, but with one change. I used File and FileStream classes instead of URLRequest to load the png. Here's what I did:

var f:File = File.applicationDirectory.resolvePath("app:/assets/arrow_refresh.png");
var s:FileStream = new FileStream();
s.open(f, flash.filesystem.FileMode.READ);
var data:ByteArray = new ByteArray();
s.readBytes(data,0,s.bytesAvailable);
var b64Encoder : Base64Encoder = new Base64Encoder;
b64Encoder.encodeBytes(data);

Upvotes: 1

Views: 4555

Answers (2)

Simon Eyraud
Simon Eyraud

Reputation: 2435

Why don't encode img in base 64 at runtime ?

package
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.html.HTMLLoader;
    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;

    // Base64Encoder from as3corelib (https://github.com/mikechambers/as3corelib)
    import mx.utils.Base64Encoder;

    public class TestHtml extends Sprite
    {
        private var _htmlLoader : HTMLLoader = new HTMLLoader();

        private var _rawImgLoader : URLLoader = new URLLoader; 

        public function TestHtml()
        {
            super();

            _htmlLoader.width = stage.stageWidth;
            _htmlLoader.height = stage.stageHeight;

            // Load google page
            _htmlLoader.load(new URLRequest("http://www.google.fr"));
            _htmlLoader.addEventListener(Event.COMPLETE,   onEvent);

            // Load one image
            _rawImgLoader.dataFormat = URLLoaderDataFormat.BINARY;
            _rawImgLoader.addEventListener(Event.COMPLETE, onEvent);
            _rawImgLoader.load(new URLRequest("logo.png"));

            addChild(_htmlLoader);
        }

        private function onEvent(e:Event) : void
        {
            addImg();
        }

        private function addImg() : void
        {
            // Wait for img and html
            if(_htmlLoader.loaded && _rawImgLoader.data)
            {
                // Encode img
                var b64Encoder : Base64Encoder = new Base64Encoder;
                b64Encoder.encodeBytes(_rawImgLoader.data);

                var img:Object = _htmlLoader.window.document.createElement('IMG');
                img.src = "data:image/png;base64," + b64Encoder.flush();
                img.width="300";
                img.height="300";
                var body :Object = _htmlLoader.window.document.getElementsByTagName('div');
                body[0].appendChild(img);
            }
        }
    }
}

Upvotes: 4

alxx
alxx

Reputation: 9897

placeLoadStringContentInApplicationSandbox doesn't work because your content isn't loaded from a string, it's loaded from external url. And remote content is restricted from using local files. If you get loaded html and set it manually to htmlText property, it will become local content, but this may have problems (like page flickering.)

Upvotes: 1

Related Questions