マウスのクリックで、二枚の画像をブレンドしながら切り替えます

前田稔の超初心者のプログラム入門

プログラムの作成

  1. メモ帳などでタイプして Blend.java の名前で保存して下さい。
    //★ ピクセルをブレンドしながら画像を切り替える    前田 稔
    import java.io.*;
    import java.awt.*;
    import javax.swing.*;
    import javax.imageio.ImageIO;
    import java.awt.image.*;
    import java.awt.event.*;
    
    class Blend extends JFrame
    {   BufferedImage Img1;
        BufferedImage Img2;
        BufferedImage View;
        int           Height;       // 画像の高さ
        int           Width;        // 画像の幅
        int           Rate= 0;      // 0〜4= 5段階
    
        // Main
        public static void main(String args[])
        {   new Blend();
        }
    
        // Constructor
        public Blend()
        {   super("Image Blend");
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setSize(520, 300);
            addMouseListener(new inMouseListener());
            Img1= loadImage("C:\\DATA\\Test\\ffx2s.jpg");
            Img2= loadImage("C:\\DATA\\Test\\GeoS.jpg");
            Height= Img1.getHeight();
            Width = Img1.getWidth();
            View= new BufferedImage(Width,Height,BufferedImage.TYPE_4BYTE_ABGR);
            ImgBlend(Rate);
            setVisible(true);
        }
    
        // Paint Method
        public void paint(Graphics g)
        {   if (View!=null)
            {   g.drawImage(View,20,40,this);
            }
        }
    
        // InnerClass MouseListener
        class inMouseListener extends MouseAdapter
        {   public void mouseClicked(MouseEvent e)
            {   Rate= (Rate+1)%5;
                ImgBlend(Rate);
                repaint();
            }
        }
    
        // BufferedImage の入力
        public BufferedImage loadImage(String fileName)
        {   InputStream is = null;
            try
            {   is = new FileInputStream(fileName);
                BufferedImage img = ImageIO.read(is);
                return img;
            }
            catch (IOException e)
            {   throw new RuntimeException(e);  }
            finally
            {   if (is != null)
                    try { is.close(); }
                    catch (IOException e) {}
            }
        }
    
        // 二枚のイメージをブレンド
        public void ImgBlend(int rate)
        {   int     pixel,pixel1,pixel2,wk1,wk2;
    
            for(int y=0; y<Height; y++)
            {   for(int x=0; x<Width; x++)
                {   pixel1= Img1.getRGB(x,y);
                    pixel2= Img2.getRGB(x,y);
                    pixel= 0XFF000000;
                    wk1= ((pixel1 & 0xFF0000)*rate)/5;      // 16〜23= 赤色
                    wk2= ((pixel2 & 0xFF0000)*(4-rate))/5;
                    pixel |= (wk1+wk2) & 0xFF0000;
                    wk1= ((pixel1 & 0xFF00)*rate)/5;        // 8〜15= 緑色
                    wk2= ((pixel2 & 0xFF00)*(4-rate))/5;
                    pixel |= (wk1+wk2) & 0xFF00;
                    wk1= ((pixel1 & 0x00FF)*rate)/5;        // 0〜7= 青色
                    wk2= ((pixel2 & 0x00FF)*(4-rate))/5;
                    pixel |= (wk1+wk2) & 0x00FF;
                    View.setRGB(x,y,pixel);
                }
            }
        }
    }
    
  2. 同じサイズの二枚の画像を用意して下さい。
    このプログラムでは、以下の画像を使っています。
    Img1= loadImage("C:\\DATA\\Test\\ffx2s.jpg");
    Img2= loadImage("C:\\DATA\\Test\\GeoS.jpg");
    マウスをクリックすると二枚の画像がブレンドしながら切り替わります。

プログラムの説明

  1. BufferedImage に格納した二枚の画像をブレンドしながら切り替えます。
    Img1 が一枚目の画像で、Img2 が二枚目の画像で、View が描画する画像の領域です。
    Height; が画像の高さで Width; が幅です。
    Rate がブレンド係数で 0〜4 の5段階を繰り返します。
        BufferedImage Img1;
        BufferedImage Img2;
        BufferedImage View;
        int           Height;       // 画像の高さ
        int           Width;        // 画像の幅
        int           Rate= 0;      // 0〜4= 5段階
        
  2. 画像の切り替えにマウスを使うので MouseListener を設定します。
    Constructor で二枚の画像を入力して、幅と高さを設定します。
    new BufferedImage() で View の領域を生成します。
    TYPE_4BYTE_ABGR はアルファチャネル付きの画像フォーマットです。
    ImgBlend(Rate); で二枚の画像をブレンドして View に設定します。
        // Constructor
        public Blend()
        {   super("Image Blend");
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setSize(520, 300);
            addMouseListener(new inMouseListener());
            Img1= loadImage("C:\\DATA\\Test\\ffx2s.jpg");
            Img2= loadImage("C:\\DATA\\Test\\GeoS.jpg");
            Height= Img1.getHeight();
            Width = Img1.getWidth();
            View= new BufferedImage(Width,Height,BufferedImage.TYPE_4BYTE_ABGR);
            ImgBlend(Rate);
            setVisible(true);
        }
        
  3. paint() メソッドでは View に格納されている画像を描画します。
        // Paint Method
        public void paint(Graphics g)
        {   if (View!=null)
            {   g.drawImage(View,20,40,this);
            }
        }
        
  4. MouseListener でクリックを検出して Rate をアップします。
    Rate は 0〜4 の繰り返しです。
    Rate に従って View の画像を更新して repaint(); で描画します。
        // InnerClass MouseListener
        class inMouseListener extends MouseAdapter
        {   public void mouseClicked(MouseEvent e)
            {   Rate= (Rate+1)%5;
                ImgBlend(Rate);
                repaint();
            }
        }
        
  5. 画像を入力する loadImage() メソッドです。
        // BufferedImage の入力
        public BufferedImage loadImage(String fileName)
        {   InputStream is = null;
            try
            {   is = new FileInputStream(fileName);
                BufferedImage img = ImageIO.read(is);
                return img;
            }
            catch (IOException e)
            {   throw new RuntimeException(e);  }
            finally
            {   if (is != null)
                    try { is.close(); }
                    catch (IOException e) {}
            }
        }
        
  6. 二枚のイメージをブレンドする ImgBlend() メソッドです。
    ImgX.getRGB(x,y); で、32bit(int型)のピクセルを取得します。
    先頭から 24〜31= アルファ成分、16〜23= 赤色成分、8〜15= 緑色成分、0〜7= 青色成分の順です。
    アルファ成分の標準値は、8ビットが全て1(0XFF000000)の不透明です。
    8ビットを全て0に設定すると、完全な透明になります。
    二枚の画像の赤緑青を rate に従ってブレンドして、View.setRGB(x,y,pixel); でピクセル毎に格納します。
        // 二枚のイメージをブレンド
        public void ImgBlend(int rate)
        {   int     pixel,pixel1,pixel2,wk1,wk2;
    
            for(int y=0; y<Height; y++)
            {   for(int x=0; x<Width; x++)
                {   pixel1= Img1.getRGB(x,y);
                    pixel2= Img2.getRGB(x,y);
                    pixel= 0XFF000000;
                    wk1= ((pixel1 & 0xFF0000)*rate)/5;      // 16〜23= 赤色
                    wk2= ((pixel2 & 0xFF0000)*(4-rate))/5;
                    pixel |= (wk1+wk2) & 0xFF0000;
                    wk1= ((pixel1 & 0xFF00)*rate)/5;        // 8〜15= 緑色
                    wk2= ((pixel2 & 0xFF00)*(4-rate))/5;
                    pixel |= (wk1+wk2) & 0xFF00;
                    wk1= ((pixel1 & 0x00FF)*rate)/5;        // 0〜7= 青色
                    wk2= ((pixel2 & 0x00FF)*(4-rate))/5;
                    pixel |= (wk1+wk2) & 0x00FF;
                    View.setRGB(x,y,pixel);
                }
            }
        }
        

超初心者のプログラム入門(Java2)