Clearing BufferedImage

Discussion in 'Java' started by Will Clark, Nov 27, 2003.

  1. Will Clark

    Will Clark Guest

    Is there any way of clearing a BufferedImage object? By which I mean
    returning it to completely transparent, as when created using:

    new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB)

    I must have missed something really obvious, because there must be a simple
    way to do it, and not by creating a new BufferedImage every time the image
    needs redrawing...

    Obviously, if it were not a transparent background, I could just use a
    Graphics2D.fill(...) to fill the background in, say, white... but
    unsurprisingly using this method with a "transparent" color doesn't work :eek:(

    What I'd like is a BufferedImage.clear() function!

    Any help would be great!

    Cheers :eek:)

    Will


    P.S. I've also come across the following code fragment, which I haven't yet
    tried to test:

    // Clear image with transparent alpha by drawing a rectangle
    g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
    g2D.fill(new Rectangle(0, 0, w, h));

    Is this the best way? Or is there a better way?
    Will Clark, Nov 27, 2003
    #1
    1. Advertising

  2. Will Clark

    Chris Smith Guest

    Will Clark wrote:
    > Is there any way of clearing a BufferedImage object? By which I mean
    > returning it to completely transparent, as when created using:
    >
    > new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB)
    >
    > I must have missed something really obvious, because there must be a simple
    > way to do it, and not by creating a new BufferedImage every time the image
    > needs redrawing...
    >
    > Obviously, if it were not a transparent background, I could just use a
    > Graphics2D.fill(...) to fill the background in, say, white... but
    > unsurprisingly using this method with a "transparent" color doesn't work :eek:(
    >
    > What I'd like is a BufferedImage.clear() function!


    Not ideal (and not tested), but I think either of the
    BufferedImage.setRGB methods could be used to accomplish this.

    --
    www.designacourse.com
    The Easiest Way to Train Anyone... Anywhere.

    Chris Smith - Lead Software Developer/Technical Trainer
    MindIQ Corporation
    Chris Smith, Nov 28, 2003
    #2
    1. Advertising

  3. Will Clark

    Will Clark Guest

    "Chris Smith" <> wrote:
    > Not ideal (and not tested), but I think either of the
    > BufferedImage.setRGB methods could be used to accomplish this.


    No, I don't think that's not really a possibility...

    setRGB(int x, int y, int rgb)

    would require each pixel set in a big loop, while

    setRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int
    scansize)

    would be marginally better but would require a huge array of int[] to be set
    up each time I want to clear it.

    Actually, it would only need to be set up once, and then used each time...
    but it still wastes a lot of memory... and Java Image objects waste enough
    as it is!

    Hmm, difficult, this one :eek:)

    Well, I'll try it anyway - it may be work out better than the other
    approaches I've got!

    Thanks!

    Will
    Will Clark, Nov 28, 2003
    #3
  4. Will Clark wrote:
    > Is there any way of clearing a BufferedImage object? By which I mean
    > returning it to completely transparent, as when created using:
    >
    > new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB)
    >
    > I must have missed something really obvious, because there must be a simple
    > way to do it, and not by creating a new BufferedImage every time the image
    > needs redrawing...
    >
    > Obviously, if it were not a transparent background, I could just use a
    > Graphics2D.fill(...) to fill the background in, say, white... but
    > unsurprisingly using this method with a "transparent" color doesn't work :eek:(
    >
    > What I'd like is a BufferedImage.clear() function!
    >
    > Any help would be great!
    >
    > Cheers :eek:)
    >
    > Will
    >
    >
    > P.S. I've also come across the following code fragment, which I haven't yet
    > tried to test:
    >
    > // Clear image with transparent alpha by drawing a rectangle
    > g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
    > g2D.fill(new Rectangle(0, 0, w, h));
    >
    > Is this the best way? Or is there a better way?
    >


    It's not exactly clear what you are really trying to do. If you just
    want to see only the background, why not just draw the background and
    not draw the BufferedImage on top? If you want to change the alpha of
    the image to partially show the background you can use the getRGB() and
    setRGB() as Chris already said or you can use the
    Graphics2D.setComposite() to draw with an arbitrary alpha value.

    float alphaLevel;

    paintComponent(Graphics g) {
    Graphics2D g2D = (Graphics2D)g;
    Composite oldcomp = g2D.getComposite();
    // draw the background
    Composite newcomp = AlphaComposite.getInstance(
    AlphaComposite.SRC_OVER,alphaLevel);
    g2D.setComposite(newcomp);
    g2D.drawImage(image,0,0,null);
    g2D.setComposite(oldcomp);
    }

    This still requires that you draw the background though. If you are
    going to make the BufferedImage completely transparent there is no
    reason to go through all this hassle.

    --

    Knute Johnson
    email s/nospam/knute/
    Molon labe...
    Knute Johnson, Nov 28, 2003
    #4
  5. Will Clark

    Will Clark Guest

    Knute Johnson wrote:
    > It's not exactly clear what you are really trying to do...


    Ah, sorry! What I have is effectively an "animated" image which is
    transparent. But it is not a repeating sequence of "frames", therefore
    cannot be handled by multiple BufferedImage objects.

    On the other hand, I cannot just use the paint method and draw directly on
    top of the component beneath as the BufferedImage drawing routine is
    complicated and slow - hence buffered! To do it this way would cause the
    background to "freeze".

    Hence, I need a way of clearing the BufferedImage object, firstly, so that I
    don't need to create more than one, and secondly, because each "frame" may
    well be transparent in a different place to the last frame.

    Cheers,

    Will
    Will Clark, Nov 29, 2003
    #5
  6. Will Clark wrote:
    > Knute Johnson wrote:
    >
    >>It's not exactly clear what you are really trying to do...

    >
    >
    > Ah, sorry! What I have is effectively an "animated" image which is
    > transparent. But it is not a repeating sequence of "frames", therefore
    > cannot be handled by multiple BufferedImage objects.
    >
    > On the other hand, I cannot just use the paint method and draw directly on
    > top of the component beneath as the BufferedImage drawing routine is
    > complicated and slow - hence buffered! To do it this way would cause the
    > background to "freeze".
    >
    > Hence, I need a way of clearing the BufferedImage object, firstly, so that I
    > don't need to create more than one, and secondly, because each "frame" may
    > well be transparent in a different place to the last frame.
    >
    > Cheers,
    >
    > Will
    >


    It's still not clear what you are doing. Are you displaying this image
    in a Swing component? Are you sure it isn't buffered? Swing components
    are buffered by default and it does take the flicker out of redraws. In
    any case you can't make it go transparent without redrawing it. The
    only way to improve rendering speed is to render less. You can improve
    the actual draw to the screen with VolatileImage (it really flies under
    Windows).

    --

    Knute Johnson
    email s/nospam/knute/
    Molon labe...
    Knute Johnson, Nov 29, 2003
    #6
  7. Will Clark

    Will Clark Guest

    "Knute Johnson" wrote:
    > It's still not clear what you are doing.


    Ok, imagine it like this... the BufferedImage is effectively a slow
    animation, say a video clip running at approximately 5 frames a second (but
    even this is too simplistic because it gives the idea of pre-rendered
    scenes, which isn't the case: scenes are rendered on the fly), parts of
    which are transparent, and overlays another (simpler) animation which runs
    at around 25 frames a second.

    If the slow animation is rendered directly on top of the fast animation then
    the whole animation becomes jerky as the speed at which the slow animation
    can be rendered is too low - hence the BufferedImage: the slow animation
    frame is rendered to the BufferedImage and then this can be rendered on top
    of the fast animation quickly, solving the problem - and this works
    brilliantly! It doesn't matter how long it takes for the top animation to
    render, because the BufferedImage object for the previous frame is painted
    on top of the bottom animation until the rendering of the next one is
    completed.

    The only problem is that of memory consumption: how best to use the
    BufferedImage object - which needs to be recreated every frame. Hence the
    question, can it be cleared!?

    Its really nothing to do with Swing or any other java Component api, simply
    a case of animation rendering. Similarily, VolatileImage doesn't seem (on
    first glance) to be the answer, but I will research it further.

    But does it make more sense now? :eek:)

    Cheers for your comments though.

    Will
    Will Clark, Dec 2, 2003
    #7
  8. Will Clark wrote:
    > "Knute Johnson" wrote:
    >
    >>It's still not clear what you are doing.

    >
    >
    > Ok, imagine it like this... the BufferedImage is effectively a slow
    > animation, say a video clip running at approximately 5 frames a second (but
    > even this is too simplistic because it gives the idea of pre-rendered
    > scenes, which isn't the case: scenes are rendered on the fly), parts of
    > which are transparent, and overlays another (simpler) animation which runs
    > at around 25 frames a second.
    >
    > If the slow animation is rendered directly on top of the fast animation then
    > the whole animation becomes jerky as the speed at which the slow animation
    > can be rendered is too low - hence the BufferedImage: the slow animation
    > frame is rendered to the BufferedImage and then this can be rendered on top
    > of the fast animation quickly, solving the problem - and this works
    > brilliantly! It doesn't matter how long it takes for the top animation to
    > render, because the BufferedImage object for the previous frame is painted
    > on top of the bottom animation until the rendering of the next one is
    > completed.
    >
    > The only problem is that of memory consumption: how best to use the
    > BufferedImage object - which needs to be recreated every frame. Hence the
    > question, can it be cleared!?
    >
    > Its really nothing to do with Swing or any other java Component api, simply
    > a case of animation rendering. Similarily, VolatileImage doesn't seem (on
    > first glance) to be the answer, but I will research it further.
    >
    > But does it make more sense now? :eek:)
    >
    > Cheers for your comments though.
    >
    > Will


    Sorry about the slow reply, I've been out of town the last week.

    I think I understand what you are trying to do now. If you can
    synchronize your rendering between the slow and the fast animation to
    some ratio then I would render all the data at one time. Change the
    fast animation every frame and the slow every 5 (or whatever ratio you
    want) frames. This would probably be faster than rendering to multiple
    components too.

    The reason I think this is better than using a transparent BufferedImage
    is that you will have to effectively do the same thing. And that is
    draw your underlying animation, render to the BufferedImage and then
    draw it over the backgroun. You will have to double buffer it too so
    that you don't get background/foreground flicker.

    --

    Knute Johnson
    email s/nospam/knute/
    Molon labe...
    Knute Johnson, Dec 7, 2003
    #8
  9. Will Clark

    Will Clark Guest

    Knute Johnson wrote:
    > Sorry about the slow reply, I've been out of town the last week.


    Don't worry! :eek:)


    I think you're right: I think that probably is the best way to do it.

    Thank you for all your help and perseverance!

    Will
    Will Clark, Dec 9, 2003
    #9
  10. Will Clark

    Mike Guest

    "Will Clark" <> wrote in message news:<bq5cok$o7i$>...

    In my case, I found that I needed to control a lot of pixels directly,
    so I created an external JNI assembler library to allow me to
    *quickly* change pixels.


    > Is there any way of clearing a BufferedImage object? By which I mean
    > returning it to completely transparent, as when created using:
    >
    > new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB)
    >
    > I must have missed something really obvious, because there must be a simple
    > way to do it, and not by creating a new BufferedImage every time the image
    > needs redrawing...
    >
    > Obviously, if it were not a transparent background, I could just use a
    > Graphics2D.fill(...) to fill the background in, say, white... but
    > unsurprisingly using this method with a "transparent" color doesn't work :eek:(
    >
    > What I'd like is a BufferedImage.clear() function!
    >
    > Any help would be great!
    >
    > Cheers :eek:)
    >
    > Will
    >
    >
    > P.S. I've also come across the following code fragment, which I haven't yet
    > tried to test:
    >
    > // Clear image with transparent alpha by drawing a rectangle
    > g2D.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
    > g2D.fill(new Rectangle(0, 0, w, h));
    >
    > Is this the best way? Or is there a better way?
    Mike, Dec 10, 2003
    #10
  11. Will Clark

    Will Clark Guest

    "Mike" wrote:
    > In my case, I found that I needed to control a lot of pixels directly,
    > so I created an external JNI assembler library to allow me to
    > *quickly* change pixels.


    Hmm, that may be a little overkill for what I have in mind, but it may be
    helpful. I don't suppose you'd have the source code for that and would be
    willing to part with it?

    But don't worry about it! :eek:)

    Will
    Will Clark, Dec 10, 2003
    #11
  12. Will Clark

    bluescales

    Joined:
    Nov 20, 2010
    Messages:
    1
    Try this :)


    Code:
    BufferedImage buf = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    
    Graphics2D g = buf.createGraphics();
    
    g.setComposite(AlphaComposite.Src);
    
    g.setColor(new Color(0, 0, 0, 0));
    
    g.fillRect(0, 0, width, height);
    
    g.dispose();
    bluescales, Nov 20, 2010
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Peter Szymanski
    Replies:
    0
    Views:
    858
    Peter Szymanski
    Jul 9, 2003
  2. Eel

    Copying BufferedImage

    Eel, Jul 9, 2003, in forum: Java
    Replies:
    2
    Views:
    6,971
  3. hz010c1877

    Read PPM images as BufferedImage

    hz010c1877, Aug 14, 2003, in forum: Java
    Replies:
    1
    Views:
    6,901
    John C. Bollinger
    Aug 14, 2003
  4. Morten Nørgaard
    Replies:
    0
    Views:
    3,432
    Morten Nørgaard
    Aug 29, 2003
  5. Mike Westerfield

    Transparent BufferedImage

    Mike Westerfield, Nov 1, 2003, in forum: Java
    Replies:
    1
    Views:
    4,695
    Andrew Thompson
    Nov 1, 2003
Loading...

Share This Page