Skip to main content

Drawing a rectangle ontop of an image, without redrawing the image?

4 replies [Last post]
samynix
Offline
Joined: 2010-04-17
Points: 0

How can i do this? Its wasted computer power to redraw the image each time the rectangle selection gets bigger/smaller. Here is the code:

Is there anyway to get the code looking like it should, with tabs and stuff when posting it here?

protected void paintComponent(Graphics g) {
super.paintComponent(g);
/*
* Draws the image in the center of the panel
* I dont want the image to be drawen everytime the rectangle is drawn
*/
if (image != null) {
if (image.getWidth()>getWidth() && image.getHeight()>getHeight()){
g.drawImage(image, 0,0, null);
}
else if (image.getWidth()>getWidth()){
g.drawImage(image,0,(getHeight()-image.getHeight())/2 , null);
}
else if (image.getHeight()>getHeight()){
g.drawImage(image,(getWidth()-image.getWidth())/2 ,0 , null);
}
else
g.drawImage(image, ((getWidth()-image.getWidth())/2), ((getHeight()-image.getHeight())/2), null);

/*
* This paints a rectangle while dragging the mouse over the picture
*/
if (rectSelection != null) {
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke (new BasicStroke(2));
g2d.setColor (Color.blue);
g2d.draw (rectSelection );
}
}
}

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
rtc1
Offline
Joined: 2010-05-09
Points: 0

Well, here are a couple of ideas if you really want to avoid redrawing the entire image:

1) Instead of drawing a rectangle using Color.BLUE, you might consider using an XOR drawing mode and simply re-draw the rectangle a second time (which should erase it) before drawing the next user selection rectangle. It's been awhile since I've used XOR in Java so I cannot offer you any specifics on this technique. I noticed that there is a Graphics.setXORMode() method which may be the way XOR drawing is done in Java 2D.

2) You could just draw the corresponding sub-rectangle of the image back onto the screen. This could be done in two ways: 1) draw the entire sub-rectangle which would be more costly than the second alternative, or 2) draw just the image pixels under the four sides/lines of your user selection rectangle. There is probably a Graphics.drawImage() method overload that allows you to draw only a sub-rectangle. Keep in mind that by using a stroke size of 2, the rectangle line thickness may not be exactly 2 pixels in size (I'm not sure that the stroke width is guaranteed to equate precisely to pixels, especially if you specify a decimal portion such as 1.5f). Also, if you have anti-aliasing turned on, figuring out which pixels have been changed due to a drawing operation may be more challenging.

Method (1) is by far the most common approach when drawing user selection "rubber band rectangles" and is less complex and probably better performing than method (2).

Regarding your question of getting code to appear properly (with indentation), I'm new to this site, but other sites sometimes have tags that address this problem. You might look around for documentation on this on this website.

jtheory
Offline
Joined: 2004-10-17
Points: 0

Don't use the XOR solution unless you have some control over the Java versions your users will have installed -- there was a series of releases starting in 2007 where XOR drawing was very broken, and many people still have these versions installed. It looks like the fix came through in version 6u14 last year:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6635462

I remember this one vividly, because I had to make a lot of desperate & urgent code changes when the broken JRE shipped, ripping out XOR from all of my suddenly-unusable applets.

Otherwise -- right, simply rendering an image is not likely to be a performance hotspot, so don't complicate your code (and spend your time) unless you actually have a problem to fix. If you do decide to optimize (with some clever clipping, etc.) do before/after tests to see that your changes are actually saving you rendering time -- if not, roll back and keep looking for the problem elsewhere. :)

linuxhippy
Offline
Joined: 2004-01-07
Points: 0

> Don't use the XOR solution unless you have some
> control over the Java versions your users will have
> installed -- there was a series of releases starting
> in 2007 where XOR drawing was very broken, and many
> people still have these versions installed. It looks
> like the fix came through in version 6u14 last year:
>
> ttp://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6635
> 462

And even with 6u14 the bug fix is to completly turn off hardware acceleration as soon as a single XOR operation is executed - in order to avoid radbacks from video memory.

So re-drawing the image is really the preffered way of doing this.

- Clemens

Olivier Lefevre

Pasting an image onto the screen should be about the
most optimized and least wasteful operation of all possible
things you could do with a canvas (although perhaps more
or less so depending on the precise kind of image). I wouldn't
worry.

-- O.L.
--
To unsubscribe from the java2d-interest list, send email to:
java2d-interest-unsubscribe@java-mail-lists.kenai.com
Instructions will be mailed back to you.