从JPanel获取高分辨率图像

时间:2014-11-14 05:07:05

标签: java swing awt

假设我有JPanel已调用panel,并且已经有paintComponent,我画了一些像矩形的形状。我可以从我的面板中获取缓冲图像,如:

    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);
    ImageIO.write(bi1, "png", new File("test.png"));

如何从panel中获取高分辨率图像? (当前输出图像仅基于我的监视器中JPanel的分辨率)

我尝试AffineTransform,但它没有做我需要的。

请注意,我已经在我的panel中绘制了所有内容,并且不想在我的paintComponent方法中更改我的绘图。

我真的在寻找一种实用的方式,并感谢任何帮助。

2 个答案:

答案 0 :(得分:8)

您可以通过两种方式实现此目的,您可以在物理上调整组件大小,也可以将AffineTransform应用于Graphics上下文,这两种方法都存在问题......

所以,从这个屏幕开始......

Default

背景图像开始时非常大,并且已按比例缩小(大致)以适应当前组件,这对即将到来的内容非常重要...

然后我将它调整为4(这应该,大致会让你达到300dpi左右)

Dimension original = tp.getSize();

System.out.println("Original = " + original);

int width = tp.getWidth() * 4;
int height = tp.getHeight() * 4;

System.out.println("Target = " + width + "x" + height);
tp.setSize(width, height);
tp.doLayout();
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
tp.print(g2d);
g2d.dispose();

tp.setSize(original);
tp.doLayout();

try {
    ImageIO.write(img, "png", new File("Test.png"));
} catch (IOException ex) {
    ex.printStackTrace();
}

导致......

enter image description here

好吧,好吧,背景图片看起来很酷,但文字已关闭......

好的,我们可以使用AffineTransform ...

int width = tp.getWidth() * 4;
int height = tp.getHeight() * 4;

BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2d.setTransform(AffineTransform.getScaleInstance(4, 4));
tp.print(g2d);
g2d.dispose();

try {
    ImageIO.write(img, "png", new File("Test.png"));
} catch (IOException ex) {
    ex.printStackTrace();
}

导致......

enter image description here

好的,现在图片看起来很糟糕,文字还可以......


供参考,测试代码......

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class HiRes {

    public static void main(String[] args) {
        new HiRes();
    }

    public HiRes() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                final TestPane tp = new TestPane();
                JButton print = new JButton("Print");
                print.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {

                        Dimension original = tp.getSize();

                        System.out.println("Original = " + original);

                        int width = tp.getWidth() * 4;
                        int height = tp.getHeight() * 4;

                        System.out.println("Target = " + width + "x" + height);
                        tp.setSize(width, height);
                        tp.doLayout();
                        BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
                        Graphics2D g2d = img.createGraphics();
                        g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
                        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                        g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
                        g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
                        g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
                        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
                        g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
//                      g2d.setTransform(AffineTransform.getScaleInstance(4, 4));
                        tp.print(g2d);
                        g2d.dispose();
                        tp.setSize(original);
                        tp.doLayout();

                        try {
                            ImageIO.write(img, "png", new File("Test.png"));
                        } catch (IOException ex) {
                            ex.printStackTrace();
                        }
                    }
                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(tp);
                frame.add(print, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage background;

        public TestPane() {

            setLayout(new GridBagLayout());

            try {
                background = ImageIO.read(new File("/some/image/some/where"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            setLayout(new GridBagLayout());

            JLabel label = new JLabel("This is a test");
            label.setForeground(Color.WHITE);
            label.setFont(label.getFont().deriveFont(24f));
            add(label);

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (background != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                Image scaled = background;
                if (getWidth() < getHeight()) {
                    scaled = background.getScaledInstance(getWidth(), -1, Image.SCALE_SMOOTH);
                } else {
                    scaled = background.getScaledInstance(-1, getHeight(), Image.SCALE_SMOOTH);
                }
                int x = (getWidth() - scaled.getWidth(this)) / 2;
                int y = (getHeight() - scaled.getHeight(this)) / 2;
                g2d.drawImage(scaled, x, y, this);
                g2d.dispose();
            }
        }

    }

}

答案 1 :(得分:0)

  1. 使用print代替paint
  2. 放大组件和图像尺寸,然后将图像缩放回目标尺寸
  3. 使用变换会使图像模糊,尝试将图像缩放8次,然后您就会看到差异