Flex mx Image source path at runtime - actionscript-3

I'm wading through a Flex AIR desktop project that someone else wrote. The original author has used several mx.controls.Image components. Runtime image paths assigned like this:
image.source = "/assets/book.png";
It doesn't work - I just get the broken image icon.
I've never used the above approach in my own code. Personally, I've always used compile-time embedded images or URLLoader/Loader for runtime images.
So, I'd like to learn how to get this image path approach working.
I wrote a simple test program. Here is my .mxml -
<?xml version="1.0" encoding="utf-8"?>
<pf:LearningAS xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:pf="com.powerflasher.*">
<mx:Image id="myImage"/>
</pf:LearningAS>
Here is my connected .as
public class LearningAS extends WindowedApplication {
public var myImage:Image;
public function LearningAS() {
super();
addEventListener(FlexEvent.CREATION_COMPLETE, init);
}
protected function init(event:FlexEvent):void {
myImage.source = '/assets/myimage.png';
}
}
I also added the src/assets folder to AIR package contents. And I added -use-network=false to my compiler directives. (I'm using FDT, and Flex 4.6).

Ok - Cracked it, with some help from the Flex mailing list.
I had to copy my assets folder into my bin folder. So that the paths were relative to the .swf. (Actually, I've done this for previous AS3 projects - but I assumed that packaging assets folder for AIR would cover this.)
Anyway - problem solved.

As per your code you are giving incorrect image path reference instead of myImage.source = '/assets/myimage.png'; try myImage.source = 'assets/myimage.png';
Hope it work for you.

Related

Can't get my relative paths to work with flashDevelop and flex

So i am using FlashDevelop and flex but i can't get the source to work correctly. When ever i Embed a image it works just fine but if i just go source="../img/Koala.jpg" same path that i used for the working embed it doesn't work. In flash builder all i would have to do is source="/img/Koala.jpg" and it work work just fine. If i type in the path "D:\flashDevelop\FlexMobileProject\src\img\Koala.jpg" this works fine. Can anyone please explain what i'm missing here?
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="HomeView" creationComplete="init()">
<fx:Script>
<![CDATA[
[Embed(source = "../img/Koala.jpg")]
[Bindable] public var img:Class;
public function init():void {
var s:String = new String();
label.text = String(imgstage.sourceHeight);
trace(imgstage.source);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<!-- can't find the image even if that path is the same as the embed -->
<s:Image id="imgstage" source="../img/Koala.jpg" y="0" x="0"/>
<s:Label id="label" text="name"></s:Label>
</s:View>
When you specify 'source' for an Image, the file will be loaded at run time. However, FlashDevelop doesn't copy the files from src/ to bin/ - you must populate the bin/ directory manually with the elements you want to load at run time. Paths at run time are resolved relatively to the HTML page.
Embeds are resolved at compile time, and it should be noted that when using FlashDevelop the path is always resolved relatively to the class/mxml file and not relatively to the project root. If the path starts with "/" it will be relative to the classpath's root.
PS: these limitations are actually in the Flex SDK.
If I remember correctly the source="../img/Koala.jpg" is processed at runtime while the embed directive is processed at compile time. So the working directory is different which causes the source="" to fail.
Does the following work :
<s:Image id="imgstage" source="img/Koala.jpg" y="0" x="0"/>
Assuming the img folder is next to your swf file it should work.
In FlashDevelop, whatever files that you want to keep outside the SWF have to be placed in bin folder.

Actionscript: how to call embedded image from an mxml file that didn't embed it?

I've embedded an image in my Flex mxml file (script section) using:
<fx:Script>
<![CDATA[
import com.views.myTitleWindowFile;
...
[Embed(source="com/assets/image_error.png")]
public static const IMG_ERROR:Class;
...
and it works fine. Now I want to use the same image in an mxml file named myTitleWindowFile (for a spark TitleWindow component), which was imported as shown above. The myTitleWindowFile.mxml gives an error on this line:
Alert.show("Please enter a value.", "Error",Alert.OK,null,null,IMG_ERROR);
The error states: 1120: Access of undefined property IMG_ERROR. Any idea what I'm doing wrong? Thanks in advance for any comments.
Your myTitleWindowFile shouldn't be accessing any resource in its parent. It can easily lead to a situation where you want to reuse that myTitleWindowFile in another area of your application that doesn't have IMG_ERROR defined.
I would just declare IMG_ERROR in myTitleWindowFile and access it locally. It keeps your code cleaner and more portable.

How to add image in the library

I have the image path manipulate from database with php. Now how can i have to import those image in the library so that i can use them as a symbol. Thanks in advance.
You cannot load it into library, but you can load this image via php and use it on stage with action script. Take a look at this answer to the similar question:
Load image dynamicly in flash
You can download it to the server and generate source file with Class that have field like this:
class Library
{
[Embed(source = 'path_to_folder/image_name.png')] public static var imageClass : Class;
}
Alsou you should refer this class somewhere to be sure it will be compiled into your swf and use it like this:
const image:Bitmap = new (Library.imageClass)();
In that case you need to recompile your swf every time the image is changed.
But I'm totaly agree with Bartek that it is better to use dynamic loading.

Alternative for getDefinitionByName

In the past, there was a simple trick, to include the flex mxmlc module by adding the following line to the flash-cs4 makefile:
-include-libraries “/absolute/path/to/my/assets/assets.swc”
This gave you the ability to use getDefinitionByName, an helper function to access the embedded swc asset-library (instead of creating hand-written classes all assets).
Unfortunately, this has stopped working since flash-cs4. Does anybody know another solution?
Unfortunately, the only workaround I have found is to explicitly refer each of asset classes somewhere in the code. You may create dummy class like this:
public class AssetsExporter extends Sprite
{
public static function export()
{
AssetClass1;
AssetClass2;
//etc
trace( "DEBUG AssetsExporter.export()" );
}
}
Specify this class as Document class in Flash IDE, so it will be compiled into the resulting swc. Then in the main code of your application call
AssetsExporter.export();
After doing this you will be able to use getDefinitionByName().
You can add them to the libraries in the publish settings.
(Image from http://wiki.gigya.com/ via Google Images)
By the way, if you use SWC files, you can also do
new somepackage.SomeClass();
instead of
new getDefinitionByName("somepackage.SomeClass")
where applicable. This is because SWC files are included at compile time, not runtime.
Even though you can change a compiler setting manually, its easy if you are using FlashDevelop as this is very simple to fix.
Right click your included swc from the Project list. Choose options then "include library (complete library)".
..you can now use getDefinitionByName to get an unreferenced class from your swc file.

pass a base path to a swf loaded at runtime

I have a main.swf which loads a module.swf and the module.swf loads some assets.
The module.swf works standalone and also needs to work when loaded by main.swf.
But unfortunately the module.swf can't find the assets when loaded by main.swf because the assets aren't located relative to the main.swf, but are located relative to the module.swf.
As I can't touch the module.swf and I'm also unwilling to change the directory structure, I am looking for a solution close to the a "base" parameter which can be used when a swf is embedded into html.
Is there a way to simulate the base parameter's behaviour when loading a swf file using Loader?
Here is a similar yet unanswered question.
You could use symlinks as a way to redirect your assets url when loaded via the main swf
Something like this
public class URLUtil
{
public static function getBaseURL(swfURL:String):String
{
return swfURL.substr(0, swfURL.lastIndexOf("/") + 1);
}
}
example of usage inside module:
var assetURL:String = URLUtils.getBaseURL(root.loaderInfo.url) + "asset.filename";
loader.load(new URLRequest(assetURL));