モザイク,ぼかし


画像にモザイク処理を施すということは解像度を荒くすることである. 解像度を荒くするには,ピクセルをいくつか集めてブロックをつくり, そのブロックをすべて同じ色にする. 以下に示すコードは,8ピクセル×8ピクセルのブロック内の すべてのピクセルの色を,強制的に一番左上のピクセルの色にする.

var
  RGBs: array of array of TRGB;

procedure TForm1.Button5Click(Sender: TObject);
var
  Bmp: TBitmap;
  P: PRGB;
  TheRGB: TRGB;
  I, J, K, L, JMax, IMax, Size: Integer;
begin
   Bmp := TBitmap.Create;
   try
     Bmp.Assign( Image.Picture.Bitmap );
     SetLength( RGBs, Bmp.Height, Bmp.Width );
     for J := 0 to Bmp.Height - 1 do  // 動的配列にRGB値をコピー
     begin
        P := Bmp.ScanLine[ J ];
        for I := 0 to Bmp.Width - 1 do
        begin
           RGBs[ J, I ] := P^;
           Inc( P );
        end;
     end;

     Size := 8;
     JMax := Bmp.Height div Size;
     IMax := Bmp.Width div Size;
     for J := 0 to JMax - 1 do
     begin
        for I := 0 to Imax - 1 do
        begin
           TheRGB := RGBs[ J * Size, I * Size ]; // ブロックの左上ピクセルのRGB値を取得
           for K := 0 to Size - 1 do
           begin
              for L := 0 to Size - 1 do
              begin
                 RGBs[ J * Size + K, I * Size + L ] := TheRGB;
              end;
           end;
        end;
     end;

     for J := 0 to Bmp.Height - 1 do
     begin
        P := Bmp.ScanLine[ J ];
        for I := 0 to Bmp.Width - 1 do
        begin
           P^ := RGBs[ J, I ];
           Inc( P );
        end;
     end;

     Image.Picture.Bitmap := Bmp;
   finally
     Finalize( RGBs );
     Bmp.Free;
   end;
end;

ブロック内のピクセルの色は,左上のピクセルの色を用いる以外にも,全部のピクセルの平均を 用いる場合もある.
蛇足だが,ここに示したような方法でモザイク処理した画像は, ピクセルの元の色情報が完全に失われているので, 決して元に戻すことはできない

また,ぼかし処理を施すには以下の式でRGB値を決定する.

(新たなR値)=((現在のR値)+(上下左右のピクセルのR値の平均)) / 2
G値,B値についても同様.

以下のコードはこのを使ってぼかし処理を行うものである. ただし,1回実行しただけでは画像はほとんど変化しないので,複数回実行する必要がある.

procedure TForm1.Button3Click(Sender: TObject);
var
  Bmp: TBitmap;
  P: PRGB;
  Mean: TRGB;
  I, J: Integer;
begin
   Bmp := TBitmap.Create;
   try
     Bmp.Assign( Image.Picture.Bitmap );
     SetLength( RGBs, Bmp.Height, Bmp.Width );

     for J := 0 to Bmp.Height - 1 do
     begin
        P := Bmp.ScanLine[ J ];
        for I := 0 to Bmp.Width - 1 do
        begin
           RGBs[ J, I ].R := P^.R;
           RGBs[ J, I ].G := P^.G;
           RGBs[ J, I ].B := P^.B;
           Inc( P );
        end;
     end;

     for J := 1 to Bmp.Height - 2 do
     begin
        P := Bmp.ScanLine[ J ];
        for I := 1 to Bmp.Width - 2 do
        begin
           Inc( P );
           Mean.R := Trunc( ( RGBs[ J - 1, I ].R + RGBs[ J, I + 1 ].R
               + RGBs[ J + 1, I ].R + RGBs[ J, I - 1 ].R ) / 4 );
           Mean.G := Trunc( ( RGBs[ J - 1, I ].G + RGBs[ J, I + 1 ].G
               + RGBs[ J + 1, I ].G + RGBs[ J, I - 1 ].G ) / 4 );
           Mean.B := Trunc( ( RGBs[ J - 1, I ].B + RGBs[ J, I + 1 ].B
               + RGBs[ J + 1, I ].B + RGBs[ J, I - 1 ].B ) / 4 );
           P^.R := Trunc( ( RGBs[ J, I ].R + Mean.R ) / 2 );
           P^.G := Trunc( ( RGBs[ J, I ].G + Mean.G ) / 2 );
           P^.B := Trunc( ( RGBs[ J, I ].B + Mean.B ) / 2 );
        end;
     end;
     Image.Picture.Bitmap := Bmp;
   finally
     Finalize( RGBs );
     Bmp.Free;
   end;
end;

以下に実行例を示す. ぼかし処理は上のコードを10回実行した画像である.
原画像
モザイク処理
ぼかし処理


お問い合わせはメールにて: akasaka@klc.ac.jp

戻る
SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送