我应该显式处理 Graphics 对象吗?
Should I explicitly dispose the Graphics object?
javadoc 说:
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.
所以在下面的代码中,我应该在返回之前调用graphics.dispose()
吗?
或者,我可以吗?
{ ...
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;
}
返回 BufferedImage result
并在别处使用。
因为 JavaDoc getGpahics()
方法转发到 createGraphics()
你应该在你的方法结束时处理 Graphics 对象。
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;
}
}
如您所见,您可以(并且应该)在您的方法中处理 graphics
。
后面的方法中不能使用图形对象,所以运行代码的时候,图片中不会出现圆圈。但是如果你在方法中注释掉了g.drawOval(5,5,5,5)
,但是在main
-Method中的同一条语句中注释掉了,就会看到一个圆圈。这样你以后就可以用了。
Graphics
对象可以被释放并且应该被释放。
BufferedImage
的getGraphics
调用内部委托给了createGraphics
,所以没有区别。 createGraphics
调用最终委托给相应的 GraphicsEnvironment
实现,其中(对于 SunGraphicsEnvironment
)它创建一个 new
实例SunGraphics2D
。
最后,SunGraphics2D
的 dispose
方法表示如下:
/**
* 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();
}
这也给出了 理由 为什么 dispose
确实 应该 被调用(即使它不是绝对必要的默认实现)
javadoc 说:
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.
所以在下面的代码中,我应该在返回之前调用graphics.dispose()
吗?
或者,我可以吗?
{ ...
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;
}
返回 BufferedImage result
并在别处使用。
因为 JavaDoc getGpahics()
方法转发到 createGraphics()
你应该在你的方法结束时处理 Graphics 对象。
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;
}
}
如您所见,您可以(并且应该)在您的方法中处理 graphics
。
后面的方法中不能使用图形对象,所以运行代码的时候,图片中不会出现圆圈。但是如果你在方法中注释掉了g.drawOval(5,5,5,5)
,但是在main
-Method中的同一条语句中注释掉了,就会看到一个圆圈。这样你以后就可以用了。
Graphics
对象可以被释放并且应该被释放。
BufferedImage
的getGraphics
调用内部委托给了createGraphics
,所以没有区别。 createGraphics
调用最终委托给相应的 GraphicsEnvironment
实现,其中(对于 SunGraphicsEnvironment
)它创建一个 new
实例SunGraphics2D
。
最后,SunGraphics2D
的 dispose
方法表示如下:
/**
* 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();
}
这也给出了 理由 为什么 dispose
确实 应该 被调用(即使它不是绝对必要的默认实现)