Canvas Hierarchy to BitmapData

I'm trying to capture the graphic contents of a hierarchy of Canvases to a BitmapData. I'm using BitmapData.draw and passing it the Canvas that contains the hierarchy. However I am only capturing the contents of the root Canvas's Graphics object. None of the contained objects are showing up in the BitmapData. I am creating a hierarchy of Canvases in order to get graphics effects (drawing with a hierarchy of clipping paths) that I can't do in a single Graphics object. Is there any way to flatten this out to a single bitmap?
David

Hi,
Although I dont understand your problem properly,but still trying to Resolve it.
Below is the code in which I am having a canvas inside canvas and so on.
Then I am capturing the bitmapdata of the outer canvas, and creating a new Image
with that bitmapdata.It is creating the same childeren heerarchy as is in the
oringional Canvas.The code is below.
Main.MXML
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal">
<mx:Script>
<![CDATA[
import mx.core.UIComponent;
public function CreateBitmapImage() : BitmapData
var bitmapData:BitmapData = getBitmapData( UIComponent( sourceCanvas ) );
targetImage.source = new Bitmap( bitmapData );
return bitmapData;
private function getBitmapData( target : UIComponent ) : BitmapData
var bitmapData : BitmapData = new BitmapData( target.width, target.height,true, 0x00000000);
bitmapData.draw( target );
return bitmapData;
]]>
</mx:Script>
<mx:Canvas id="sourceCanvas" width="500" height="500" backgroundColor="0xFFFFFF">
<mx:Canvas width="400" height="400" backgroundColor="0xFF0000">
<mx:Canvas width="300" height="300" backgroundColor="0x000FF00">
<mx:Canvas width="200" height="200" backgroundColor="0x0000FF"/>
</mx:Canvas>
</mx:Canvas>
</mx:Canvas>
<!--This will be the Image Created by the BitmapData of the 'sourceCanvas'.-->
<mx:Image id="targetImage" creationComplete="CreateBitmapImage()"/>
</mx:Application>
Pls let me know if you have any problem,or i am unable to understand ur problem.
Shardul Singh Bartwal

Similar Messages

  • Problem obtaining BitmapData for a canvas via Javascript

    Hi,
    For my web application I have one HTML button, which is outside of flash application shown on the same page. Via Flex application I've declared callback function to be called by Javascript in this way:
    ExternalInterface.addCallback("cbProcessButton", processButton);
    For HTML button I have this:
    <input id="bSave" name="button" type="submit" value="Save" onclick="getSWF('${application}').cbProcessButton();" />
    And inital lines of processButton function (which is Flex function) are defined as this:
              var bitmapData:BitmapData = new BitmapData(canvas.width, canvas.height, false, 0xFFFFFF);
              bitmapData.draw(canvas);
              var jpgEncoder:JPEGEncoder = new JPEGEncoder(85);
              var jpgStream:ByteArray = jpgEncoder.encode(bitmapData);
    Now I have problem here. If I call that processButton in this way for my canvas via Javascript - then I get length of jpgStream as 32654 bytes and after save into a file - that jpg file cannot be shown properly.
    But if I call the same processButton via a Flex button, which is placed inside my Flex - I get jpgStream in my case of length 33074 bytes and after save to a file - could normally show it later.
    I'm using Flex Builder 3 with Flex sdk 3.5.0.12683 installed and later show everything/work via Flash Player v10,1,53,64 installed on WinXP.
    Is it known bug/limitation of BitmapData usage in such Javascript scenario? Or is it bad sdk/Flash Player? Are you able to reproduce such in your environment?
    I'm really going out of my mind to understand why lengths of encoded data in 2 cases are different. Of course I know about that 2176 Error for other situations dealing with Flex UI, but here I don't get it - so I assume my Javascript scenario is allowed by Adobe so far.
    Any help would be highly appreciated.
    Andrejus

    Thanks very much, Everybody. Here is something that works. This is based on all the inputs provided by you guys. Many thanks.
    <table>
    <td width="3%" align=right></td>
    <td align=left valign=top> <b>Existing Notes:</td>
    <TD><textarea name="existing" wrap="hard" cols="70" rows="10" onkeypress
    ="validateSize(this, 2000)" onchange="validateSize(this, 2000)" READONLY>
    <%
    int logSize = actionLog.size();
    if (logSize > 0) {
    for (int j=logSize-1; j >=0; j--){
    DealStatusAction dsa = (DealStatusAction)actionLog.get(j);
    String actionNm = dsa.getActionName();
    String actionDate = dsa.getActionDate().toString() + "";
    String memo = dsa.getMemo();
    String actionPerformer = ((dsa.getLastName() == null || dsa.get
    FirstName() ==null)?"":(dsa.getFirstName() + " " + dsa.getLastName()));
    String datePerf = actionDate + " " + actionPerformer;
    %>
    <%=datePerf%>
    <%=actionNm%>
    <%=memo%>
    <%
    %>
    </textarea>
    </TD>
    </table>

  • BitmapData.draw is not rendering contents outside visible portion of Canvas

    My application has a Canvas with a bunch of elements on it and which has a scrollbar to see the full contents of it, i.e. the Canvas has a height of 200px, but the objects contained within extend past the 200px all the way to 400px. When I pass this canvas object to my BitmapData instance which I have created with a height of 400px, the result is that I get a 400px image but only the top 200px are actually rendered. If I move the scrollbar down and call draw, I get the bottom 200px of the canvas rendered on the top half of the BitmapData.
    Is there a way to render the full contents of the Canvas object and not only what is currently visible in the viewport?
    Thanks
    Ruy

    It is internal, meaning it is not documented, but it should be in the rawChildren or you can access it via mx_internal.  I would think if you set height=400, called validateNow() then bitmapData.draw it might work.
    You could also try setting scrollRect=null.
    FWIW, often folks have a print view that hooks up to the same data model.
    Alex Harui
    Flex SDK Developer
    Adobe Systems Inc.
    Blog: http://blogs.adobe.com/aharui

  • Canvas background via Java

    Is there a way to set the background color of a canvas via Java. I am using FocusLost and FocusGained to change the background color of textfields to be able to better show where the cursor is on a form. I have a couple of forms that have multiple canvases showing at the same time and the user wants the canvas color to change when the cursor is in a field on that canvas.
    Is there a focus event associated with a canvas? Is there a way to control the canvas color via Java?

    Hi Dave,
    Is there a reason you don't use SET_CANVAS_PROPERTY(BACKGROUND_COLOR, ...)?
    In Java on the client, the canvas is not one of the objects we expose. However you can do what you want in Java and using some getParents() to get to the canvas, and then do a setBackground() on that. But note that this isn't supported, and the hierarchy could change at any time...
    Regards,
    Robin Zimmermann
    Forms Product Management

  • BitmapData class - displaying and resizing

    Hi Forum,
    I'm trying to teach myself flex by working through the tutorial videos on here and searching the net, however i have become a bit stuck with image manipulation.
    I want to make a Flash solution that loads in an image and with let the user zoom in and out and pan around.  I'm having problems quite early on particularly with displaying the resized image correctly and was wondering someone could provide some advice....some simple advice.  I have development experience but very little knowledge with flash/flex components.
    So far i have loaded the image, and i've been playing around with the bitmapdata class and managed to resize it.  But when i output it the image is smaller but has a background that takes up the original size.  I Think this may be solved somehow with the rec property?  But i can't get it to work. 
    I wanted to load the image at its original size and then resize it smaller to fit a view area, then when someone wants to zoom increase the size of the displayed image with the overflow not showing.
    So far my output looks like this:
    As you can see the image is smaller but it must still be taking up the same size or something because the canvas has scoll bars on it.  Whats happening.  Also when the image is bigger than the canvas how can i not have scroll bars and hide the overflow.  Here is my code:
    mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
         layout="absolute"
         backgroundGradientAlphas="[1.0, 1.0]"
         backgroundGradientColors="[#FBF8F8, #FBF8F8]"
         applicationComplete="Init()">
         <mx:Script>
              <![CDATA[
                   private var imgLoader:Loader;
                   private function Init():void{
                        imgLoader = new Loader();
                        //Image location string
                        var imageURL:String = "http://www.miravit.cz/australia/new-zealand_panoramic/new-zealand_panoramic_01.jpg"
                        //Instantiate URL request
                        var imageURLReq:URLRequest = new URLRequest(imageURL);  
                        imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoadCompleted);
                        imgLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressListener);
                        //Begin image load
                        imgLoader.load(imageURLReq);
                   private function imgLoadCompleted(event:Event):void{
                   //On completion of image load     
                        progressBar.visible = false;
                        var scale:Number = .1;
                        //Set matrix size
                        var m:Matrix = new Matrix();
                        m.scale (scale,scale);
                        var bmd:BitmapData = new BitmapData(this.width, this.height);
                        bmd.draw(this.imgLoader,m);
                        var bm:Bitmap = new Bitmap(bmd);
                        auctionImageContainer.source = bm;
                   private function progressListener(event:ProgressEvent):void {
                    //Update progress indicator.
                         progressBar.setProgress(Math.floor(event.bytesLoaded / 1024),Math.floor(event.bytesTotal / 1024));
              ]]>
         </mx:Script>
         <mx:Canvas height="583" width="674">
              <mx:Canvas id="cvsImage"
                   borderColor="#BABEC0" borderStyle="solid" left="152" right="151" top="177" bottom="121">
                   <mx:Image id="auctionImageContainer" />
                   <mx:ProgressBar id="progressBar"
                             mode="manual" 
                               x="84.5" y="129"
                               labelPlacement="center"
                               themeColor="#6CCDFA" color="#808485" />
              </mx:Canvas>
         </mx:Canvas>
    </mx:Application>
    Thanks for any help
         LDB

    MediaTracker isn't about the number of images. I've been bitten in the ass by this before -- images seem to magically refuse to appear, or only appear on reloads, and it's because paint() got called before the image was loaded. MediaTracker fixed it.
    I don't know what you mean about images not working in constructors though. You can do that.
    Here's some code that works to display an image (for me anyway):
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.*;
    public class Test {
      public static void main(String[] argv) {
        Image i = Toolkit.getDefaultToolkit().createImage("image.jpg");
        Frame f = new Frame("Test");
        MediaTracker mt = new MediaTracker(f);
        mt.addImage(i, 1);
        try {
          mt.waitForAll();
        } catch (InterruptedException e) {
          e.printStackTrace();
        f.addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            System.exit(0);
        f.add(new Displayer(i));
        f.pack();
        f.setVisible(true);
      private static class Displayer extends Canvas {
        private Image i;
        Displayer(Image i) { this.i = i; }
        public void paint(Graphics g) {
          g.drawImage(i, 0, 0, null);
        public Dimension getPreferredSize() {
          return new Dimension(i.getWidth(null), i.getHeight(null));
        public Dimension getMinimumSize() { return getPreferredSize(); }
    }

  • When/Why to use Canvas?

    Okay, so I'm looking into creating custom components and I know that Canvas class was made to give programmers a class to use solely for drawing. However, you could just use JComponent/Component to creat custom buttons, menu's, etc. So I'm a little confused why we have Canvas and what the best way is to go about making a custom component, graphically.

    LavaJava wrote:
    Okay, here's another point to bring up since you said don't mix awt and swing. Things like graphics and graphics 2d are under awt but to my knowledge there is no equivalent in swing. This all may seem confusing at first, but the more you play with it, the more you read on it, the more it will make sense. Morgalr and Darryl are as usual right on the money. As they state, Swing is built on top of AWT, however they are very different in how they display components. While AWT uses the native OS to render its buttons, panels and other widgets, Swing renders these things internally, all except the root container such as the JFrame (I believe). This gives Swing much greater flexibility in how it displays these things and how you can change and control them. Because of these differences though, it is generally not safe to display Swing widgets together with AWT widgets. There are as always exceptions, but you have to have a darn good reason to claim an exception (you don't), and have to have the smarts to be able to mingle the AWT and Swing widgets together (I don't).
    Also, for some odd reason, JFrame is in swing package but it's hierarchy is under awt. In fact, that very fact about JFrame has give me problems when trying to do keybindings on a JFrame.Then don't do key bindings on the JFrame. Do it instead on one of the JComponents it holds. You do know that even the contentPane is at its heart a JComponent (though this needs to be casted if you want to use it directly).
    Good luck,
    Pete

  • Drawing mc with canvas on it

    Hey,
    I got a problem with displaying canvas on mc, which is drawn on BitmapData object. Code is more or less:
    var can:Canvas = new Canvas;
    can.setStyle("backgroundColor","blue");
    can.width = 100;
    can.height = 100;
    can.x = 100;
    can.y = 100;
    var mc:MovieClip = new MovieClip
    mc.addChile(can);
    var bd:BitmapData = new BitmapData;
    bd.draw(mc);
    this.beginBitmapFill(bd,new Matrix(),false,false);
    this.graphics.endFill();
    And I dont see the canvas. ValidateNow() or callLater doesn't help either.
    On the other if I add a sprite instead of canvas I can see this sprite on screen.
    What should I do and why validateNow() doesn't help in this case?

    thanks for that :)
    my problem is that the nodes are placed inside a panel to appear as draggable entities on the GUI interface using the google web toolkit. that way I need to somehow not put the JPanels in a JFrame but in the panel created by google web toolkit, which I think you cannot do?

  • Adding a child canvas immediately

    Hi there,
    I'm trying to add a canvas to my application which fills the screen while a CPU intensive action runs in the background. No matter what I try, I cannot get the loading screen to appear until after the slow action has finished.
    Code (belongs in a subclass of Canvas):
    private function saveBitmap(event:ContextMenuEvent):void
        loadingScreen.visible = true;
        loadingScreen.appLoadingText.text = "Preparing bitmap...";
        addChild(loadingScreen);
        validateNow();
         // Slow code!
        var bmpd:BitmapData = new BitmapData(canv.width, canv.height);
        bmpd.draw(canv);
        var fr:FileReference = new FileReference();
        fr.addEventListener(Event.COMPLETE, removeLoadingScreen);
        fr.addEventListener(Event.CANCEL, removeLoadingScreen);
        var png:PNGEncoder = new PNGEncoder();
        var iba:ByteArray = png.encode(bmpd);
        fr.save(iba, "export.png");   
    Unfortunately sticking the slow code into callLater() doesn't work because then the FileReference() can't be created.
    Any ideas?
    Cheers

    Thanks for the reply. What I've ended up with is quite strange:
    private function saveBitmap(event:ContextMenuEvent):void
        loadingScreen.visible = true;
        loadingScreen.appLoadingText.text = "Preparing bitmap...";
        <point a>
        addChild(loadingScreen);
        validateNow();
        <point b>
        trace("Fired!");
    private function prepareBitmap(event:FlexEvent):void
        trace("Fired beta!");
        removeEventListener(FlexEvent.UPDATE_COMPLETE, prepareBitmap);
        var bmpd:BitmapData = new BitmapData(canv.width, canv.height);
        bmpd.draw(canv);
        var fr:FileReference = new FileReference();
        fr.addEventListener(Event.COMPLETE, removeLoadingScreen);
        fr.addEventListener(Event.CANCEL, removeLoadingScreen);
        var png:PNGEncoder = new PNGEncoder();
        var iba:ByteArray = png.encode(bmpd);
        fr.save(iba, "export.png");   
    If I put addEventListener(FlexEvent.UPDATE_COMPLETE, prepareBitmap); at point a, then I get "Fired beta" then "Fired" (this makes sense I think, since the validateNow() will block until the UPDATE_COMPLETE event is finished) with no loading screen.
    If I put it the listener at point b then "Fired" is first and the loading screen appears, followed by a small (5 sec?) delay before "Fired Beta" is printed and the application dies from "Error: Error #2176: Certain actions, such as those that display a pop-up window, may only be invoked upon user interaction, for example by a mouse click or button press.".

  • Handling large number of waves in Campaign Canvas

    Hi All,
    I want to bounce off some ideas around create multi wave campaigns.
    We have few campaigns that have more than 15 waves. When we try to build these in Campaign Canvas, we are not able to accommodate all waves in the same Campaign, especially because there is some Opt and other processing between waves. For example, the total number of waves are split across 3 campaign canvas, with contacts moving from the first campaign to second and then to third.
    This is done because the campaign canvas does not allow us to keep scrolling vertically or horizontally.
    Is there a better way of handling this?
    Aditya

    Aditya,
    Your best option is to split these across multiple canvases.  I have worked with customers that use the individual campaign in Eloqua as the 'treatment' and, using a campaign hierarchy in their CRM, roll up the results. (hopefully Eloqua puts campaign hierarchies back into the application to allow for this to be done within Eloqua again)
    I have done nurture programs like this with an 'Learn/Solve', 'Compare', and 'Purchase' campaign.  Each with 5-7 emails and corresponding landing pages. 
    The canvas gets unwieldy at more than 10 emails with the corresponding wait and decision points.
    This also makes reporting a bit easier for reporting on nurture stage.
    Nathan

  • Dropping image on canvas causes image to jump.

    When I drop an image on a canvas in AIR the image "jumps" a few pixels to several from the current mouse location.
    So if the mouse is at location (12, 12) and I drop the image it may appear at (10, 14), or (15, 20), or whatever. It doesn't appear to be a consistent offset like I would expect if this were caused by using global to local mouse position thing (but I'm not ruling that out anyway).
    Secondly, when I then drag to move the image on the canvas the drag proxy will again jump many pixels from the mouse cursor.
    Here is my mouse down handler:
                private function dragBegin(event:MouseEvent):void
                      var dragInitiator:Image = Image(event.currentTarget);
                    var ds:DragSource = new DragSource();
                    ds.addData(dragInitiator, "img");   
                    var dragProxy:Image = new Image();
                    dragProxy.source = event.currentTarget.source;
                    DragManager.doDrag(dragInitiator, ds, event, dragProxy);
    And the drop handler:
            private function dragDropHandler(event:DragEvent):void
                   var image:Image = Image(event.dragSource.dataForFormat("img"));
                   image.x = event.localX;
                   image.y = event.localY;
                   UIComponent(event.currentTarget).addChild(device);
    What am I doing wrong that is causing this jumping?
    Thanks,
    -Mark

    Hi,
    I think the only way to do this is to use a jsp with a servlet, where the servlet would create the image and send it over as a stream, while the jsp would call on the link of the servlet and display that image using the HTML <IMG> tag.
    So, if you have a servlet, lets call it PictureServlet.
    This is what you would do in your servet:
    // create that image and send it over from the doPost/doGet method of the servlet
    public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("image/jpg"); // set the stream to be a JPEG image
    ServletOutputStream sos = response.getOutputStream(); // create the output stream
    BufferedImage bImg = createImage(); // this is where you write on your image using canvas and return it as a Bufferedimage
    ImageIO.write(bImg,"JPG",sos); // write the image to the stream as JPEG
    sos.close(); // close the output stream
    public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
            doPost(request, response);
        } This is how you would get that image and display it in your JSP.
    <img src="../servlet/PictureServlet" name="pic">Note the path might be different, depending on the hierarchy of where jsps and servlets are stored on the server.
    I hope this helps,
    Val.

  • Why is the CANVAS so shy all of all sudden?

    Suddenly, when I want to slide the Canvas around to enlarge it full screen, it hides behind the Viewer or the Browser or the Timeline. Brand new phenomena. Any shortcuts for making the Canvas fullscreen and back? And why this new curtailment? - Thanks!
    G5   Mac OS X (10.4.5)   fcp 5.1.2

    The Viewer, Browser, Canvas and Timeline are all different windows that have their own visual hierarchy. If you resize the canvas and then select the viewer and they overlap, the viewer will cover the canvas. Quickest way to get back to your canvas if you lose it is using exposé.
    To preview your movie turn on Digital Cinema Display. Go to the toolbar ----> View ----> Video Playback ---> and Select Digital Cinema Display Playback.
    Now use command + F12 to toggle between cinema display and your standard editing view. If you're using a notebook you'll have to reclaim your F1-F12 keys in system preferences.
    Other hotkeys for navigating between your windows while editing:
    Command + 1 = Viewer
    Command + 2 = Canvas
    Command + 3 = Timeline
    Command + 4 = Browser
    Option + H will give you a list of all the hotkeys.
    Good luck.
    15" MBP, 2.16ghz Core 2 Duo, 2 GB ram   Mac OS X (10.4.10)  

  • Saving images with BitmapData

    I am saving a screen shot of my application using the
    following code...
    var bd : BitmapData = new BitmapData( target.width,
    target.height );
    bd.draw( target, new Matrix());
    to get the contents of the target (a UIComponent) into the
    BitmapData object, which I then convert to a PNG, etc, etc. My
    question revolves around the fact that when I do this, the
    resulting image only shows the "viewable" portion of the target
    component. As an example, I have a Canvas that is nested in another
    Canvas in such a way that there are scrollbars. When I do the
    saving, rather than getting the entire size of the inner Canvas, I
    only get the viewable size of the outer Canvas.
    My question is, how do I (or can I) get the entire content of
    the inner Canvas and not just what is viewable/
    Thanks

    In Keynote you can add your image to a slide, move the bottom of it upwards, select reflection, adjust the background color and opacity to get the effect you want and then export as a JPEG.
    If the Keynote slide size doesn't suit your photo size you can do as above, take a snapshot and crop it.

  • New to FLEX, Writing text on a BitmapData object

    Hello,
    it has been quite some time since I coded in actionscript, I am a java  developer who is struggling to learn some game oriented actionscript.
    The problem:
    I have a double buffering schema using a canvas declared on the MXML  file and a bitmapdata on a class as the back buffer. the enterframe  method paints the bitmapdata into the canvas thus updating the screen.
    I know I can add graphics to the bitmapdata object but I want to write  some text into the bitmapdata. How can I do that?

    You can convert Text into bitmapdata and write it.

  • How to generate 300 DPI image from canvas using Imagesnapshot

    Hi all,
    I want to generate image from my canvas.
    I tried using bitmapdata and imagesnapshot.
    Bitmapdata has no property called DPI.
    Imagesnapshot allows to set DPI but it is not generating 300 dpi image.
    Any idea?

    You are in the Using iPhone forum. I will ask the hosts to move this to the iPad forum. However, I'm not aware of any setting change you can make to the cameras in the iPad or iPhone.

  • Subclassing Canvas

    Hi everyone!
    I'm trying to subclass the Canvas class to create a double buffered rectangular area where to draw some image sequence.
    This code doesn't work:
    public class ImageCanvas extends Canvas {
    ImageCanvas () {
    this.createBufferStrategy(2);
    and I get a "Component must have a valid peer" exception. I tried to add a call to addNotify() before createBufferStrategy(2) but I get a nullPointerException instead.
    I'm not a skilled java programmer, so there must be a mistake! Could someone show it to me?
    Many many thanks!
    Zalexx

    I believe that your ImageCanvas must be displayable. See Component.isDisplayable for details.
    You may have to supply a Window or a Frame as a parameter to the constructor, or delay setting the buffer strategy until your containment hierarchy is set up.

Maybe you are looking for