※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

小さなフィルタのサンプルをマルチスレッドにしてみた。
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;
       }

   }

}