gpt4 book ai didi

java - 在配备 Retina 显示屏的 MacBook 上显示 Java BufferedImage 不起作用

转载 作者:行者123 更新时间:2023-12-01 14:08:44 26 4
gpt4 key购买 nike

我编写了一个Java7应用程序,它创建一个BufferedImage,每当用户更改对图像有影响的内容时,后台线程就会使用它。问题是,当显示图像时,正确的图像仅显示几秒钟,然后显示不稳定的图像(大小正确)以及来自系统的帧缓冲区的其余部分;见下图:

image

它应该是这样的:

correct image

一旦绘制线程完成,BufferedImage 将在使用 AffineTransformation 进行转换后绘制到 JPanel 组件上以反射(reflect)一定的缩放级别。

BufferedImage 的大小由固定数字决定,该数字不依赖于 MacBook 或 JFrame 的分辨率(通常相当高,例如 4000x2000) 。绘制 BufferedImage 的面板位于可根据面板大小进行调整的 ScrollPane 内。每次线程绘制新版本时,BufferedImage 是否被重写或创建新的并不重要。

我已经在 Windows、一台不带视网膜显示屏的 MacBook 和三台带视网膜显示屏的 MacBook 上测试了该工具,在所有不带视网膜显示屏的机器上,该工具都能完美运行。有什么想法吗?

编辑:程序是这样工作的:HexaVisExplorer 类是使用项目的 NetBeans 构建的 JFrame GUI。它保留一个 ScrollPane 和一个作为 ScrollPane 内容的 VisualizationPanel,并且每当用户更改影响结果的属性时,图像,组件的 ActionListener 调用 VisualizationPanel 中的方法。在那里,设置了一个属性,并初始化并启动了一个 Thread,该线程将根据 VisualizationPanel 中设置的属性绘制一个新的 BufferedImage。完成此操作后,新的 BufferedImage 将被保存到 VisualizationPanel,然后将使用重写的 PaintComponent() 重新绘制,其中图像将使用 java.awt.geom.AffineTransform 进行转换,以实现高效缩放。最后,滚动 Pane 的视口(viewport)被修改以反射(reflect)新的图像大小。这是代码:

类 HexavisExplorer.java

public class HexaVisExplorer extends javax.swing.JFrame {

private VisualizationPanel visualizationPanel;
private javax.swing.JScrollPane jScrollPane1;

public HexaVisExplorer() {
//...Example where a component listener calls a method in VisualizationPanel.java to set a property
polygonBorderCheckbox.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
visualizationPanel.setPolygonBorders(polygonBorderCheckbox.isSelected());
}
});
//...
}
}

VisualizationPanel,方法recalculate()创建一个新的VisualizationThread,它使用以下方法生成有问题的BufferedImage VisualizationPanel 中的属性。当重新计算完成后,

public class VisualizationPanel extends JPanel {

private boolean polygonBorders;
//here be more property class variables and getter/setter for them

public void setPolygonBorders(boolean polygonBorders) {
this.polygonBorders = polygonBorders;
recalculate();
this.revalidate();
this.repaint();
}

public void recalculate(){
vt = new VisualizationThread(this);
vt.execute();
}

@Override
protected void paintComponent(Graphics g) {


Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
dataTransformation.setToScale(transform_factor, transform_factor);
g2d.transform(dataTransformation);
g2d.drawImage(toDraw, 0, 0, null);
this.setSize((int) Math.ceil(transform_factor * maxwidth), (int) Math.ceil(transform_factor * maxheight));
this.setPreferredSize(new Dimension((int) Math.ceil(transform_factor * maxwidth), (int) Math.ceil(transform_factor * maxheight)));
this.revalidate();
hx.modifyVisPanelViewport(this);
}
}

VisualizationThread 采用一个 VisualizationPanel,读取其属性并基于该属性计算一个新的 BufferedImage。完成后,调用 done(),然后将新的 BufferedImage 设置为绘制到 VisualizationPanel` 并重新绘制它。

public class VisualizationThread extends SwingWorker<Object, Object> {
private VisualizationPanel vp;
private BufferedImage toDraw;

@Override
protected Object doInBackground() throws Exception {
// The bufferedImage gets drawn on here.
}

@Override
protected void done() {
vp.setToDraw(toDraw);
vp.setPreferredSize(new Dimension(toDraw.getWidth(), toDraw.getHeight()));
vp.repaint();
vp.revalidate();
}
}

最佳答案

看起来就像主机对等组件期望使用一种颜色模型渲染图像,但遇到另一种颜色模型。有太多的方法会导致这个问题无法得到明确的答案,但有几件事需要仔细审查:

  • 验证您的 BufferedImage 是否具有兼容的颜色模型和空间,例如 example .

  • 考虑使用 AffineTransformOp 进行缩放,概述 here ,因为它可以创建“具有正确大小和波段数的目标图像。”

  • done()event dispatch thread 上执行时,验证程序的其余部分是否正确同步,对于 example .

关于java - 在配备 Retina 显示屏的 MacBook 上显示 Java BufferedImage 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18700080/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com