合并BG为JPEG的图像会导致意外结果 [英] Combining images where BG is a JPEG causes unexpected results
问题描述
为什么在BG为JPEG的情况下合并图像会导致意外结果?
Why does combining images where BG is a JPEG cause unexpected results?
这是我对 2张图片的叠加无法正常工作的回答的后续内容.在那里发布的源(使用在内存中创建的BG图像)看起来像这样:
This is a follow-up to my answer in Overlaying of 2 images doesnt work properly. The source posted there (using a BG image created in memory) looks like this:
- BG图片在左侧.
- FG图像(具有透明性的PNG)在中间.
- 组合的图像在右侧.
到目前为止,太好了.但是随后提出这个问题的人评论说,如果BG是JPEG,它就会失败.认为它们是错误的,所以我更改了示例以将BG图像编码为JPEG.现在,如果我在最终图像中使用BufferedImage.TYPE_INT_ARGB
或BufferedImage.TYPE_INT_RGB
,我将得到他们所指的内容:
So far, so good. But then the person who asked the question commented that if the BG was a JPEG, it failed. Thinking they were mistaken, I altered my example to encode the BG image to a JPEG. Now if I use BufferedImage.TYPE_INT_ARGB
or BufferedImage.TYPE_INT_RGB
for the final image I get what they were referring to:
我希望其中至少一个的结果与原始结果相同(更像是ARGB
变体).
I expected the result to be the same as the original for at least one of those (more so the ARGB
variant).
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import javax.imageio.ImageIO;
class CombineImages {
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
try {
URL urlImage1 =
new URL("http://i.stack.imgur.com/T5uTa.png");
// Load the FG image
Image fgImage = ImageIO.read(urlImage1);
int w = fgImage.getWidth(null);
int h = fgImage.getHeight(null);
// Create a non-trasparent BG image
BufferedImage bgImageTemp =
new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
ByteArrayOutputStream baos =
new ByteArrayOutputStream();
ImageIO.write(bgImageTemp, "jpg", baos);
ByteArrayInputStream bais =
new ByteArrayInputStream(baos.toByteArray());
BufferedImage bgImageJpeg = ImageIO.read(bais);
int result = JOptionPane.showConfirmDialog(
null,
"Use a final image with transparency?",
"Transparency",
JOptionPane.YES_NO_OPTION);
int type = (result==JOptionPane.OK_OPTION ?
BufferedImage.TYPE_INT_ARGB :
BufferedImage.TYPE_INT_RGB);
// Create the final image
BufferedImage finalImage =
new BufferedImage(w,h,type);
Graphics2D g = finalImage.createGraphics();
g.drawImage(bgImageJpeg, w, h, null);
g.drawImage(fgImage, w, h, null);
g.dispose();
JPanel gui = new JPanel(new GridLayout(1,0,5,5));
gui.add(new JLabel(new ImageIcon(bgImageJpeg)));
gui.add(new JLabel(new ImageIcon(fgImage)));
gui.add(new JLabel(new ImageIcon(finalImage)));
JOptionPane.showMessageDialog(null, gui);
} catch (Exception e) {
e.printStackTrace();
}
}
};
SwingUtilities.invokeLater(r);
}
}
推荐答案
类似的原因是打字错误.
Looks like this is due to a typo.
在您引用的 answer 中,合并后的图片是
In your referenced answer, the code that formed the combined image was
Graphics2D g = finalImage.createGraphics();
g.drawImage(bgImage, 0, 0, null);
g.drawImage(fgImage, 0, 0, null);
但是在这个问题中,它已更改为
But in this question, it's been changed to,
Graphics2D g = finalImage.createGraphics();
g.drawImage(bgImageJpeg, w, h, null);
g.drawImage(fgImage, w, h, null);
后者开始在,它恰好是图像的右下角,因此实际上没有任何东西画.但是,前者可以按预期绘制整个图像.
The latter begins drawing at the "top-left corner", which happens to be the bottom-right corner of the images, so nothing is really drawn. The former, however, draws the entire images, as expected.
这篇关于合并BG为JPEG的图像会导致意外结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!