DOBON.NET DOBON.NETプログラミング掲示板過去ログ

C#で、画像に対してのモザイク処理

環境/言語:[Visual C#]
分類:[.NET]

はじめまして。ななと申します。
C#の初心者です。
C#で、ピクチャボックスに貼りつけている画像に対しての
モザイク処理をしたいのですが、どうすればよいのか判りません。。。

インターネットで、C#の画像処理などで、検索してみたのですが、
私の探し方があまりよくなかったからなのでしょうか、
判りやすい説明を見つける事ができませんでした。。。
VisualBasicで、処理を見つける事ができたのですが、
VisualBasicでの開発経験が全くなく、C#へどう変換すれば、
いいのか判りませんでした。。。

ご存知のお方がいらっしゃいましたら、
ぜひご教授して頂きたく思い、投稿させて頂きました。
よろしくお願いします。
こんにちは、じゃんぬねっと です。

■No8362に返信(ななさんの記事)
> VisualBasicで、処理を見つける事ができたのですが、
> VisualBasicでの開発経験が全くなく、C#へどう変換すれば、
> いいのか判りませんでした。。。

問題さえなければ、そこへのリンクを貼っておくと回答がつきやすいでしょうね。
... というより、モザイク処理のアルゴリズムさえわかれば良いのではないでしょうか?

> ご存知のお方がいらっしゃいましたら、
> ぜひご教授して頂きたく思い、投稿させて頂きました。

【モザイク処理のアルゴリズム】

 [簡単な方法]
  任意の幅で縦横に線を引きます。
  そうすると、ブロックができます。
  そのブロックのどこかの 1 部分の色を抽出して、そのブロックを塗りつぶします。
  大抵は左下の色を使うそうです。

 [難しい方法 (一般的な方法)]
  任意の幅で縦横に線を引きます。
  そうすると、ブロックができます。
  そのブロックの色の平均値を出して、その色でブロックを塗りつぶします。



   /*******************************************
     * @Homepage  http://f57.aaa.livedoor.jp/~jeanne/
     * @Blog        http://www.ailight.jp/blog/jeanne/
     *******************************************/
こんばんわ、じゃんぬねっとさん。
早速のご回答、ありがとうございます。
私が参考にさせて頂いたモザイク処理のサンプルを
おいているVBのサイトはこちらです。↓

http://tokyo.cool.ne.jp/kanain/APIHTM/Mozaic.html

↑こちらのソースを解析したのですが、お恥ずかしながら、
私の力では、理解できませんでした。。。
当然ながら、VB -> C#をできるだけのスキルもなく、
(VBは経験なし、C#はやり出して2週間位でしょうか…)
具体的に、どの関数をどう使えば、実現できるのか
判らず、皆さまのお知恵をお借りしようと思った次第です。。。

ご存知の方がいらっしゃいましたら、
再度よろしくお願いします。
プロジェクト-プロジェクト名のプロパティ-構成プロパティ-ビルドの
セーフモード以外のコードブロックの許可をtrueにする必要があります。

unsafe public static Color CalcMosaic( BitmapData bitmapDataSrc, int width, int height, int x, int y, int size )
{
    Color color ;
    int r = 0, g = 0, b = 0, count = 0 ;
    double[] Mosaic = new double[3]{0,0,0} ;

    uint * src = (uint *)(void *)bitmapDataSrc.Scan0 ;
    for( int m=0 ; m<size ; m++ ) 
    {
        int i = y + m ;
        int ySrc = i*bitmapDataSrc.Stride/sizeof(uint) ;
        if ( i < 0 || i >= height ) continue ;
        for( int n=0 ; n<size ; n++ ) 
        {
            int j = x + n ;
            if ( j < 0 || j >= width ) continue ;
            color = Color.FromArgb( (int)src[ySrc + j] ) ;
            r += (int)color.R ;
            g += (int)color.G ;
            b += (int)color.B ;
            count ++ ;
        }
    }
    color = Color.FromArgb( (byte)(r/count), (byte)(g/count), (byte)(b/count) ) ;
    return color ;
}

public static void Mosaic( out Bitmap bitmapdst, Bitmap bitmapsrc, int size )
{
    bitmapdst = new Bitmap( bitmapsrc.Width, bitmapsrc.Height ) ;
    Rectangle rectangle = new Rectangle( 0,0, bitmapsrc.Width, bitmapsrc.Height ) ;
    BitmapData bitmapDataSrc = bitmapsrc.LockBits( rectangle, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb ) ;
    BitmapData bitmapDataDst = bitmapdst.LockBits( rectangle, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb ) ;

    unsafe
    {
        uint * dst = (uint *)(void *)bitmapDataDst.Scan0 ;

        for( int y=0 ; y<bitmapsrc.Height ; y+=size )
        {
            for( int x=0 ; x <bitmapsrc.Width ; x+=size )
            {
                Color mosaic = CalcMosaic( bitmapDataSrc, bitmapsrc.Width, bitmapsrc.Height, x, y, size ) ;
                for( int m=0 ; m<size ; m++ ) 
                {
                    int i = y + m ;
                    int yDst = i*bitmapDataDst.Stride/sizeof(uint) ;
                    if ( i < 0 || i >= bitmapsrc.Height ) continue ;
                    for( int n=0 ; n<size ; n++ ) 
                    {
                        int j = x + n ;
                        if ( j < 0 || j >= bitmapsrc.Width ) continue ;
                        dst[yDst + j] = (uint)mosaic.ToArgb() ;
                    }
                }
            }
        }
    }

    bitmapdst.UnlockBits(bitmapDataDst);
    bitmapsrc.UnlockBits(bitmapDataSrc);
}

[使い方 pictureBox1.Image を 10dotでモザイクする]
Bitmap bitmap = new Bitmap( pictureBox1.Image ) ;
Mosaic( out bitmap, dispBitmap, 10 ) ;
pictureBox1.Image = bitmap ;
dispBitmap = bitmap ;

このページの応用ですのであわせてみてください。
http://www.geocities.jp/mnow/cs_bitmap1.html
> [使い方 pictureBox1.Image を 10dotでモザイクする]
> Bitmap bitmap = new Bitmap( pictureBox1.Image ) ;
> Mosaic( out bitmap, dispBitmap, 10 ) ;
> pictureBox1.Image = bitmap ;
> dispBitmap = bitmap ;
Bitmap は new する必要なかったようですね。
Bitmap bitmap ;
Mosaic( out bitmap, dispBitmap, 10 ) ;
pictureBox1.Image = bitmap ;
dispBitmap = bitmap ;

あと dispBitmap は例えばこんな感じ
Bitmap dispBitmap = null ;

private void button1_Click(object sender, System.EventArgs e)
{
    DialogResult res = openFileDialog1.ShowDialog() ;
    if ( res == DialogResult.OK )
    {
        FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
        Bitmap bitmap = new Bitmap( System.Drawing.Image.FromStream(fs) ) ;
        fs.Close();
        pictureBox1.Image = bitmap ;
        dispBitmap = bitmap ;
    }
}
おはようございます、えムナウさん。
丁寧に参考になるソースまで、教えて下さって
本当にありがとうございます。
早速、解析させて頂きますね。

もしかしたら、教えて頂いたソースについて
質問をさせて頂く事があるかもしれません。
その時は申し訳ありませんが、よろしくお願い致します。

DOBON.NET | プログラミング道 | プログラミング掲示板