使用具有alpha的PNG改进Java ImageIO读/写

时间:2015-08-26 23:20:48

标签: java image png

我有一个大的PNG图像(600x600),我的应用程序使图像不透明并写出文件。问题是ImageIO的性能很糟糕。还有其他选择吗?我要求图像不透明。以下是我正在做的事情:

    BufferedImage buf = ImageIO.read(localUrl);
    float[] scales = {1f, 1f, 1f, 1f};  // R, G, B, A
    float[] offsets = {0f, 0f, 0f, 1f};   // R, G, B, A
    RescaleOp rescaler = new RescaleOp(scales, offsets, null);
    BufferedImage opaque = rescaler.filter(buf, null);
    File outputfile = new File(localUrl.getPath());
    ImageIO.write(opaque, "png", outputfile);

2 个答案:

答案 0 :(得分:3)

如果你只是想摆脱透明度,那么在这里使用RescaleOp是完全必要的。一个更简单的解决方案是将图像绘制在背景上,如下所示:

Color bgColor = Color.WHITE;

BufferedImage foreground = ImageIO.read(localUrl);
int width = foreground.getWidth();
int height = foreground.getHeight();
BufferedImage background = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = background.createGraphics();
g.setColor(bgColor);
g.fillRect(0, 0, width, height);
g.drawImage(foreground, 0, 0, null);
g.dispose();
File outputfile = new File(localUrl.getPath());
ImageIO.write(background, "png", outputfile);

这似乎是一种更简单的处理方法,并且可能需要更少的处理能力,但我怀疑会有很大的差异。如果您对速度不满意,可以从硬盘读取/写入图像,那么您可以做的很少,以加快速度。

答案 1 :(得分:0)

使用PNGJ

private static void removeAlpha(File file1,File file2) {
    PngReaderByte reader = new PngReaderByte(file1);
    ImageInfo info = reader.imgInfo;
    PngWriter writer = new PngWriter(file2,info);
    writer.setFilterPreserve(true);
    writer.setCompLevel(6);
    writer.copyChunksFrom(reader.getChunksList(), ChunkCopyBehaviour.COPY_ALL_SAFE);
    if( info.bitDepth != 8 ||info.channels!=4) throw new RuntimeException("expected 8bits RGBA ");
    while(reader.hasMoreRows()) {
        ImageLineByte line = reader.readRowByte();
        byte [] buf = line.getScanlineByte();
        for(int i=0,j=3;i<info.cols;i++,j+=4)
            buf[j]=(byte)255;
        writer.writeRow(line);
    }
    reader.end();
    writer.end();
}

我不确定这是否会提高性能。请记住,(与Parker Hoyes&#39;回答相反)这只会杀死alpha通道,但它不会与某些背景颜色混合(因此&#34;原始&#34;颜色将出现在之前 - 透明的现在不透明的区域。)