The javadoc said:
For efficiency, programmers should call dispose when finished using a Graphics object only if it was created directly from a component or another Graphics object.
So in the following code, should I call graphics.dispose()
before returning?
Or, can I?
{ ...
BufferedImage result = new BufferedImage(toWidth, toHeight, BufferedImage.TYPE_INT_RGB);
java.awt.Graphics graphics=result.getGraphics();
graphics.drawImage(im.getScaledInstance(toWidth, toHeight, java.awt.Image.SCALE_SMOOTH), 0, 0, null);
return result;
}
The BufferedImage result
is returned and used elsewhere.
The Graphics
object can be disposed and should be disposed.
The getGraphics
call of BufferedImage
internally delegates to createGraphics
, so there is no difference. The createGraphics
call eventually delegates to the respective GraphicsEnvironment
implementation, where (for the SunGraphicsEnvironment
) it creates a new
instance of a SunGraphics2D
.
Finally, the dispose
method of SunGraphics2D
says the following:
/**
* This object has no resources to dispose of per se, but the
* doc comments for the base method in java.awt.Graphics imply
* that this object will not be useable after it is disposed.
* So, we sabotage the object to prevent further use to prevent
* developers from relying on behavior that may not work on
* other, less forgiving, VMs that really need to dispose of
* resources.
*/
public void dispose() {
surfaceData = NullSurfaceData.theInstance;
invalidatePipe();
}
which also gives a justification of why dispose
indeed should be called (even if it is not strictly necessary in the default implementations)
public class Main{
public static void main(String[] args) {
BufferedImage img = get();
Graphics g = img.getGraphics();
//g.drawOval(5, 5, 5, 5); //this statement will work (you'll see the cirle)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ImageIO.write( img, "jpg", baos );
baos.flush();
byte[] imageInByte = baos.toByteArray();
baos.close();
Files.write(Paths.get("test2.png"), imageInByte);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static BufferedImage get(){
BufferedImage res = new BufferedImage(50, 50, BufferedImage.TYPE_INT_ARGB);
Graphics g = res.getGraphics();
g.drawRect(0, 0, 20, 20);
g.dispose();
g.drawOval(5, 5, 5, 5); //this statement won't work, you'll only see the rect
return res;
}
}
As you can see, you can savely (and should) dispose the graphics
in your method.
You can't use the graphics object in the method afterwards, so when you run the code, there won't be a circle in the picture. But if you comment out g.drawOval(5,5,5,5)
in the method, but comment in the same statement in the main
-Method, you will see a circle. So you can use it afterwards.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With