Java-获取JPanel的图像
我正在写一个程序,我在Java-获取JPanel的图像,java,swing,jpanel,bufferedimage,Java,Swing,Jpanel,Bufferedimage,我正在写一个程序,我在JPanel上画画。如何获得绘制在JPanel上的图像? 我尝试了这段代码,但得到的只是一张背景颜色为我的JPanel的空白图像。 buffereImage不包含我的面板上绘制的内容 private BufferedImage createImage(JPanel panel) { int w = panel.getWidth(); int h = panel.getHeight(); BufferedImag
JPanel
上画画。如何获得绘制在JPanel
上的图像?
我尝试了这段代码,但得到的只是一张背景颜色为我的JPanel
的空白图像。
buffereImage
不包含我的面板上绘制的内容
private BufferedImage createImage(JPanel panel) {
int w = panel.getWidth();
int h = panel.getHeight();
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
panel.paint(g);
return bi;
}
我做错了什么?这里有一个SSCCE说明了它的工作原理。一个常见的错误是将null
传递为drawImage
方法的ImageObserver
,因为图像的加载是异步的
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestPrint {
protected static void initUI() throws MalformedURLException {
final ImageIcon image = new ImageIcon(new URL("http://www.travelblog.org/Wallpaper/pix/tb_fiji_sunset_wallpaper.jpg"));
JPanel panel = new JPanel() {
@Override
protected void paintComponent(java.awt.Graphics g) {
super.paintComponent(g);
g.drawImage(image.getImage(), 0, 0, this);
};
};
panel.setPreferredSize(new Dimension(image.getIconWidth(), image.getIconHeight()));
panel.setSize(panel.getPreferredSize());
BufferedImage bi = new BufferedImage(panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
panel.print(g);
g.dispose();
try {
ImageIO.write(bi, "png", new File("test.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
initUI();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
你的代码对我有用
下面是一个简单的例子。调整框架大小,以查看面板更改大小和图像移动
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
JPanel panel = new JPanel();
panel.setBackground(Color.BLUE);
JLabel label = new JLabel("Image");
label.setForeground(Color.RED);
panel.add(label);
frame.add(panel, BorderLayout.NORTH);
frame.pack();
JLabel image = new JLabel(new ImageIcon(createImage(panel)));
frame.add(image, BorderLayout.SOUTH);
frame.pack();
label.setText("Original");
frame.setVisible(true);
}
private static BufferedImage createImage(JPanel panel) {
int w = panel.getWidth();
int h = panel.getHeight();
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bi.createGraphics();
panel.paint(g);
return bi;
}
所以你的问题一定在别处。在创建面板映像时,请确保面板的大小为正。下面是一个可以添加到任何Java 2/JDK 1.2应用程序的快速示例方法。只需传入要快照的组件和要保存到其中的文件名
public void saveComponentAsJPEG(Component myComponent, String filename) {
Dimension size = myComponent.getSize();
BufferedImage myImage = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = myImage.createGraphics();
myComponent.paint(g2);
try {
OutputStream out = new FileOutputStream(filename);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(myImage);
out.close();
} catch (Exception e) {
System.out.println(e);
}
}
这种方法用途广泛。它可以用来拍摄各种Java应用程序组件的快照。但是,请务必预先警告,您使用com.sun.image.codec.jpeg会对代码的可移植性造成一定风险
编辑:
我测试了代码以确保一切正常:
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.OutputStream;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ScreenCapture extends JFrame {
public ScreenCapture() {
createAndShowUI();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
ScreenCapture screenCapture = new ScreenCapture();
}
});
}
private void createAndShowUI() {
setTitle("Test Screen Capture");
setSize(300, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
getContentPane().add(new DrawingPanel());
setVisible(true);
saveComponentAsJPEG(this, "C:/test.jpg");
}
public void saveComponentAsJPEG(Component myComponent, String filename) {
Dimension size = myComponent.getSize();
BufferedImage myImage = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = myImage.createGraphics();
myComponent.paint(g2);
try {
OutputStream out = new FileOutputStream(filename);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(myImage);
out.close();
} catch (Exception e) {
System.out.println(e);
}
}
class DrawingPanel extends JPanel {
public DrawingPanel() {
setDoubleBuffered(true);
}
@Override
public void paintComponent(Graphics grphcs) {
super.paintComponents(grphcs);
Graphics2D g2d = (Graphics2D) grphcs;
RenderingHints rhints = g2d.getRenderingHints();
boolean antialiasOn = rhints.containsValue(RenderingHints.VALUE_ANTIALIAS_ON);
if (!antialiasOn) {
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
}
Shape circle = new Ellipse2D.Float(100.0f, 100.0f, 100.0f, 100.0f);
g2d.setColor(Color.RED);
g2d.draw(circle);
g2d.fill(circle);
}
}
}
@sijoune尝试我上面发布的代码,看看与您的代码的差异,找出您的问题。我尝试了,同样的事情发生了。我不明白。我必须做一些其他的错误,但我找不到。检查我的编辑,也许然后发布的代码可能会出现问题,我不知道如何,虽然,因为你可以看到,一旦你通过一个组件和文件名的方法,它做其余的。考虑张贴如何绘制您的图像。你使用graphics.drawImage吗?如果是,ImageObserver参数是什么?