6

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

2 に答える 2

0

gui.repaint();

joptionpane の構築中にパネルとコンポーネントを効果的にペイントしたため、後で試してみてください。ただし、それでも構築スレッドに一致する可視性の呼び出しが真実を保持しないため、joptionpane の呼び出し後にペイント オーバーライド メソッドで g.drawImage を呼び出す必要があります。

画面上にまだ実際に存在していないものを描画することはできませんが、理論的にはメソッドに十分なオブジェクトのセットとして存在するため、呼び出しには許容範囲があります。

于 2013-07-23T18:58:09.140 に答える