调整BufferedImage的大小并将其存储到文件中会导致JPG图像的黑色背景

我有以下代码:

import java.awt.Graphics2D;

import java.awt.Image;

import java.awt.image.BufferedImage;

import java.io.File;

import javax.imageio.ImageIO;

public class JavaApplication

{

public static void main(String[] args) throws Exception

{

File orig = new File ("/home/xxx/Pictures/xxx.jpg");

BufferedImage bm1 = ImageIO.read(orig);

Image scaled = bm1.getScaledInstance(100, 200, BufferedImage.SCALE_SMOOTH);

BufferedImage bm2 = toBufferedImage(scaled);

File resized = new File ("/home/xxx/Pictures/resized.jpg");

ImageIO.write(bm2, "jpg", resized);

}

public static BufferedImage toBufferedImage(Image img)

{

if (img instanceof BufferedImage)

{

return (BufferedImage) img;

}

BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);

bimage.getGraphics().drawImage(img, 0, 0 , null);

return bimage;

}

}

如果我在.png文件上使用此代码,则可以正常工作,并按预期调整文件大小。但是,在jpg文件上,它会导致黑色背景。

如果我删除了getScaledInstance()代码,而只是尝试bm1使用将原始文件重写到磁盘上ImageIO.write(bm1,

"jpg",

resized),则可以正常工作。仅当使用调整大小getScaledInstance()然后尝试将结果转换Image回时BufferedImage,我才会获得完全黑色的背景文件。

关于如何解决此问题的任何想法,或者我做错了什么?

回答:

当我运行您的代码时,我没有得到黑色背景,但是图像的颜色看起来很奇怪(通道似乎被弄乱了)。

当我 中toBufferedImage(..),以BufferedImage.TYPE_INT_RGB

,因为JPEG不支持透明度),一切工作正常。

仍然很奇怪ImageIO在编写JPEG图像时没有考虑到这一点…

顺便说一下,异步图像缩放(getScaledInstance(..)不是那样)不是问题,我确保在继续操作之前已完成图像大小调整,这对结果没有影响。

要完全加载图像,请使用MediaTracker

public static void loadCompletely (Image img) {

MediaTracker tracker = new MediaTracker(new JPanel());

tracker.addImage(img, 0);

try {

tracker.waitForID(0);

} catch (InterruptedException ex) {

throw new RuntimeException(ex);

}

}

这是我用来调整图像大小,保留比例的代码(不同的调整大小方法取决于您是放大还是缩小,以及更快的面积平均替代方法):

public static BufferedImage resizeImage (BufferedImage image, int areaWidth, int areaHeight) {

float scaleX = (float) areaWidth / image.getWidth();

float scaleY = (float) areaHeight / image.getHeight();

float scale = Math.min(scaleX, scaleY);

int w = Math.round(image.getWidth() * scale);

int h = Math.round(image.getHeight() * scale);

int type = image.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;

boolean scaleDown = scale < 1;

if (scaleDown) {

// multi-pass bilinear div 2

int currentW = image.getWidth();

int currentH = image.getHeight();

BufferedImage resized = image;

while (currentW > w || currentH > h) {

currentW = Math.max(w, currentW / 2);

currentH = Math.max(h, currentH / 2);

BufferedImage temp = new BufferedImage(currentW, currentH, type);

Graphics2D g2 = temp.createGraphics();

g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

g2.drawImage(resized, 0, 0, currentW, currentH, null);

g2.dispose();

resized = temp;

}

return resized;

} else {

Object hint = scale > 2 ? RenderingHints.VALUE_INTERPOLATION_BICUBIC : RenderingHints.VALUE_INTERPOLATION_BILINEAR;

BufferedImage resized = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

Graphics2D g2 = resized.createGraphics();

g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);

g2.drawImage(image, 0, 0, w, h, null);

g2.dispose();

return resized;

}

}

以上是 调整BufferedImage的大小并将其存储到文件中会导致JPG图像的黑色背景 的全部内容, 来源链接: utcz.com/qa/420188.html

回到顶部