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

使用具有alpha的PNG改进Java ImageIO读/写,java,image,png,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 Re

我有一个大的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);

如果您只是想消除透明度,那么在这里使用
重新缩放
并不是完全必要的。更简单的解决方案是在如下背景上绘制图像:

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);

这似乎是一种更简单的方法,可能需要更少的处理能力,但我怀疑这会有很大的区别。如果您对从硬盘读取/写入图像的速度不满意,那么您几乎无法提高速度。

如果您只是想消除透明度,使用
重新缩放在这里并不是完全必要的。更简单的解决方案是在如下背景上绘制图像:

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);

这似乎是一种更简单的方法,可能需要更少的处理能力,但我怀疑这会有很大的区别。如果您对从硬盘读取/写入图像的速度不满意,那么您几乎无法提高速度。

如果您只是想消除透明度,使用
重新缩放在这里并不是完全必要的。更简单的解决方案是在如下背景上绘制图像:

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);

这似乎是一种更简单的方法,可能需要更少的处理能力,但我怀疑这会有很大的区别。如果您对从硬盘读取/写入图像的速度不满意,那么您几乎无法提高速度。

如果您只是想消除透明度,使用
重新缩放在这里并不是完全必要的。更简单的解决方案是在如下背景上绘制图像:

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);
这似乎是一种更简单的方法,可能需要更少的处理能力,但我怀疑这会有很大的区别。如果您对从硬盘读取/写入图像的速度不满意,您几乎无法提高速度。

使用:

private static void removeAlpha(文件file1,文件file2){
PngReaderByte读取器=新的PngReaderByte(文件1);
ImageInfo=reader.imgInfo;
PngWriter writer=新的PngWriter(文件2,信息);
writer.setFilterPreserve(true);
作者:setCompLevel(6);
writer.copyChunksFrom(reader.getChunksList(),chunkCopyBehavior.COPY\u ALL\u SAFE);
if(info.bitDepth!=8 | | info.channels!=4)抛出新的运行时异常(“预期的8位RGBA”);
while(reader.hasMoreRows()){
ImageLineByte line=reader.readRowByte();
byte[]buf=line.getScanlineByte();
对于(int i=0,j=3;i和:

private static void removeAlpha(文件file1,文件file2){
PngReaderByte读取器=新的PngReaderByte(文件1);
ImageInfo=reader.imgInfo;
PngWriter writer=新的PngWriter(文件2,信息);
writer.setFilterPreserve(true);
作者:setCompLevel(6);
writer.copyChunksFrom(reader.getChunksList(),chunkCopyBehavior.COPY\u ALL\u SAFE);
if(info.bitDepth!=8 | | info.channels!=4)抛出新的运行时异常(“预期的8位RGBA”);
while(reader.hasMoreRows()){
ImageLineByte line=reader.readRowByte();
byte[]buf=line.getScanlineByte();
对于(int i=0,j=3;i和:

private static void removeAlpha(文件file1,文件file2){
PngReaderByte读取器=新的PngReaderByte(文件1);
ImageInfo=reader.imgInfo;
PngWriter writer=新的PngWriter(文件2,信息);
writer.setFilterPreserve(true);
作者:setCompLevel(6);
writer.copyChunksFrom(reader.getChunksList(),chunkCopyBehavior.COPY\u ALL\u SAFE);
if(info.bitDepth!=8 | | info.channels!=4)抛出新的运行时异常(“预期的8位RGBA”);
while(reader.hasMoreRows()){
ImageLineByte line=reader.readRowByte();
byte[]buf=line.getScanlineByte();
对于(int i=0,j=3;i和:

private static void removeAlpha(文件file1,文件file2){
PngReaderByte读取器=新的PngReaderByte(文件1);
ImageInfo=reader.imgInfo;
PngWriter writer=新的PngWriter(文件2,信息);
writer.setFilterPreserve(true);
作者:setCompLevel(6);
writer.copyChunksFrom(reader.getChunksList(),chunkCopyBehavior.COPY\u ALL\u SAFE);
if(info.bitDepth!=8 | | info.channels!=4)抛出新的运行时异常(“预期的8位RGBA”);
while(reader.hasMoreRows()){
ImageLineByte line=reader.readRowByte();
byte[]buf=line.getScanlineByte();

对于(int i=0,j=3;我不知道这是否对你有帮助。我有一个开源Java映像库,可以读写PNG而不使用alpha。默认情况下,在没有alpha通道的情况下写入,你可以选择压缩级别以提高速度。关于保存基于alpha和不基于alpha的映像,你有什么标准吗?所以我在1600x14的映像上使用你的代码做了一个快速测试40,加载时间为0.280秒,重采样时间为0.183秒,写入时间为0.784秒……我不确定我会称之为任何糟糕的…(在我运行测试之前,我的电脑的cpu使用率约为75%,所以是的,很多事情都在进行)我不知道这是否对你有帮助。我有一个开源Java图像库,可以读写PNG而不使用alpha。默认情况下,不使用alpha通道进行写入,你可以选择压缩级别以提高速度。关于保存基于alpha和非基于alpha的图像,你有什么标准吗?所以我在1600x1440的图像上使用你的代码进行了一个快速测试,花费了0。加载需要280秒,重采样需要0.183秒,写入需要0.784秒……我不确定我会认为这些都很糟糕……(在我运行测试之前,我的电脑的cpu使用率约为75%,所以是的,很多事情都在进行)我不知道这是否对你有帮助。我有一个开源的Java图像库,可以读写PNG而不需要alpha。默认情况下,不需要alpha通道,你可以选择压缩