将 java 小程序的图形内容保存到图像文件无法正常工作
Save graphical content of java applet to image file doesn't work properly
我正在尝试将 Java 小程序的图形内容自动保存到图像文件中,但我遇到了文件无法正确保存的问题。我的完整 Java 代码是:
package nl.mark.SierpinskiCarpet;
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class SierpinskiCarpet extends Applet {
private Graphics g = null;
private int d0 = 729; // 3^6
private BufferedImage bufferedImage;
private final GraphicsConfiguration gConfig = GraphicsEnvironment
.getLocalGraphicsEnvironment().getDefaultScreenDevice()
.getDefaultConfiguration();
public void init() {
g = getGraphics();
resize(d0, d0);
}
public void paint(Graphics g) {
drawSierpinskiCarpet(0, 0, getWidth(), getHeight());
storeImage();
}
public void storeImage() {
BufferedImage image = create(d0, d0, true);
Graphics2D g = image.createGraphics();
// you can disable this if you don't want smooth graphics
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
drawSierpinskiCarpet(0, 0, getWidth(), getHeight());
g.dispose();
try {
ImageIO.write(image, "png", new File(
"N:\Tapijt van Sierpiński\image.png"));
} catch (IOException e) {
}
}
private void drawSierpinskiCarpet(int xOL, int yOL, int breedte, int hoogte) {
if (breedte > 2 && hoogte > 2) {
int b = breedte / 3;
int h = hoogte / 3;
g.fillRect(xOL + b, yOL + h, b, h);
for (int k = 0; k < 9; k++)
if (k != 4) {
int i = k / 3;
int j = k % 3;
drawSierpinskiCarpet(xOL + i * b, yOL + j * h, b, h);
}
}
}
private BufferedImage create(final int width, final int height,
final boolean alpha) {
BufferedImage buffer = gConfig.createCompatibleImage(width, height,
alpha ? Transparency.TRANSLUCENT : Transparency.OPAQUE);
return buffer;
}
}
小程序中显示的图像 (Sierpinski Carpet) 是正确的,但创建的文件只是一张空白图像。要绘制图案,调用方法 drawSierpinskiCarpet() 并在执行函数后调用函数 storeImage() 来保存图像,但会在输出目录中生成空白图像文件。图片保存过程中出现什么问题?
您应该 永远 在组件上调用 getGraphics
(并且 永远 存储一个 Graphics
对象作为参数给 paint
左右)。
(而且你永远不应该默默地吞下一个 IOException
。至少添加一些 e.printStackTrace()
以知道什么时候出了问题)。
这里的问题是你从图像中获取了Graphics
对象,但是对drawSierpinskiCarpet
的调用仍然使用了Graphics g
,它作为字段存储在class.
在这种情况下,一个简单的解决方案是通过递归调用将 Graphics
对象作为参数传递:
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class SierpinskiCarpet extends Applet
{
private int d0 = 729; // 3^6
private BufferedImage bufferedImage;
private final GraphicsConfiguration gConfig = GraphicsEnvironment
.getLocalGraphicsEnvironment().getDefaultScreenDevice()
.getDefaultConfiguration();
public void init()
{
resize(d0, d0);
}
public void paint(Graphics g)
{
drawSierpinskiCarpet(g, 0, 0, getWidth(), getHeight());
storeImage();
}
public void storeImage()
{
BufferedImage image = create(d0, d0, true);
Graphics2D g = image.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
drawSierpinskiCarpet(g, 0, 0, getWidth(), getHeight());
g.dispose();
try
{
ImageIO.write(image, "png", new File(
"C:\Users\User\Desktop\sierpinskiImage.png"));
}
catch (IOException e)
{
e.printStackTrace();
}
}
private void drawSierpinskiCarpet(Graphics g, int xOL, int yOL,
int breedte, int hoogte)
{
if (breedte > 2 && hoogte > 2)
{
int b = breedte / 3;
int h = hoogte / 3;
g.fillRect(xOL + b, yOL + h, b, h);
for (int k = 0; k < 9; k++)
if (k != 4)
{
int i = k / 3;
int j = k % 3;
drawSierpinskiCarpet(g, xOL + i * b, yOL + j * h, b, h);
}
}
}
private BufferedImage create(final int width, final int height,
final boolean alpha)
{
BufferedImage buffer =
gConfig.createCompatibleImage(width, height, alpha
? Transparency.TRANSLUCENT : Transparency.OPAQUE);
return buffer;
}
}
我正在尝试将 Java 小程序的图形内容自动保存到图像文件中,但我遇到了文件无法正确保存的问题。我的完整 Java 代码是:
package nl.mark.SierpinskiCarpet;
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class SierpinskiCarpet extends Applet {
private Graphics g = null;
private int d0 = 729; // 3^6
private BufferedImage bufferedImage;
private final GraphicsConfiguration gConfig = GraphicsEnvironment
.getLocalGraphicsEnvironment().getDefaultScreenDevice()
.getDefaultConfiguration();
public void init() {
g = getGraphics();
resize(d0, d0);
}
public void paint(Graphics g) {
drawSierpinskiCarpet(0, 0, getWidth(), getHeight());
storeImage();
}
public void storeImage() {
BufferedImage image = create(d0, d0, true);
Graphics2D g = image.createGraphics();
// you can disable this if you don't want smooth graphics
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
drawSierpinskiCarpet(0, 0, getWidth(), getHeight());
g.dispose();
try {
ImageIO.write(image, "png", new File(
"N:\Tapijt van Sierpiński\image.png"));
} catch (IOException e) {
}
}
private void drawSierpinskiCarpet(int xOL, int yOL, int breedte, int hoogte) {
if (breedte > 2 && hoogte > 2) {
int b = breedte / 3;
int h = hoogte / 3;
g.fillRect(xOL + b, yOL + h, b, h);
for (int k = 0; k < 9; k++)
if (k != 4) {
int i = k / 3;
int j = k % 3;
drawSierpinskiCarpet(xOL + i * b, yOL + j * h, b, h);
}
}
}
private BufferedImage create(final int width, final int height,
final boolean alpha) {
BufferedImage buffer = gConfig.createCompatibleImage(width, height,
alpha ? Transparency.TRANSLUCENT : Transparency.OPAQUE);
return buffer;
}
}
小程序中显示的图像 (Sierpinski Carpet) 是正确的,但创建的文件只是一张空白图像。要绘制图案,调用方法 drawSierpinskiCarpet() 并在执行函数后调用函数 storeImage() 来保存图像,但会在输出目录中生成空白图像文件。图片保存过程中出现什么问题?
您应该 永远 在组件上调用 getGraphics
(并且 永远 存储一个 Graphics
对象作为参数给 paint
左右)。
(而且你永远不应该默默地吞下一个 IOException
。至少添加一些 e.printStackTrace()
以知道什么时候出了问题)。
这里的问题是你从图像中获取了Graphics
对象,但是对drawSierpinskiCarpet
的调用仍然使用了Graphics g
,它作为字段存储在class.
在这种情况下,一个简单的解决方案是通过递归调用将 Graphics
对象作为参数传递:
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class SierpinskiCarpet extends Applet
{
private int d0 = 729; // 3^6
private BufferedImage bufferedImage;
private final GraphicsConfiguration gConfig = GraphicsEnvironment
.getLocalGraphicsEnvironment().getDefaultScreenDevice()
.getDefaultConfiguration();
public void init()
{
resize(d0, d0);
}
public void paint(Graphics g)
{
drawSierpinskiCarpet(g, 0, 0, getWidth(), getHeight());
storeImage();
}
public void storeImage()
{
BufferedImage image = create(d0, d0, true);
Graphics2D g = image.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
drawSierpinskiCarpet(g, 0, 0, getWidth(), getHeight());
g.dispose();
try
{
ImageIO.write(image, "png", new File(
"C:\Users\User\Desktop\sierpinskiImage.png"));
}
catch (IOException e)
{
e.printStackTrace();
}
}
private void drawSierpinskiCarpet(Graphics g, int xOL, int yOL,
int breedte, int hoogte)
{
if (breedte > 2 && hoogte > 2)
{
int b = breedte / 3;
int h = hoogte / 3;
g.fillRect(xOL + b, yOL + h, b, h);
for (int k = 0; k < 9; k++)
if (k != 4)
{
int i = k / 3;
int j = k % 3;
drawSierpinskiCarpet(g, xOL + i * b, yOL + j * h, b, h);
}
}
}
private BufferedImage create(final int width, final int height,
final boolean alpha)
{
BufferedImage buffer =
gConfig.createCompatibleImage(width, height, alpha
? Transparency.TRANSLUCENT : Transparency.OPAQUE);
return buffer;
}
}