Getting High Resolution Image from JPanel

前端 未结 2 637
别跟我提以往
别跟我提以往 2020-12-18 16:01

Suppose I have a JPanel Called panel, and already with a paintComponent, I drew some shapes like rectangles. I can get a buffered imag

相关标签:
2条回答
  • 2020-12-18 16:38
    1. Use print instead of paint
    2. Scale up your component and your image dimension, then scale your image back to target size
    3. Use transform will make your image blurring, try to scale your image 8 times and you'll see the differences
    0 讨论(0)
  • 2020-12-18 16:51

    There are two possible ways you might achieve this, you could physically resize the component or you could apply an AffineTransform to the Graphics context, there are problems with both...

    So, starting with this screen...

    Default

    The background image is quite large to start with and has been scaled down (roughly) to fit within the current component, this is important for what's about to come...

    I then resized it by 4 (this should, roughly, get you to around 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();
    }
    

    Which resulted in...

    enter image description here

    Well, okay, the background image looks cool, but the text is off...

    Okay, so instead, we could use an 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();
    }
    

    Which resulted in...

    enter image description here

    Okay, now the image looks crap and the text is okay...


    And for reference, the test code...

    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();
                }
            }
    
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题