Java 为文件导出调整JComponent的大小
我有一个JPanel,在它的基础上,我使用通常的“paintComponent(Graphics g)”方法绘制了许多自定义编写的JComponent。我使用JLayeredPane控制自定义组件的显示顺序,如下所示:Java 为文件导出调整JComponent的大小,java,swing,resize,bufferedimage,jcomponent,Java,Swing,Resize,Bufferedimage,Jcomponent,我有一个JPanel,在它的基础上,我使用通常的“paintComponent(Graphics g)”方法绘制了许多自定义编写的JComponent。我使用JLayeredPane控制自定义组件的显示顺序,如下所示: public Class MyPanel extends JPanel { private JLayeredPane layeredPane = new JLayeredPane(); private JComponent component1; priv
public Class MyPanel extends JPanel {
private JLayeredPane layeredPane = new JLayeredPane();
private JComponent component1;
private JComponent component2;
public MyPanel() {
super();
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
component1 = new CustomComponent1();
layeredPane.add (component1, new Integer(0));
component2 = new CustomComponent2();
layeredPane.add (component2, new Integer(1));
add (layeredPane);
}
public void resizePanel(Graphics g, int newWidth, int newHeight) {
component1.setBounds (f(x), f(y), f(newWidth), f(newHeight));
component2.setBounds (f(x), f(y), f(newWidth), f(newHeight));
}
public void paintComponent(Graphics g) {
if ((getWidth() != oldWidth) || (getHeight() != oldHeight)) {
oldWidth = getWidth();
oldHeight = getHeight();
resizePanel (g, getWidth(), getHeight());
}
super.paintComponent(g);
}
现在,我想将此面板导出为JPEG文件,但大小不同。当我使用以下代码时,它成功地创建/导出了所需大小的JPEG文件,但它也将面板的屏幕图像版本更新为新的大小!哎呀
public void export(File file, int width, int height)
throws IOException
{
BufferedImage scaledImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = scaledImage.createGraphics();
resizePanel (g2, width, height);
super.paintComponent (g2);
try {
OutputStream out = new FileOutputStream(file);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(scaledImage);
out.close();
} catch (FileNotFoundException e) {
throw new IOException ("Unable to export chart to ("
+ file.getAbsolutePath() + "): " + e.getLocalizedMessage());
} finally {
g2.dispose();
}
}
如何“绘制”适合导出的图像,但不实际显示此新图像
谢谢
嗯,我又回到这个问题上来了 我正在绘制的场景包含一些文本,现在最终用户希望以“纵向”纵横比导出图形。因为我不是在新的维度中重新绘制场景,而是缩放图像,这会导致文本被严重水平挤压
不管怎么说 根本不调整面板的大小;只需创建一个面板的当前大小,并绘制它。获得快照后,立即使用或将其缩放到所需的尺寸 附录:的一个优点是控制旋转、插值、比例和纵横比:
BufferedImage image = ...
int w = image.getWidth();
int h = image.getHeight();
AffineTransform scaleTransform = new AffineTransform();
// last-in-first-applied: rotate, scale
scaleTransform.scale(scaleX, scaleY);
scaleTransform.rotate(Math.PI / 2, w / 2, h / 2);
AffineTransformOp scaleOp = new AffineTransformOp(
scaleTransform, AffineTransformOp.TYPE_BILINEAR);
BufferedImage new = scaleOp.filter(image, null);
看起来是第二个很好的解决方案。我的最终解决方案如下所示:
public void export(File file, int width, int height)
throws IOException
{
BufferedImage scaledImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = scaledImage.createGraphics();
g2.scale(((double) width)/((double)getWidth()), ((double) height)/((double)getHeight()));
paintComponents(g2);
try {
ImageIO.write(scaledImage, "jpg", file);
} catch (FileNotFoundException e) {
throw new IOException ("Unable to export chart to ("
+ file.getAbsolutePath() + "): " + e.getLocalizedMessage());
} finally {
g2.dispose();
}
}
好的,我能让一切看起来正常的唯一方法(例如,光栅化后的文本没有缩放)是使用新的大小在新的图形上下文上绘制图像。这是我的新“export()”方法
上面调用的“draw()”方法在我的所有子组件上调用“setbounds()”方法,将它们绘制到新的缓冲图像上。需要做一点工作,但结果正是我所需要的。Cross-posted:这正确地建议使用javax.imageio:嗯,这种方法看起来比“g2.scale()”n重画组件稍微好一点,但文本仍然有点水平扭曲。我现在就用这个方法。再次感谢。R
public void export(File file, final int width, final int height)
throws IOException
{
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
final Graphics2D g2 = image.createGraphics();
// Must wait for the bloody image to be drawn as Swing 'paint()' methods
// merely schedule painting events. The 'draw()' below may not complete
// the painting process before the 'write()' of the image is performed.
// thus, we wait....
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
draw (g2, new Rectangle (0, 0, width, height));
}
});
ImageIO.write(image, "png", file);
} catch (Exception e) {
throw new IOException ("Unable to export chart to ("
+ file.getAbsolutePath() + "): " + e.getLocalizedMessage());
} finally {
g2.dispose();
}
}