[英]Strange color changes to a BufferedImage after saving it as a PNG file with ImageIO.write
[英]Java painting to BufferedImage or ImageIO.write() do not block and png file produced is either blank of half-baked
我正在在Linux CentOS上的Tomcat 7上運行的servlet中創建帶有簡單黑白線圖的小png文件,並使用幀緩沖區Xvfb提供圖形資源。 然后,我的目標是在服務器返回的html頁面上顯示此png文件。 我發現,有時(例如,每10張照片中的一張)顯示為空白,有時甚至是半張。 我檢查了服務器上的相應.png文件,在這些情況下,它們的確確實是空白或半繪制的。
這就是我的代碼的樣子(另外的復雜之處是ChimePro是專有類庫的一部分,我沒有它的代碼;它只是擴展了Panel或Canvas):
Frame f = new Frame();
ChimePro cp = new ChimePro();
f.add(cp);
f.addNotify();
cp.setBounds(0,0,200,200);
BufferedImage bi = new BufferedImage (200,200,BufferedImage.TYPE_BYTE_INDEXED);
Graphics g = bi.createGraphics()
cp.paint(g);
File ffjj = new File("file.png");
ImageIO.write(bi, "png", ffjj);
因此,似乎paint(g)或可能不太可能的ImageIO.write()方法沒有像應做的那樣阻塞,並且即使尚未創建正確的文件,程序也繼續前進。 有趣的是,取決於我在Tomcat啟動之前如何指向DISPLAY變量-指向模擬同一服務器上X環境的Xvfb屏幕,或者指向遠程計算機上運行的某些真實X顯示-圖片發生空白或損壞的可能性發生了變化。
關於如何處理此問題以確保用戶看不到空白或損壞的圖形的任何想法? 我實際上是在寫少量的短文件,所以這與速度無關,只是為了避免顯示錯誤繪制的圖片。 謝謝您的任何建議。
這是例外(僅在某些圖形中偶然發生-不取決於圖形的內容,而可能取決於某些着色):
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerExceptio
at com.mdli.chime.ChimePro.paint(ChimePro.java)
at java.awt.Canvas.update(Canvas.java:142)
at sun.awt.RepaintArea.updateComponent(RepaintArea.java:255)
at sun.awt.X11.XRepaintArea.updateComponent(XRepaintArea.java:60)
at sun.awt.RepaintArea.paint(RepaintArea.java:232)
at sun.awt.X11.XComponentPeer.handleEvent(XComponentPeer.java:591)
at java.awt.Component.dispatchEventImpl(Component.java:4937)
在ImageIO.write之前使用g.dispose(),看看是否有幫助:
Frame f = new Frame();
ChimePro cp = new ChimePro();
f.add(cp);
f.addNotify();
cp.setBounds(0,0,200,200);
BufferedImage bi = new BufferedImage (200,200,BufferedImage.TYPE_BYTE_INDEXED);
Graphics g = bi.createGraphics()
cp.paint(g);
File ffjj = new File("file.png");
g.dispose();
ImageIO.write(bi, "png", ffjj);
您需要確保自己...
printAll
而不是print
,因為它將嘗試確保內容被完整繪制,並且不會對流程進行雙重緩沖(使其更快) dispose
Graphics
上下文。 下面顯示了在框架上顯示和使用示例代碼打印時的面板...
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class PrintComponent {
public static void main(String[] args) {
new PrintComponent();
}
public PrintComponent() {
Example example = new Example();
example.setSize(example.getPreferredSize());
example.doLayout();
BufferedImage bi = new BufferedImage (example.getWidth(), example.getHeight(), BufferedImage.TYPE_BYTE_INDEXED);
Graphics2D g2d = bi.createGraphics();
example.printAll(g2d);
g2d.dispose();
try {
ImageIO.write(bi, "png", new File("D:/PrintExample.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
public class Example extends JPanel {
public Example() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel("Hello"), gbc);
add(new JTextField("'ello", 20), gbc);
add(new JButton("g'day"), gbc);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.