「小さなフィルタのサンプル1-2」の編集履歴(バックアップ)一覧に戻る

小さなフィルタのサンプル1-2 - (2010/06/10 (木) 16:23:05) のソース

[[小さなフィルタのサンプル]]をマルチスレッドにしてみた。
C#で人生初スレッド。

マルチスレッドは、デッドロックだの処理の排他的制御だの複雑な話も増えるが、現実に役に立つアプリやゲームアプリで絶対必須なので、これは大事なのだった。
実現したいものが複雑である以上、コードがそれに対応した複雑さになるのは当然の話だけど、マルチスレッドとか苦手。



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
public delegate void ExampleCallback(Bitmap outBit,PictureBox p1);

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        int tc = 0;
        Bitmap lastB;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Bitmap b1 = new Bitmap(pictureBox1.Image);    // 変数の宣言
            //pictureBox1.Image  =b1;


            pictFilter PTC = new WindowsFormsApplication2.pictFilter(b1, new ExampleCallback(ResultCallback),pictureBox1);
            Thread t1 =new Thread(new ThreadStart(PTC.cercleChange));
            t1.Start();
            t1.Join();
            //pictureBox1.Image = PTC.cercleChange();
            //            pictureBox1.Image = PTC.flatFilter2( PTC.cercleChange      (b1)) ;
            //b1.Dispose();
        }
        public static void ResultCallback(Bitmap outBit,PictureBox p1)
        {
            p1.Image = outBit;
        }


        private void pictureBox1_Click(object sender, EventArgs e)
        {
            tc++;
            if (tc == 1)
            {
                pictureBox1.Image = Image.FromFile("D:/色々/中高生向け戦争小説 ギガンダム討伐/11161658_m.png");
            }
            else if (tc == 2)
            {
                pictureBox1.Image = Image.FromFile("D:/色々/中高生向け戦争小説 ギガンダム討伐/11129096_m.jpg");
            }
            else if (tc == 3)
            {
                pictureBox1.Image = Image.FromFile("D:/色々/中高生向け戦争小説 ギガンダム討伐/9933981.jpg");
            }
                pictureBox1.Height = 1200;
            pictureBox1.Width  = 1000;
            pictureBox1.Top = 0;
            pictureBox1.Left = 0; 
            
        }

    }
    class pictFilter
    {
        Random rnd = new Random();
        Bitmap pictOut = null;
        int h;//絵の高さ
        int w;//絵の横幅
        Bitmap pictIn;
        ExampleCallback callback;
        PictureBox lastPict;


        public pictFilter(Bitmap b1, ExampleCallback callbackDelegate,PictureBox p1)
        {
            this.pictIn=b1; 
            h = 0;
            w = 0;
            callback = callbackDelegate;
            lastPict = p1; 
        }
        public Bitmap cercleChange2(Bitmap pictIn)
        {
            //各ピクセルの色空間内の位置を点(ccR,ccB,ccG)を中心に体積拡大する処理
            float ccR = 118;
            float ccG = 118;
            float ccB = 118;
            float a = -1.0f;
            float b = 2.0f;
            double cR, cG, cB;
            double r1 = 0;
            double r2 = 0;
            Color CC,CU,CD,CR,CL;

            this.h = pictIn.Height;
            this.w = pictIn.Width;
            pictOut = new Bitmap(this.w, this.h);

            for (int i = 1; i < this.w-1; i++)
            {
                for (int j = 1; j < this.h-1; j++)
                {
                    CC = pictIn.GetPixel(i, j);
                    CU = pictIn.GetPixel(i, j-1);
                    CD = pictIn.GetPixel(i, j + 1);
                    CR = pictIn.GetPixel(i+1, j);
                    CL = pictIn.GetPixel(i + 1, j);

                }
            }
            return pictOut;



            //テンプレ
            //this.h = pictIn.Height;
            //this.w = pictIn.Width;
            //pictOut = new Bitmap(this.w, this.h);
            //for(int i=0;i<this.w;i++){
            //    for (int j = 0; j < this.h; j++)
            //    {   
            //    }
            //}
            //return pictOut;
        }
        public void cercleChange()
        {
            //各ピクセルの色空間内の位置を点(ccR,ccB,ccG)を中心に体積拡大する処理
            float  ccR = 118;
            float  ccG = 118;
            float  ccB = 118;
            float a=-1.0f;
            float b =2.0f;
            double cR, cG, cB;
            double r1=0;
            double r2 = 0;
            Color C1;
            double rk;

            this.h = pictIn.Height;
            this.w = pictIn.Width;
            pictOut = new Bitmap(this.w, this.h);

            for(int i=0;i<this.w;i++){
                for (int j = 0; j < this.h; j++)
                {
                    C1 = pictIn.GetPixel(i, j);
                    r1 = Math.Sqrt( (C1.R - ccR) * (C1.R - ccR) +
                        (C1.G - ccG) * (C1.G - ccG) +
                        (C1.B - ccB) * (C1.B - ccB))/225;
                    
                    r2 = (a * r1 + b);
                    cR = r2  *(C1.R - ccR) + ccR;
                    cG = r2  *(C1.G - ccG) + ccG;
                    cB = r2  *(C1.B - ccB) + ccB;


                    pictOut.SetPixel(i,j, 
                        Color.FromArgb(
                        cutNum (0,255,(int)(cR)),
                        cutNum(0,255,(int)(cG)),
                        cutNum(0,255,(int)(cB))));
                    //これはLispではありませんw
                }
            }
            callback (pictOut,lastPict);
            


            //テンプレ
            //this.h = pictIn.Height;
            //this.w = pictIn.Width;
            //pictOut = new Bitmap(this.w, this.h);
            //for(int i=0;i<this.w;i++){
            //    for (int j = 0; j < this.h; j++)
            //    {   
            //    }
            //}
            //return pictOut;
        }
        public Bitmap flatFilter2(Bitmap pictIn)
        {
            //色空間内の点の色座標をを法線ベクトル(1,1,1),rgbAve=r+g+bとなる平面から遠くへ引き離したり、近づけたりする処理
            Color C1;
            this.h = pictIn.Height;
            this.w = pictIn.Width;
            double  flatLen = 0;
            double  r1  = 0;
            
            float rgbAve=256;
            pictOut = new Bitmap(this.w, this.h);
            double  a = -1.0;
            double  b =  2.0;
            double root3 = Math.Sqrt(3);
            double v1 = 184;
            double  maxRGB=0,minRGB=0;

            for (int i = 0; i < this.w; i++)
            {
                for (int j = 0; j < this.h; j++)
                {
                    C1 = pictIn.GetPixel(i, j);
                    flatLen =(C1.R + C1.G + C1.B-rgbAve) / (root3); //点と平面までの距離
                    r1 =Math.Sign(flatLen )*(  (a * Math.Abs  (flatLen) / v1 + b));//点と平面までの距離に基づいて、次の点の平面からの距離を決定する。
                    maxRGB =Math.Max(C1.R+r1*v1, Math.Max(C1.G+r1*v1, C1.B+r1*v1));
                    if (maxRGB > 255)
                    {
                        if (C1.R > C1.G && C1.R > C1.B)
                        {
                            r1=  r1-(255 - C1.R)/v1-1 ; 
                        }else if (C1.G > C1.R && C1.G > C1.B)
                        {
                            r1 = r1-(255 - C1.G) / v1-1; 
                        }else{
                            r1 = r1-(255 - C1.B) / v1-1;
                        }
                    }
                    minRGB = Math.Min (C1.R + r1 * v1, Math.Min(C1.G + r1 * v1, C1.B + r1 * v1));
                    if (minRGB < 0)
                    {
                        if (C1.R < C1.G && C1.R < C1.B)
                        {
                            r1 = r1-(C1.R) / v1-1;
                        }
                        else if (C1.G < C1.R && C1.G < C1.B)
                        {
                            r1 = r1-(C1.G) / v1-1;
                        }
                        else
                        {
                            r1 = r1-(C1.B) / v1-1;
                        }
                    }


                    pictOut.SetPixel(i, j, Color.FromArgb(
                        cutNum(0,255,(int)(C1.R+r1*v1)),
                        cutNum(0,255,(int)(C1.G+r1*v1)),
                        cutNum(0,255,(int)(C1.B+r1*v1))));
                }
            }
            return pictOut;
        }


        public Bitmap adsorptionFilter(Bitmap pictIn)
        {
            //テンプレ
            Color C1;
            this.h = pictIn.Height;
            this.w = pictIn.Width;
            pictOut = new Bitmap(this.w, this.h);
            byte maxRGB;
            byte minRGB;
            double  rgbR, rgbG, rgbB; 

            for (int i = 0; i < this.w; i++)
            {
                for (int j = 0; j < this.h; j++)
                {



                    C1 = pictIn.GetPixel(i, j);
                    rgbR =C1.R;
                    rgbG =C1.G;
                    rgbB =C1.B;

                    maxRGB =(byte ) Math.Max(rgbR , Math.Max(rgbG, rgbB));
                    minRGB =(byte ) Math.Min(rgbR , Math.Min(rgbG, rgbB));
                    

                    if (255 - maxRGB < minRGB)
                    {
                        if (rgbR == maxRGB)
                        {
                            rgbR = 255*0.5+rgbR*0.5 ;
                        }
                        else if (rgbB  == maxRGB)
                        {
                            rgbB = 255*0.5+rgbB*0.5;    
                        }
                        else
                        {
                            rgbG = 255*0.5+rgbG*0.5;
                        }
                    }
                    else
                    {
                        if (C1.R == minRGB)
                        {
                            rgbR = rgbR * 0.5;
                        }
                        else if (C1.G == minRGB)
                        {
                            rgbG = rgbG * 0.5;
                        }
                        else
                        {
                            rgbB = rgbB * 0.5;   
                        }
                    }

                    pictOut.SetPixel(i, j,
                        Color.FromArgb(
                            (int)rgbR ,
                            (int)rgbG,
                            (int)rgbB));
                }
            }
            return pictOut;
        }





        public Bitmap lineFilter(Bitmap pictIn)
        {
            //テンプレ
            Color C1;
            this.h = pictIn.Height;
            this.w = pictIn.Width;
            double r1;
            double r2;
            double [] vecOB = {1,1,1};
            double [] vecOH = {0, 0, 0};
            double [] vecOA = {0, 0, 0};
            double [] vecHA = {0, 0, 0};
            double [] vecOA2 = { 0, 0, 0 };
            double LenOH, LenOB,LenHA=0;

            double a = -1.0;
            double b = 2.0;
            LenOB=Math.Sqrt(vecOB[0]* vecOB[0]+vecOB[1]* vecOB[1]+vecOB[2]* vecOB[2]);
            pictOut = new Bitmap(this.w, this.h);



            for (int i = 0; i < this.w; i++)
            {
                for (int j = 0; j < this.h; j++)
                {
                    LenHA = 0;


                    C1 = pictIn.GetPixel(i, j);
                    vecOA[0] = C1.R;
                    vecOA[1] = C1.G;
                    vecOA[2] = C1.B;

                    LenOH =(vecOA[0] *vecOB[0]+vecOA[1] *vecOB[1]+vecOA[2] *vecOB[2])  /LenOB ;


                    for (int k = 0; k < 3; k++)
                    {
                        vecOH[k] = LenOH / LenOB * vecOB[k];
                        vecHA[k] = -vecOH[k] + vecOA[k];
                        LenHA += vecHA[k] * vecHA[k];
                    }
                    LenHA = Math.Sqrt(LenHA );
                    r1 = LenHA / 255.0;
                    r2 = a * r1 + b;


                    for (int k = 0; k < 3; k++)
                    {
                        vecOA2[k] = cutNum(0,255,(int)( r2 * vecHA[k]  + vecOH[k]));
                    }

                    pictOut.SetPixel(i, j,
                        Color.FromArgb(
                            (int)vecOA2[0], 
                            (int)vecOA2[1],
                            (int)vecOA2[2] ));
                }
            }
            return pictOut;
        }


        public Bitmap  flatFilter(Bitmap pictIn){
            //テンプレ
            Color C1;
            this.h = pictIn.Height;
            this.w = pictIn.Width;
            int rgbR,rgbG,rgbB;
            pictOut = new Bitmap(this.w, this.h);



            for(int i=0;i<this.w;i++){
                for (int j = 0; j < this.h; j++)
                {
                    C1 = pictIn.GetPixel(i, j);
                    if (C1.R + C1.G + C1.B > 255)
                    {
                        rgbR = (int )(C1.R * 0.5 + 255 * 0.5);
                        rgbG = (int )(C1.G * 0.5 + 255 * 0.5);
                        rgbB = (int )(C1.B * 0.5 + 255 * 0.5);
                    }
                    else
                    {
                        rgbR = (int )(C1.R * 0.5);
                        rgbG = (int )(C1.G * 0.5);
                        rgbB = (int )(C1.B * 0.5);
                    }
                    pictOut.SetPixel(i, j, Color.FromArgb(rgbR, rgbG, rgbB));  
                }
            }
            return pictOut;
        }


        private int cutNum(int min, int max, int t)
        {
            if (t < min)
            {
                t = min;
            }
            if (t > max)
            {
                t = max;
            }
            return t;
        }

    }

}