从JPanel获取高分辨率图像

假设我有一个JPanel Called 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方法中更改我的绘图。

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

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

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

默认

背景图像开始时非常大,并且已缩小(大致)以适应当前组件,这对于将要发生的事情非常重要…

然后我将它调整为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(); } 

结果导致……

在此处输入图像描述

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

好吧,相反,我们可以使用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(); } 

结果导致……

在此处输入图像描述

好的,现在图像看起来很垃圾,文字还可以……


供参考,测试代码……

 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. 使用print而不是paint
  2. 放大组件和图像尺寸,然后将图像缩放回目标尺寸
  3. 使用变换会使图像模糊,尝试将图像缩放8次,您将看到差异