2014-09-03 50 views
3

我該如何保存BufferedImageTYPE_INT_ARGB to jpg?Java ARGB到JPG

程序生成我的形象:

enter image description here

而且它的好,但是當我保存它以這種方式:

ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); 
    BufferedOutputStream bos = new BufferedOutputStream(byteStream); 
    try { 
     ImageIO.write(buffImg, "jpg", bos); 
     // argb 
     byteStream.flush(); 
     byte[] newImage = byteStream.toByteArray(); 

     OutputStream out = new BufferedOutputStream(new FileOutputStream("D:\\test.jpg")); 
     out.write(newImage); 
     out.close(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

結果是: enter image description here

瞭解這是由於alpha層,但不知道如何解決它。 Png格式不適合我,需要JPG。

+0

你試過用白色替換alpha通道嗎? – 2014-09-03 19:07:41

+0

不,我不知道。怎麼樣? – Gwalk 2014-09-03 19:15:15

+0

不相關:當你可以直接寫入一個'FileOutputStream'時,你爲什麼要寫入一個字節數組,然後把這個字節寫入一個文件?相關:像*「BufferedImage JPG錯誤顏色」這樣的關鍵字搜索*會產生一些結果,它似乎在某些情況下發生 – Marco13 2014-09-03 23:28:49

回答

6

好的! 我解決了它。 一切都很簡單。不知道這是一個好的決定,它的速度有多快。我還沒有找到其他的。 所以我們需要的是定義新的BufferedImage。

BufferedImage buffImg = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); 
Graphics2D g2 = buffImg.createGraphics(); 

// ... other code we need 

BufferedImage img= new BufferedImage(buffImg.getWidth(), buffImg.getHeight(), BufferedImage.TYPE_INT_RGB); 
Graphics2D g2d = img.createGraphics(); 
g2d.drawImage(buffImg, 0, 0, null); 
g2d.dispose(); 

如果有什麼想法來改進這種方法,歡迎您的光臨。

+2

僅供參考:JPEG沒有alpha通道,因此在讀取/寫入時不能正確處理。如您所示,您需要將圖像轉換爲基於非alpha的結果 – MadProgrammer 2014-09-04 03:18:11

+0

謝謝! 但是,這是或多或少正常的方式來轉換BufferedImage? – Gwalk 2014-09-04 04:29:49

+0

在這種情況下,是的。這實際上是'ImageIO'讀寫器處理alpha值的一種錯誤。 – MadProgrammer 2014-09-04 04:37:50

0

具有4個顏色通道的圖像不應寫入jpeg文件。我們可以在不重複像素值的情況下在ARGB和RGB圖像之間進行轉換。這適用於大圖像。舉例:

int a = 10_000; 

BufferedImage im = new BufferedImage(a, a, BufferedImage.TYPE_INT_ARGB); 
Graphics2D g = im.createGraphics(); 
g.setColor(Color.RED); 
g.fillRect(a/10, a/10, a/5, a*8/10); 
g.setColor(Color.GREEN); 
g.fillRect(a*4/10, a/10, a/5, a*8/10); 
g.setColor(Color.BLUE); 
g.fillRect(a*7/10, a/10, a/5, a*8/10); 

//preserve transparency in a png file 
ImageIO.write(im, "png", new File("d:/rgba.png")); 

//pitfall: in a jpeg file 4 channels will be interpreted as CMYK... this is no good 
ImageIO.write(im, "jpg", new File("d:/nonsense.jpg")); 

//we need a 3-channel BufferedImage to write an RGB-colored jpeg file 
//we can make up a new image referencing part of the existing raster 
WritableRaster ras = im.getRaster().createWritableChild(0, 0, a, a, 0, 0, new int[] {0, 1, 2}); //0=r, 1=g, 2=b, 3=alpha 
ColorModel cm = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB).getColorModel(); //we need a proper ColorModel 
BufferedImage imRGB = new BufferedImage(cm, ras, cm.isAlphaPremultiplied(), null); 

//this image we can encode to jpeg format 
ImageIO.write(imRGB, "jpg", new File("d:/rgb1.jpg"));