将JPanel保存为图像 [英] Saving JPanel as image

查看:97
本文介绍了将JPanel保存为图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个应用程序允许用户在图层中加载图像。用户可以在另一个图层上绘制一些图片并仅保存用户绘制的图像。这是我的代码:

I am developing an application allow user load an image in a layer. User can draw some picture on another layer and save only the image that user drawn.Here is my code:

import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.ImageIcon;
import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;

public class LayerDemo extends JApplet {

    private JLayeredPane mainLayer;

    private JPanel layer1;

    private JPanel layer2;

    private JLabel label;

    private ImageIcon imgIcon;


    /**
     * Create the applet.
     */
    public LayerDemo() {    
    }

    public void init() {
        Dimension mainDemension = new Dimension(1024,768);
        setSize(mainDemension);

        mainLayer = new JLayeredPane();   
        layer1 = new JPanel();
        layer1.setOpaque(false);
        layer1.setBounds(0, 0, this.getWidth(), this.getHeight());
        imgIcon = new ImageIcon("bear.jpg");
        label = new JLabel(imgIcon);
        label.setBounds(0, 0, imgIcon.getIconWidth(), imgIcon.getIconHeight());
        layer1.add(label);

        layer2 = new PaintDemo(true);
        layer2.setOpaque(false);
        layer2.setBounds(0, 0, this.getWidth(), this.getHeight());

        mainLayer.add(layer1, 1);
        mainLayer.add(layer2, 2);
        this.setContentPane(mainLayer);
    }

    public void paint(Graphics g) {    
    }

}

这是用户绘制的类:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseWheelListener;
import java.awt.event.MouseWheelEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class PaintDemo extends JPanel {
    /**
     * field explanation
     */
    private Point startPoint = new Point();

    private Point endPoint = new Point();

    private Graphics2D g2;

    private int minX;

    private int minY;

    private int maxX;

    private int maxY;

    private int height;

    private int width;


    /**
     * Create the panel.
     */

    public PaintDemo(boolean isDoubleBuffer) {

        addMouseWheelListener(new MouseWheelListener() {
            public void mouseWheelMoved(MouseWheelEvent e) {
            }
        });
        this.setDoubleBuffered(isDoubleBuffer);
        addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                endPoint = e.getPoint();
                Graphics g = PaintDemo.this.getGraphics();
                paintComponent(g);
                minX = minX < endPoint.x ? minX : endPoint.x;
                minY = minY < endPoint.y ? minY : endPoint.y;
                maxX = maxX > endPoint.x ? maxX : endPoint.x;
                maxY = maxY > endPoint.y ? maxY : endPoint.y;
                startPoint = endPoint;
            }
        });
        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                startPoint = e.getPoint();
                minX = startPoint.x;
                minY = startPoint.y;
                maxX = startPoint.x;
                maxY = startPoint.y;
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                endPoint = e.getPoint();
                Graphics g = PaintDemo.this.getGraphics();
                paintComponent(g);
                minX = minX < endPoint.x ? minX : endPoint.x;
                minY = minY < endPoint.y ? minY : endPoint.y;
                maxX = maxX > endPoint.x ? maxX : endPoint.x;
                maxY = maxY > endPoint.y ? maxY : endPoint.y;
                minX = minX > 0 ? minX : 0;
                minY = minY > 0 ? minY : 0;
                maxX = maxX < 1024 ? maxX : 1024;
                maxY = maxY < 768 ? maxY : 768;
                width = maxX - minX;
                height = maxY - minY;
                saveImage();     
                startPoint = new Point();
                endPoint = new Point();

            }
        });
    }

    /**
     * Paint method
     * 
     * {@inheritDoc}
     */
    @Override
    public void paintComponent(Graphics g) {
        g2 = (Graphics2D)g;
        g2.setStroke(new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        g2.setFont(new Font("Serif", Font.BOLD, 18));
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.red);
        g2.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y);
    }

    public void saveImage() {
        BufferedImage bi = new BufferedImage(PaintDemo.this.getWidth(), PaintDemo.this.getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = bi.createGraphics();
        paintComponent(g2);
        g2.dispose();
        try
        {
            ImageIO.write(bi, "jpg", new File("clip.jpg"));
        }
        catch(IOException ioe)
        {
            System.out.println("Clip write help: " + ioe.getMessage());
        }
    }
}

保存图片时,它只是空白图片。请帮助我。非常感谢你。
P / S:我已将我的代码编辑为您的想法,但它不起作用。结果是没有图像背景,仍然保存空白图像。 :(

When save the image, it just blank image.Please help me.Thank you so much. P/S: I have edited my code as your idea but it is not work. The result is no image background and still save blank image. :(

推荐答案

自定义绘画是通过覆盖面板的paintComponent()方法完成的。然后你使用Graphics对象来做你画画。

Custom painting is done by overriding the paintComponent() method of the panel. Then you use the Graphics object to do you painting.

你不应该有一个空的paint()方法。

You should NOT have an empty paint() method.

drawline()方法shouuld不要使用getGraphics()方法。而应该将代码移动到paintComponent()方法,然后使用传递给方法的Graphics对象。

The drawline() method shouuld not use the getGraphics() method. Instead that code should be moved to the paintComponent() method and then use the Graphics object passed to the method.

此外,你应该不要覆盖applet的paint()方法。由于你的代码是以实际大小绘制图像,你应该使用JLabel通过创建ImageIcon来显示图像。然后你将标签添加到分层窗格以用作您的背景图片。

Also, you should NOT be overriding the paint() method of the applet. Since your code is painting the image at its actual size you should just use a JLabel to display the image by creating an ImageIcon. Then you add the label to the layered pane to use as your background image.

编辑:

为什么还有空的paint()方法?摆脱它没有必要覆盖paint()方法。

Why do you still have the empty paint() method? Get rid of it there is no need to override the paint() method.

当我运行代码时,我得到一个安全异常,因为小程序无法运行迭代到一个文件,所以我无法测试你的代码部分。但如果您感兴趣我使用屏幕图像来创建图像一个组件。

When I run the code I get a security exception since applets are not able to write to a file so I can't test that part of your code. But in case you are interested I use Screen Image to create images of a component.

然而,你的主要问题是绘画代码是错误的。是的,你会看到绘制的线条,但它们不是永久性的。如果要进行永久性绘画,则不应使用组件的getGraphics()方法。尝试绘制一些线条,然后最小化applete然后恢复applet,你会看到我的意思。

However, you main problem is that the painting code is wrong. Yes you will see lines drawn, but they are not permanent. You should never use the getGraphics() method of a component when you want to do permanent paintinting. Try drawing some lines, then minimize the applete and then restore the applet and you will see what I mean.

这个解决方案是在BufferedImage上绘图。请参阅 DrawOnImage 示例>自定义绘画方法

The solution for this is to do your drawing on a BufferedImage. See the DrawOnImage example from Custom Painting Approaches.

这篇关于将JPanel保存为图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆