【问题标题】:PNG - Is it possible to reduce the palette using Java 2D?PNG - 是否可以使用 Java 2D 减少调色板?
【发布时间】:2011-10-13 12:43:41
【问题描述】:

如果我将 PNG 图像打开为 BufferedImage,是否可以减少 PNG 图像中的调色板以减少颜色(每像素位数/颜色深度减少)?

例如,如果您查看 Wikipedia 中的 Colour depth,我想在我的 PNG 图像中使用 16 种颜色(右侧第三张图像)。

如果 Java 2D 无法实现,是否有一个库可以让我有效地做到这一点?

【问题讨论】:

标签: java png java-2d color-palette


【解决方案1】:

我认为 Martijn Courteaux 是对的:

这里是示例实现:

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class ImagingTest2 {
    public static void main(String[] args) throws IOException {
        BufferedImage src = ImageIO.read(new File("in.png")); // 71 kb

        // here goes custom palette
        IndexColorModel cm = new IndexColorModel(
                3, // 3 bits can store up to 8 colors
                6, // here I use only 6
                //          RED  GREEN1 GREEN2  BLUE  WHITE BLACK              
                new byte[]{-100,     0,     0,    0,    -1,     0},
                new byte[]{   0,  -100,    60,    0,    -1,     0},
                new byte[]{   0,     0,     0, -100,    -1,     0});

        // draw source image on new one, with custom palette
        BufferedImage img = new BufferedImage(
                src.getWidth(), src.getHeight(), // match source
                BufferedImage.TYPE_BYTE_INDEXED, // required to work
                cm); // custom color model (i.e. palette)
        Graphics2D g2 = img.createGraphics();
        g2.drawImage(src, 0, 0, null);
        g2.dispose();

        // output
        ImageIO.write(img, "png", new File("out.png"));   // 2,5 kb
    } 
}

【讨论】:

  • 缩小后的图像看起来很糟糕。我认为 16 种颜色(均匀分布)会比你的 6 种颜色好得多。 (但仍然 +1。)
  • 谢谢,16 种颜色会破坏缩进并引入滚动条。 :D
  • 这很有魅力!你能解释一下为什么你有标记为// RED GREEN1 GREEN2 BLUE WHITE BLACK 的索引为什么你有'GREEN1'和'GREEN2'?谢谢
  • 哦,是的。我只是想看看它是否拿起了调色板。如果是,则生成的图片将具有两种绿色阴影和一种任何其他颜色的阴影。很难看到,但确实有。
【解决方案2】:

使用下部调色板创建一个新的 BufferedImage 并使用createGraphic() 获取一个Graphics2D 对象。在图形上绘制原始图像。 dispose() 图形,给你。

BufferedImage img = new BufferedImage(orig.getWidth(), orig.getHeight(),
                                      BufferedImage.TYPE_USHORT_555_RGB);

【讨论】:

  • 如何定义调色板颜色?
  • 你当然不应该投反对票。我提供了我的答案来证明这一点。
猜你喜欢
  • 2012-03-03
  • 1970-01-01
  • 2021-12-21
  • 2019-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-24
  • 2013-01-15
相关资源
最近更新 更多