BG が JPEG である画像を結合すると、予期しない結果が生じるのはなぜですか?
これは、 Overlaying of 2 images doesn't work correctly での私の回答のフォローアップです。そこに投稿されたソース (メモリ内に作成された BG イメージを使用) は次のようになります。
- 左がBG画像です。
- FG 画像 (透明度のある PNG) は中央にあります。
- 組み合わせた画像が右です。
ここまでは順調ですね。しかし、質問者は、BG が JPEG の場合は失敗したとコメントしました。それらが間違っていると考えて、BG 画像を JPEG にエンコードするように例を変更しました。最終的な画像にBufferedImage.TYPE_INT_ARGB
またはを使用すると、彼らが参照していたものが得られます。BufferedImage.TYPE_INT_RGB
TYPE_INT_ARGB
TYPE_INT_RGB
結果は、少なくとも 1 つの元の結果と同じであると予想していました (ARGB
バリアントはさらにそうです)。
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);
}
}