patternjavaMinor
Drawing a bufferedimage into another
Viewed 0 times
bufferedimageintodrawinganother
Problem
For what I'm doing, I need to be able to draw a buffered image directly into a larger buffered image. I've searched around a little and still have failed to find a better way, but my current way is extremely inefficient and I would like a better way if it's possible. Any improvements onto this design would also be great, even if it's not a totally separate way.
This is the second biggest bottleneck on my program, so it really is important to be improved. It's called all the time, and is rather slow. Memory isn't an issue, so memory-using methods can be considered.
public static final void drawOntoBI(final BufferedImage on, final BufferedImage draw, final int x, final int y)
{
// Calls method instead of needing to call them every loop
final int width = draw.getWidth(), height = draw.getHeight(), onwidth = on.getWidth(), onheight = on.getHeight();
// Stores temporary variables so they wont be recalculated
int x3, y3;
// Goes through all of the pixels in the drawn image to copy them
for(int x2 = 0; x2 onwidth - 1 || x3 onheight - 1 || y3 < 1) break;
// Draws the pixel on the image where it needs to be from the x and y looped in the image
on.setRGB(x3, y3, draw.getRGB(x2, y2));
}
}
}This is the second biggest bottleneck on my program, so it really is important to be improved. It's called all the time, and is rather slow. Memory isn't an issue, so memory-using methods can be considered.
Solution
Java Native Solution
The solution Java offers for adding two BufferedImages should be faster than anything that you will program yourself:
Your Code
As I said, if you remove the unnecessary
You can also move the
If most of the time the smaller image does fit into the larger image, you can also remove the bounds check completely. Create two new methods. One for when the image fits - no bound checks necessary - and one for when it does not fit (here you obviously still need the check). Then in your main method, you check once if the image would fit and use the quicker method without bounds check. If it does not fit, you use the method with bounds check.
If the smaller image does not fit most of the time, you could also first crop the smaller image (if it does not fit), so that it does always fit. I doubt that it will be faster, but it is worth a try.
The solution Java offers for adding two BufferedImages should be faster than anything that you will program yourself:
/**
* prints the contents of buff2 on buff1 with the given opaque value.
*/
private void addImage(BufferedImage buff1, BufferedImage buff2,
float opaque, int x, int y) {
Graphics2D g2d = buff1.createGraphics();
g2d.setComposite(
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opaque));
g2d.drawImage(buff2, x, y, null);
g2d.dispose();
}Your Code
As I said, if you remove the unnecessary
x3 checks, you would at least save two comparisons for each loop of y2 (and those can really add up).You can also move the
onheight - 1 and onwidth - 1 computations outside the loop. If most of the time the smaller image does fit into the larger image, you can also remove the bounds check completely. Create two new methods. One for when the image fits - no bound checks necessary - and one for when it does not fit (here you obviously still need the check). Then in your main method, you check once if the image would fit and use the quicker method without bounds check. If it does not fit, you use the method with bounds check.
If the smaller image does not fit most of the time, you could also first crop the smaller image (if it does not fit), so that it does always fit. I doubt that it will be faster, but it is worth a try.
Code Snippets
/**
* prints the contents of buff2 on buff1 with the given opaque value.
*/
private void addImage(BufferedImage buff1, BufferedImage buff2,
float opaque, int x, int y) {
Graphics2D g2d = buff1.createGraphics();
g2d.setComposite(
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opaque));
g2d.drawImage(buff2, x, y, null);
g2d.dispose();
}Context
StackExchange Code Review Q#58067, answer score: 4
Revisions (0)
No revisions yet.