簡體   English   中英

如何使用JAVA將帶有alpha的PNG轉換為JPEG保存顏色

[英]How to convert PNG with alpha to JPEG conserving colors using JAVA

我在使用Alpha將PNG轉換為JPEG時遇到了一些麻煩。

這是圖像: http//upload.wikimedia.org/wikipedia/commons/thumb/e/ee/Radio_SRF_3.svg/500px-Radio_SRF_3.svg.png

原版的: 在此輸入圖像描述

轉換后的JPEG文件顏色錯誤。 它現在更灰暗而不是更暗。 圖像結果

這就是我進行轉換的方式:

刪除alpha:

public static BufferedImage imageFillAlphaWithColor(BufferedImage image, Color fillColor) {
    if (image.getColorModel().getTransparency() == Transparency.OPAQUE) return image;

    int w = image.getWidth();
    int h = image.getHeight();
    BufferedImage newImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    Graphics2D g = newImage.createGraphics();
    g.drawImage(image, 0, 0, fillColor, null);
    g.dispose();

    return newImage;
}

Jpeg壓縮:

public static byte[] compressedJpegImage(BufferedImage image, float quality) {
        byte jpegImage[] = null;
        try {
            // Find a jpeg writer
            ImageWriter writer = null;
            Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName("jpg");
            if (iter.hasNext()) {
                writer = (ImageWriter) iter.next();
            }

            // Prepare output
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageOutputStream ios = ImageIO.createImageOutputStream(os);
            writer.setOutput(ios);

            // Set the compression quality
            ImageWriteParam iwparam = writer.getDefaultWriteParam();
            iwparam.setProgressiveMode(ImageWriteParam.MODE_DEFAULT);
            iwparam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            iwparam.setCompressionQuality(quality);

            // Write the image
            writer.write(null, new IIOImage(image, null, null), iwparam);

            // Cleanup
            ios.flush();
            writer.dispose();
            ios.close();

            jpegImage = os.toByteArray();

        } catch (IOException e) {
            e.printStackTrace();
        }

        return jpegImage;
    }

並通過ImageIO將其存儲為JPEG。

知道如何保留色彩空間以保持原始色彩的顏色嗎?

UPDATE

問題是由ImageMagick調整大小時引起的。 似乎ImageMagick確實將顏色空間更改為TYPE_CUSTOM,Java無法處理。

當前解決方案

在我開始通過ImageMagick調整圖像大小之前刪除alpha。

還沒有找到將色彩空間從“CUSTOM”轉換回“ARGB”的解決方案。 所以這只是這個問題的“解決方法”。

您實際上並沒有刪除alpha值。 當您執行在imageFillAlphaWithColor方法中執行的操作時,Java會將顏色值除以alpha。

我建議使用AlphaComposite來實際刪除alpha。

這是關於如何使用Composite Graphics的Oracle教程: http//docs.oracle.com/javase/tutorial/2d/advanced/compositing.html

無法輕松測試,我認為您需要做的是:

Graphics2D g = newImage.createGraphics();
g.setComposite(AlphaComposite.Src);
g.drawImage(image, 0, 0, fillColor, null);

如果這不起作用,請閱讀此相關問題: 更改BufferedImage的alpha值?

那這個呢?

public static void main(String[] args) throws Exception {
        Color fillColor = Color.BLUE; // just to verify
        BufferedImage bi = ImageIO.read(new File("c:\\temp\\tGjhw.png"));
        BufferedImage bi2 = new BufferedImage(bi.getWidth(), bi.getHeight(),
              BufferedImage.TYPE_3BYTE_BGR);
        bi2.getGraphics().drawImage(bi, 0, 0, fillColor, null);
        // you can do a more complex saving to tune the compression  parameters
        ImageIO.write(bi2,"JPG",new File("c:\\temp\\tGjhw2.jpg"));
    }

太亮的結果似乎是由於從線性色空間(gamma = 1)到sRGB(gamma = 1 / 2.2)的轉換。 原始版本不包含任何伽瑪信息,因此ImageMagick可以自由選擇自己的默認值。 最近版本的ImageMagick處理灰度圖像的方式不同,有些假設是線性的,而其他版本則假設為sRGB。 從命令行開始,您將使用“-gamma 1”選項獲得所有版本的較暗結果。 你需要在Java中做同等的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM