2012年5月5日 星期六

匯整數個例子在一個專案(轉黑白照、反轉顏色..等)

利用高效率的方法寫出「轉成黑白照」、「反轉顏色」、「紅色瀘鏡」、「綠色瀘鏡」、「藍色瀘鏡」、「增加亮度」。







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.Drawing .Imaging ;

namespace 紅色綠色藍色瀘鏡
{
    public partial class Form1 : Form
    {
     
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {   OpenFileDialog openFileDialog1 = new OpenFileDialog();
        openFileDialog1.InitialDirectory = "D:\\MyPhoto";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                ImageForm image = new ImageForm(openFileDialog1.FileName);// 建立秀圖物件
                image.ColorFilter(0);
                image.Show();
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
           OpenFileDialog openFileDialog1 = new OpenFileDialog();
           openFileDialog1.InitialDirectory = "D:\\MyPhoto";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                ImageForm image = new ImageForm(openFileDialog1.FileName);// 建立秀圖物件
                image.ColorFilter(1);
                image.Show();
            }
         
        }

        private void button3_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.InitialDirectory = "D:\\MyPhoto";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                ImageForm image = new ImageForm(openFileDialog1.FileName);// 建立秀圖物件
                image.ColorFilter(2);
                image.Show();
            }
        }
        private void button4_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.InitialDirectory = "D:\\MyPhoto";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                ImageForm image = new ImageForm(openFileDialog1.FileName);// 建立秀圖物件
                image.Light();
                image.Show();
            }
         
        }
        private void button5_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.InitialDirectory = "D:\\MyPhoto";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                ImageForm image = new ImageForm(openFileDialog1.FileName);// 建立秀圖物件
                image.doGray();
                image.Show();
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.InitialDirectory = "D:\\MyPhoto";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                ImageForm image = new ImageForm(openFileDialog1.FileName);// 建立秀圖物件
                image.InvertFirst();
                image.Show();
            }
        }
        class ImageForm : Form
        {
            Image image;
            public ImageForm(String Filename)
            {
                image=Image.FromFile(Filename);
                this.Text=Filename;
            }
            protected override void OnPaint(PaintEventArgs e)
            {
                this.Width=image.Width;
                this.Height=image.Height;
                //image.Save(@"c:\\Result.jpg", ImageFormat.Jpeg);
                e.Graphics.DrawImage(image,0,0,image.Width,image.Height);
             
            }
         
         
            public static int[, ,] getRGBData(Bitmap bimage) {
             
            // Step 1: 先鎖住存放圖片的記憶體
            BitmapData bmData = bimage.LockBits(new Rectangle(0, 0, bimage.Width, bimage.Height),
                                           ImageLockMode.ReadOnly,
                                           PixelFormat.Format24bppRgb);
            int stride = bmData.Stride;

            // Step 2: 取得像點資料的起始位址
            System.IntPtr Scan0 = bmData.Scan0;

            // 計算每行的像點所佔據的byte 總數
            int ByteNumber_Width = bimage.Width * 3;

            // 計算每一行後面幾個 Padding bytes
            int ByteOfSkip = stride - ByteNumber_Width;

            int Height=bimage.Height ;
            int Width=bimage.Width ;
            int[, ,] rgbData = new int[Width, Height, 3];

            // Step 3: 直接利用指標, 把影像資料取出來
            unsafe {
                byte* p = (byte*)(void*)Scan0;//p指向此圖的起始點
                for (int y = 0; y < Height; y++) {
                    for (int x = 0; x < Width; x++) {//寫入順序為BGR,不是RBG
                        rgbData[x, y, 2] = p[0];    // B
                        ++p;
                        rgbData[x,y,1]=p[0];        // G
                        ++p;
                        rgbData[x,y,0]=p[0];        // R
                        ++p;
                    }
                    p += ByteOfSkip; // 跳過剩下的 Padding bytes
                }
            }

            bimage.UnlockBits(bmData);//取消記憶體鎖定
            return rgbData;
        }
         
            public void ColorFilter(int Select)
            {
                Bitmap bimage = new Bitmap(image);

                // Step 1: 取出顏色資料
                int[, ,] rgbData = getRGBData(bimage);

                // Step 2: 數位影像處理
                //  將所有顏色 Channel 資料改成 0, 只留下紅色區域
                int Width = rgbData.GetLength(0);
                int Height = rgbData.GetLength(1);
             
                for (int y = 0; y < Height; y++)
                {
                    for (int x = 0; x < Width; x++)
                    {
                        switch (Select)
                        {
                            case 0: // 紅色濾鏡功能
                                rgbData[x, y, 1] = 0; // Green Channel 改成 0
                                rgbData[x, y, 2] = 0; // Blue Channel 改成 0
                                break;
                            case 1: // 綠色濾鏡功能
                                rgbData[x, y, 0] = 0; // Red Channel 改成 0
                                rgbData[x, y, 2] = 0; // Blue Channel 改成 0
                                break;
                            case 2: // 藍色濾鏡的功能
                                rgbData[x, y, 0] = 0; // Red Channel 改成 0
                                rgbData[x, y, 1] = 0; // Blue Channel 改成 0
                                break;
                            default:
                                break;
                        }

                    }
                }

                // Step 3: 將處理後的資料寫回 image
                bimage=setRGBData(rgbData);
                image = bimage;
                this.Refresh();
            }
         
            public static Bitmap setRGBData(int[, ,] rgbData) {

            int Width=rgbData.GetLength(0);
            int Height=rgbData.GetLength(1);

            Bitmap bimage = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);

            // Step 1: 先鎖住存放圖片的記憶體
            BitmapData bmData = bimage.LockBits(new Rectangle(0, 0, Width, Height),
                                           ImageLockMode.WriteOnly,
                                           PixelFormat.Format24bppRgb);
            int stride = bmData.Stride;

            // Step 2: 取得像點資料的起始位址
            System.IntPtr Scan0 = bmData.Scan0;

            // 計算每行的像點所佔據的byte 總數
            int ByteNumber_Width = bimage.Width * 3;

            // 計算每一行後面幾個 Padding bytes
            int ByteOfSkip = stride - ByteNumber_Width;
         

            // Step 3: 直接利用指標, 把影像資料取出來
            unsafe {
                byte* p = (byte*)(void*)Scan0;
                for (int y = 0; y < Height; y++) {
                    for (int x = 0; x < Width; x++) {
                        p[0] = (byte) rgbData[x, y, 2] ; // 先放 B

                        ++p;
                        p[0] = (byte) rgbData[x, y, 1];  // 再放 G
                        ++p;
                        p[0] = (byte) rgbData[x, y, 0];  // 最後放 R
                        ++p;
                    }
                    p += ByteOfSkip; // 跳過剩下的 Padding bytes
                }
            }

            bimage.UnlockBits(bmData);
            return bimage;    
        }
            public void Light()
            {
                Bitmap bimage = new Bitmap(image);
                int[, ,] rgb = getRGBData(bimage);
                this.Height = bimage.Height;
                this.Width = bimage.Width;
                int g;
                for (int y = 0; y < Height; y++)
                {
                    for (int x = 0; x < Width; x++)
                    {
                        for (int c = 0; c < 3; c++)
                        {
                            g = rgb[x, y, c];
                            g += 30;
                            if (g > 255) g = 255;
                            rgb[x, y, c] = g;
                        }
                    }
                }
                bimage = setRGBData(rgb );
                image = bimage;
                this.Refresh();
            }
            public void InvertFirst()
            {
                Bitmap bimage = new Bitmap(image);
                image=Invert(bimage);
                this.Refresh();
            }
            public static Bitmap Invert(Bitmap bimage)
            {
             
             
                BitmapData bmData = bimage.LockBits(new Rectangle(0, 0, bimage.Width, bimage.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                int stride = bmData.Stride;
                System.IntPtr Scan0 = bmData.Scan0;
                int ByteNumber_Width = bimage.Width * 3;
                int ByteOfSkip = stride - ByteNumber_Width;
                int Height = bimage.Height ;

                unsafe
                {
                    byte* p = (byte*)(void*)Scan0 ;
                    for (int y = 0; y < Height; y++)
                    {
                        for (int x = 0; x < ByteNumber_Width; x++)
                        {
                            p[0] = (byte)(255 - p[0]);
                            p++;
                        }
                        p += ByteOfSkip;
                    }
                }
                bimage.UnlockBits(bmData);
                return bimage;
            }
            public void doGray()
            {
                Bitmap bimage = new Bitmap(image);
                this.Height = bimage.Height;
                this.Width = bimage.Width;
                int[, ,] rgb = getRGBData(bimage);
                for (int y = 0; y < Height; y++)
                {
                    for(int x = 0; x < Width; x++)
                    {
                        int gray = (rgb[x, y, 0] + rgb[x, y, 1] + rgb[x, y, 2]) / 3;
                        bimage.SetPixel (x,y,Color.FromArgb(gray,gray,gray));

                    }
                }
                image = bimage;
                this.Refresh();

            }
           }   
        }
    }




沒有留言:

張貼留言