Unable to access embedded images in htmlText - apache-flex

Images can be included in TextArea controls using the htmlText property:
ta.htmlText = '<img src="http://..."/>';
How can I reference embedded images?
An example:
<mx:TextArea xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
[Embed(source='../assets/img.gif')]
public var img:Class;
]]>
</mx:Script>
<mx:htmlText>
<![CDATA[
<img src="???" />
]]>
</mx:htmlText>
</mx:TextArea>
UPD:
<img src='../assets/img.gif />
works on local machine, but in server environment it throws:
Error #2044: Unhandled IOErrorEvent:. text=Error #2035: URL Not Found.
How can I fix this?

OK, I've just spent a couple of hours sorting this out, but I've got it working in Flash and Flex.
Displaying images in a TextField
You can load DisplayObjects into TextField <img /> tags including MovieClips, Sprites and embedded images.
In Flash or Flex if you want to display an embedded image then you will have to create a wrapper class that extends a DisplayObject class (e.g. Sprite or MovieClip).
Make sure your text field is large enough to contain the image. During testing I thought things weren't working when I really had the TextField too small to display the whole image.
Flash Example
Simple example, all code is on the main timeline.
Create a dynamic TextField on the stage. Give it a useful name, I'm calling mine txtImageTest.
Resize txtImageTest to a decent size, e.g. 300x150px.
Create a new MovieClip symbol and give it a class name, e.g. imageClip1.
Draw something in your new clip or place an embedded image inside imageClip1.
Go back to the main timeline, deselect all objects and open the Actionscript editor on the first frame.
Turn on multiline and word-wrapping on the text field:
imageClip1.wordWrap = true;
imageClip1.multiline = true;
imageClip1.htmlText = "<p>You can include an image in your HTML text with the <img> tag.</p><p><img id='testImage' src='imageClip1' align='left' width='30' height='30' hspace='10' vspace='10'/>Here is text that follows the image. I'm extending the text by lengthening this sentence until it's long enough to show wrapping around the bottom of the image.</p>"
Save and test your movie.
Flex Example
Since we can't just create a new MovieClip in the library like we did in Flash we need to create a new class that performs the same task (this method also works in Flash if you want want to create a new clip in the library).
Here is my class for a black triangle bullet, called BlackArrow.as:
// Set the correct package for you class here.
package embed
{
import flash.display.Sprite;
import mx.core.BitmapAsset;
public class BlackArrow extends Sprite
{
// Embed the image you want to display here.
[Embed(source='assets/embed/triangleIcon_black.png')]
[Bindable]
private var TriangleImage:Class;
public function BlackArrow()
{
super();
// Instantiate the embedded image and add it to your display list.
var image:BitmapAsset = new TriangleImage();
addChild(image);
}
}
}
NOTE: Do not extend Bitmap (in Flash) or BitmapAsset (in Flex) as they do not scale or position properly in the TextField. Choose Sprite or something similar.
Here is an example of a class that displays this image in the TextField:
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
width="100%" height="100%">
<mx:Script>
<![CDATA[
import embed.BlackArrow;
// You must include a variable declaration of the same type as your
// wrapper class, otherwise the class won't be compiled into
// the SWF and you will get an IOError.
private var img2:BlackArrow;
]]>
</mx:Script>
<mx:Text id="txtResults1" width="100%" height="100%">
<mx:htmlText>
<![CDATA[<p>You can include an image in your HTML text with the <img> tag.</p><p><img id='testImage' src='embed.BlackArrow' align='left' hspace='10' vspace='10'/>Here is text that follows the image. I'm extending the text by lengthening this sentence until it's long enough to show wrapping around the bottom of the image.</p>]]>
</mx:htmlText>
</mx:Text>
</mx:VBox>
Note that I am using the fully-qualified class name in the src attribute of the image tag.
Final Notes
Images are aligned to the left or right of a text field as determined by the align attribute of the image tag. This means that you cannot position an image in the middle of text without accessing the image directly.
A list of the attributes supported by the image tag is here:
http://blog.coursevector.com/notes-htmltext
The TextField LiveDoc page is here:
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/text/TextField.html
The getImageReference() function is what you need to get a reference the images in the textfield:
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/text/TextField.html#getImageReference%28%29
Make sure you use fully-qualified class names in the src attribute.
Make sure you declare a variable of your wrapper class to ensure it is compiled into the SWF.

You can specify embedded images as the src for HTML img tags in htmlText by referencing them using their fully qualified class name, which you can determine using getFullyQualifiedClassName). Like so:
public class Example
{
[Embed(source="myImage.png")
public static const MyImage:Class;
public function getHTMLImg() : String
{
return "<img src='" + getQualifiedClassName(MyImage) + "' />";
}
}
That's much simpler than creating a wrapper class for every image which might be embedded...

Try:
<mx:htmlText>
<![CDATA[
<p>
<img src='../assets/butterfly.gif'
width='30' height='30'
align='left'
hspace='10' vspace='10'>
</p>
]]>
</mx:htmlText>
See documentation.

I was looking for the same thing. The idea behind using embedded images is to prevent loading of said images from an external URL. So the accepted answer actually isn't solving the problem. I've seen the documentation, and they too use an URL there, and that image will not be compiled into the swf, but will be loaded at runtime from the server. Why they call that embedded image is probably because it's embedded withing the text, but what I'm looking for is to use an image that is embedded in the compiled code.
Why would you want an embedded image show used in a htmlText? Because it's the easiest way to display an image in a tooltip (you just need to override to default tooltip class to set the htmlText instead of text, and set it as the default tooltip class in the TooltipManager). In my search I discovered this: http://groups.google.com/group/flex_india/browse_thread/thread/cf0aa62afaae3fdc/b21f462f8d5da117?pli=1 . Haven't test it yet, and I guess the problem will come in determining that linkage id. I'll come back with more details when I have them.

Sly_cardinal wrote a very helpful answer. Big thanks to him!
I could not solve this problem for half a day. Sly_cardinal noticed that if you do so getQualifiedClassName (embed bitmap) image is inserted in the text is not correctly just to the upper left corner.
Sly_cardinal offered to make a wrapper class.
I want to append an his answer
A new class wrapper
ImageWrapper.as ->
package
{
import flash.display.Bitmap;
import flash.display.Sprite;
public class ImageWrapper extends Sprite{
public static var img:Class;
public function ImageWrapper() {
var bitmap:Bitmap = new img();
addChild(bitmap);
}
}
}
The call in the code:
[Embed(source = "img/MyImg.png")] var _MyImg:Class;
ImageWrapper.img = _MyImg;
tf.htmlText = "My text, and my image <img src='ImageWrapper'>";
That's it.
Thank you!

Try
src='../assets/img.gif'
Taken from: Using the htmlText property

Use src='assets/img.gif' but you will have to create an assets directory in the directory of the server where the application SWF is deployed and place your img.gif file there. When in html, it is looking for the file relative to the SWF file.
This will allow you to use the same file and location in both development and deployed locations.

It works on localhost because you have the image on the machine, so you can load it. If you are embedding it, it is not uploaded on the server in the specified directory, rather it is contained by the .SWF file itself. Upload the image (browse it for upload from you source files folder) in the corresponding place in the production output.

There's no need to bother ourselves any more buddies! from now on importing MovieClips is not such a big deal! by the help of the new class named TextArea (not TextArea the component, it's an OOP class an extenstion to the original TextField class).
We don't need Embedding or library any more, we can use the TextArea every where instead of Textfield and that enable us to import our own SWF files such as a video player, talking avatar or anything else in line of our texts.
It has lots of more features and doesn't specifically limited to this issue.
Check out www.doitflash.com for more information, the site provides the platform and downloading it is also free of charge :)

Related

CSS "display:none" doesn't prevent image loading? [duplicate]

is there a way with javascript/jquery to prevent images from loading? I am building a slideshow from a html list with images. So I would like to collect all the src data and then prevent the images from loading. So later when the user really needs the image I would load it then.
I found some lazy loading script on google but couldn't find the way they prevent images from loading.
Thanks in advance.
Edit1:
It seems from the answers that it's not possible to use javascript to prevent images from loading.
Here is a script that does lazy loading. Could anybody explain how it works? It seems when javascript is off it just loads the images normaly and when it's on it will load them when you scroll to their location.
You can wrap the image in a noscript tag:
<noscript>
<img src="foo.jpg"/>
</noscript>
All browsers that has JavaScript enabled will ignore the image tag so the image won't load.
If you render the HTML on the page, even if it's hidden, it's going to load. If you want images to load only when they're needed, you're going to have to dynamically set the source (src) on the image tag in javascript.
Edit 1: The script you referenced merely checks to see how far you've scrolled the page down and then determines which images are visible (or almost visible) by checking their top -- see the $.belowthefold and $.rightoffold extensions.
The example works great when the images are all the same size because their containers can also be the same size and you won't get any odd page resizing behavior when you lazy load them. If your images' heights and widths vary, you may get some odd results.
Edit 2:
<script type="text/javascript" charset="utf-8">
$(document).ready( function() { $("img").removeAttr("src"); } );
</script>
<img src="Chrysanthemum.jpg" />
<img src="Desert.jpg" />
<img src="Hydrangeas.jpg" />
<img src="Jellyfish.jpg" />
<img src="Koala.jpg" />
<img src="Lighthouse.jpg" />
<img src="Penguins.jpg" />
<img src="Tulips.jpg" />
Store the URLs somewhere else, then set all image URLs to some dummy image (empty, transparent, "loading data...", whatever). When an image should be displayed, use JS to set the src attribute and the browser will fetch it.
Well with Prototype you can do something like this I guess:
var unloaded = [];
$$('img.noload').each(function (image) {
unloaded.push(image);
image._src = image.src;
image.src = '';
});
To load all of them:
unloaded.each(function (image) {
image.src = image._src;
});
To load the first one:
function loadImage (image) {
image.src = image._src;
}
loadImage(unloaded.shift());
Well I hope you got the idea.
Just do not include the img tag in your original HTML, generate it on the fly using DHTML as you need it. You can also put a fake url to image in the img tag and replace it with the real one dynamically.
On the side note - what's the point. All you are trying to do here is to build another caching mechanism over the existing one. Leave caching to browsers, they are pretty good at this
You can use the portion below to replace all image tags with a dummy file (for example, an 1x1 transparent gif). The url's are stored in a array for later reference.
$(document).ready(function(){
var images = new Array();
$("img").each(function(i){
images[i] = this.src;
this.src='blank.gif';
});
});
I don't recommend this solution, for many reasons (like it ruins your page if you don't have Javascript enabled, screen-readers etc), but its a possibility...
You could change the IMG tag so that it hijacks a different attribute, like ALT (LONGDESC, or TITLE too):
Then use Javascript to update the SRC attribute with the ALT value as you need to.
So thats one way, and not a good one. I think the only real approach is to dynamically generate the proper IMG tag as needed via Javascript and not publish it with the HTML (this too has implications for non-JS browsers etc)
This article shows some tests using both css background and img tags on a set of standard browsers.
In my personal experience the PictureFill by Scott Jehl is the best solution I've ever used to deal with image resolutions and sizes for mobile devices.
I know this is an old question, but it took me a while to figure out how to accomplish what I wanted to. This is the top result on DuckDuckGo so I think it's worth posting here.
This little snippet will prevent imgs, embeds and iframes from being loaded and will manually load them later when needed.
One caveat: objects that are loaded too fast for JQuery/JavaScript to catch them are still loaded, and the script still removes them.
Since this is intended to decrease load time this should not be a problem though.
Fiddle
loadObjects = function() {
/* LOAD OBJECTS */
$("img, embed, iframe").each(function() {
var obj = $(this);
obj.attr("src", obj.data("objsrc")).ready(function() {
obj.fadeIn(1000, "linear").prev(".loading").fadeOut(750, "linear", function() {
$(this).remove();
});
});
});
}
$(document).ready(function() {
/* *** PREVENT OBJECTS FROM LOADING *** */
$("img, embed, iframe").each(function() {
var obj = $(this);
obj.data("objsrc", obj.attr("src"));
obj.hide().attr("src", "").before("<span class=\"loading\"></span>");
});
});
You can also wrap the image in a template tag:
<template>
<img src="foo.jpg"/>
</template>
Browsers will not try to load it.
The answer to this problem is very easy via insertAdjacentHTML() which lets you add HTML when you like, in this case on button click:
function LoadImages(){
document.body.insertAdjacentHTML('afterEnd','<img src="one.jpg" alt="" height="100" width="100"> <img src="two.jpg" alt="" height="100" width="100">');
}
The HTML...
<button onclick="LoadImages();">Click to load images</button>

How to insert a LinkElement into a paragraph in Flex mobile project?

Hi, everyone.
I'm working on a mobile project on Flex.
Once I get a paragraph from the internet, I need to recognize a specific string(may not appear just once)from that paragraph and make it clickable to trigger the other function in flex project.
I know the "LinkElement" helps, such as the content of this url:
http://bbs.9ria.com/forum.php?mod=viewthread&tid=42640
in which the code is like
var p:ParagraphElement=new ParagraphElement();
var tf:TextFlow=new TextFlow();
var nameLink:LinkElement=new LinkElement();
var nameSpan:SpanElement=new SpanElement();
nameSpan.text="LINK_TEXT";
nameLink.addChild(nameSpan);
p.addChild(nameLink);
//////////////////////////////////////////////////////
tf.addChild(p);
rt.textFlow=tf;
nameLink.addEventListener(FlowElementMouseEvent.CLICK, link_click_handler);
<s:RichEditableText editable="false" selectable="false" id="rt/>
However there's a simple linked text only, but I want other normal text(without link) in the same line.
The effect I want can be easily achieved by html like:
<p>
unlinked_text1
<a>linked_text</a>
unlinked_text2
</p>
I've tried simply add another unlinked child at the place of "////////////////"
But it didn't work.
Is there any solution?
It's doesn't seem so hard, but I just can't make it.
Thanks for any sol in advance, please help me!!
A ParagraphElement object can have the following types of child objects: SpanElement, LinkElement, InlineGraphicElement, and TCYElement.
So why not just add additional SpanElements to your paragraph that contain the normal (non-linked) text:
var regularText:SpanElement = new SpanElement();
regularText.text = "this is some regular text";
paragraphElement.addChild(regularText);
If you already tried, this please show your code so we can help you further.

Loss of image quality when zooming in Flex Mobile application

i have a mobile application that i am creating in Adobe Flex (Flash Builder 4), and i am trying to create a zoom function. The one i have works, but the point is to be able to more easily read words that are in the image (the images are .jpg files). The images are 2550x3300 originally, but as soon as you zoom, the image quality reduces drastically, and nothing is readable.
My code for the zoom function is included below.
protected function onZoom(e:TransformGestureEvent, img:Image):void
{
img.transformAround(new Vector3D(e.localX, e.localY, 0), new Vector3D(img.scaleX*e.scaleX, img.scaleY*e.scaleY, 0));
}
and this is the code for the image object:
<s:Image id="titlepage" includeIn="title_page" x="0" y="0" width="320" height="415"
gesturePan="onPan(event, titlepage)"
gestureSwipe="onSwipe(event)"
gestureZoom="onZoom(event, titlepage)"
source="#Embed('assets/myImage.jpg')"/>
Image quality would be improved by setting smooth to true for anti-aliasing.
<s:Image smooth="true" />
There are many ways to handle registration issues - you might be interested in Yahoo Astra utils DynamicRegistration class.
Maybe something like this?
<fx:Script>
<![CDATA[
import com.yahoo.astra.utils.DynamicRegistration;
protected function image_gestureZoomHandler(event:TransformGestureEvent):void
{
DynamicRegistration.scale(image,
new Point(event.localX, event.localY),
image.scaleX *= event.scaleX,
image.scaleY *= event.scaleY);
}
]]>
</fx:Script>
<s:Image id="image"
smooth="true"
gestureZoom="image_gestureZoomHandler(event)" />
I'm not positive on this, but I think the 'transform' functions creates a bitmap out of your Image which is why you're losing quality. Try using the 'smoothing' attribute on your image.
From there, it's simply scaling and moving your image incrementally. However, what I'm not sure about is if the localX/Y property is from the original place of touch, or of the new position on the container (ie. if you're pinch/zooming from the middle and it scales, will the point still be on the middle or slightly top left).
I'll try to test this out on my phone and see what I come up with.

How to set the a background image of a RichTextEditor in Flex 4

I have tried setting the background image this way, but it doesn't work. Any ideas how to set the background image of a rich text control in flex as easy as possible? Thanks
.rte{
...
backgroundImage: "assets/globe.jpg";
}
and
<mx:RichTextEditor id="rt"
...
styleName="rte"
/>
Unfortunately, you can't.
The docs for RichTextEditor show that it doesn't support a backgroundImage property, and the component is not skinnable.
Therefore, I'd suggest creating your own wrapper component, which accepts an image, like so:
<!-- Note: Using Canvas becuase your post indicates Flex 3, if using Flex 4, please use Group -->
<Canvas>
<mx:Image width="100%" height="100%" />
<RichTextEditor />
</Canvas>
The RichTextEditor component doesn't support background images last I checked. What you'd want to do is create a custom RTE skin where you add an image behind the actual text, then within the skin, have the do getStyle('backgroundImage') and set it in a bindable private var which is then binded to the image.
That's about it. It's either use this skin or you can always wrap your RTE within a BitmapImage or some other kind of component that supports background images.
EDIT: Sorry, didn't see that this was Flex3. In that case, you'll need to extend your RTE component and add the Image component manually by overriding the createChildren function and then changing the value of the image by overriding the updateDisplayList function using the same getStyle function as mentioned above.
It can be done by setting RTE TextArea's backgroundAlpha to 0
<mx:RichTextEditor id="richTextEditor"
backgroundImage="#Embed('<imagepath>')" width="100%" height="100%"
initialize="{richTextEditor.textArea.setStyle('backgroundAlpha', '0') }"
/>
Note:Please modify image path and you can also set style through CSS/Style tag
Hopefully this will helps

displaying HTML inside a Flex application

I have some HTML that is generated via a Rich Text Editor outside of my Flex application but would like to display it inside Flex.
The HTML is simple HTML tags, things like styles, anchors, and possibly image tags, is there a control that would let me render this HTML in flex or am I going to have to roll up my sleeves and roll my own?
Any ideas appreciated...Thanks.
If the HTML is really simple, you can display it in a normal label or textarea component, If it is more complex, I'll quote what I answered in this question. The discussion there also has a little more info.
If it is complex HTML and Javascript, one possible way is HTMLComponent, a method that uses an iframe over your flash to make it appear like the HTML is in your app. There are a few downsides to this method however - most of them described in detail at Deitte.com.
If this can move offline, you could use Air (it has an mx:HTML component built in). Deitte.com has a detail of this technique as well.
Check out the documentation on mx.controls.Label and flash.text.TextField (which is what displays the text in a Text or Label control in Flex). The TextField documentation states that
The <img> tag lets you embed external image files (JPEG, GIF, PNG), SWF files, and movie clips inside text fields. Text automatically flows around images you embed in text fields. To use this tag, you must set the text field to be multiline and to wrap text.
Which means that you can display an image in a Text component in Flex by setting its htmlText property to some HTML which contains an <img> tag. You can't use Label, because it is not multiline.
I've noticed that text fields have trouble with properly measuring their heights if the images displayed in them are left or right aligned with text flowing around them (e.g. align="left"). You may have to add some extra spacing below to counter that if you plan to use aligned images.
You will have to use flex iFrame control.
It is not an 100% flash solutions, and combines a bit of js calls but works perfectly for me.
You can grab latest source code from github https://github.com/flex-users/flex-iframe
Here is some sample code from the component author.
<!---
A basic example application showing how to embed a local html page in a Flex application.
#author Alistair Rutherford
-->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:flexiframe="http://code.google.com/p/flex-iframe/"
horizontalAlign="center"
verticalAlign="middle"
viewSourceURL="srcview/index.html">
<!-- Example project presentation -->
<mx:ApplicationControlBar dock="true">
<mx:Text selectable="false">
<mx:htmlText><![CDATA[<font color="#000000" size="12"><b>flex-iframe - Simple html example</b><br>This example shows how to embed a simple Html page in a Flex application.</font>]]></mx:htmlText>
</mx:Text>
</mx:ApplicationControlBar>
<!-- HTML content stored in a String -->
<mx:String id="iFrameHTMLContent">
<![CDATA[
<html>
<head>
<title>About</title>
</head>
<body>
<div>About</div>
<p>Simple HTML Test application. This test app loads a page of html locally.</p>
<div>Credits</div>
<p> </p>
<p>IFrame.as is based on the work of</p>
<ul>
<li>Christophe Coenraets</li>
<li>Brian Deitte</li>
</ul>
</body>
</html>
]]>
</mx:String>
<!-- Example using the 'source' property -->
<mx:Panel title="A simple Html page embedded with the 'source' property"
width="80%"
height="80%">
<flexiframe:IFrame id="iFrameBySource"
width="100%"
height="100%"
source="about.html"/>
</mx:Panel>
<!-- Example using the 'content' property -->
<mx:Panel title="A simple Html page embedded with the 'content' property"
width="80%"
height="80%">
<flexiframe:IFrame id="iFrameByContent"
width="100%"
height="100%"
content="{iFrameHTMLContent}"/>
</mx:Panel>
</mx:Application>
#mmattax
Indeed you can display images in a TextArea component. The approach is not entirely without problems though...

Resources