24h購物| | PChome| 登入
2011-03-04 17:13:29| 人氣5,234| 回應1 | 上一篇 | 下一篇

[C#] 影像Brightness, Contrast, Saturation調整

推薦 0 收藏 0 轉貼0 訂閱站台



程式碼如下:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.IO;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            ResetImageSettings();
        }
        Bitmap myBitmap = null;
        private void button1_Click(object sender, EventArgs e)     ////載入圖檔
        {
            this.openFileDialog1.Filter = "所有檔案|*.*|BMP File| *.bmp|JPEG File|*.jpg| GIF File|*.gif";

            if (openFileDialog1.ShowDialog() == DialogResult.OK)   ////由對話框選取圖檔
            {
                myBitmap = new Bitmap(openFileDialog1.FileName);
                pictureBox1.Image = myBitmap;
            }
        
            ResetImageSettings();
             pictureBox2.Image = null;
        }

        private void button2_Click(object sender, EventArgs e)  ///灰階影像處理
        {
            int[, ,] ImgData = GetImgData(myBitmap);
            ImageAdjust(ImgData,  trackBarBright.Value, trackBarContrast.Value, trackBarSaturation.Value);
            Bitmap processedBitmap = CreateBitmap(ImgData);
            pictureBox2.Image = processedBitmap;

        }
        private int[, ,] GetImgData(Bitmap myBitmap)
        {
            int[,,] ImgData = new int[myBitmap.Width, myBitmap.Height, 3];
            BitmapData byteArray = myBitmap.LockBits(new Rectangle(0, 0, myBitmap.Width, myBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            int ByteOfSkip = byteArray.Stride - byteArray.Width * 3;
            unsafe
            {
                byte* imgPtr = (byte*)(byteArray.Scan0);
                for (int y = 0; y < byteArray.Height; y++)
                {
                    for (int x = 0; x < byteArray.Width; x++)
                    {
                        ImgData[x, y, 2] = (int) *(imgPtr);
                        ImgData[x, y, 1] = (int) *(imgPtr + 1);
                        ImgData[x, y, 0] = (int) *(imgPtr + 2);
                        imgPtr += 3;
                    }
                    imgPtr += ByteOfSkip;
                }
            }
            myBitmap.UnlockBits(byteArray);
            return ImgData;
        }

        public static Bitmap CreateBitmap(int[, ,] ImgData)
        {   
            int Width = ImgData.GetLength(0);
            int Height = ImgData.GetLength(1);
            Bitmap myBitmap = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);

            BitmapData byteArray = myBitmap.LockBits(new Rectangle(0, 0, Width, Height),
                                           ImageLockMode.WriteOnly,
                                           PixelFormat.Format24bppRgb);
         
            //Padding bytes的長度
            int ByteOfSkip = byteArray.Stride - myBitmap.Width * 3;

            unsafe
            {                                   // 指標取出影像資料
                byte* imgPtr = (byte*) byteArray.Scan0;
                for (int y = 0; y < Height; y++)
                {
                    for (int x = 0; x < Width; x++)
                    {
                        *imgPtr = (byte)ImgData[x, y, 2];       //B
                      
                        *(imgPtr+1) = (byte)ImgData[x, y, 1];   //G
                      
                        *(imgPtr+2) = (byte)ImgData[x, y, 0];   //R 
                        imgPtr += 3;
                    }
                    imgPtr += ByteOfSkip; // 跳過Padding bytes
                }
            }
            myBitmap.UnlockBits(byteArray);
            return myBitmap;
        }

        private void ImageAdjust(int[, ,] ImgData, int Brightness, int Contrast, int Saturation)
        {
            int Width = ImgData.GetLength(0);
            int Height = ImgData.GetLength(1);
            int R, G, B;
            int Y, Cb, Cr;
          
          
            for (int y = 0; y < Height; y++)
            {
                for (int x = 0; x < Width; x++)
                {
                    R = ImgData[x, y, 0]; G = ImgData[x, y, 1]; B = ImgData[x, y, 2];

                    Y = (int) ((double) R * 0.299  + (double) G * 0.587 + (double) B * 0.114);
                  
                    Y = Math.Max(Math.Min(Y, 255), 0);
                    Cb = (int)((double)R * -0.16874 + (double)G * -0.33126 + (double)B * 0.50000) + 128;
                    Cb = Math.Max(Math.Min(Cb, 255), 0);
                    Cr = (int)((double)R * 0.50000 + G * -0.41869 + (double)B * -0.08131) + 128;
                    Cr = Math.Max(Math.Min(Cr, 255), 0);

                    Y = (int) ((double)(Contrast + 100) * (double)Y / (double)100) + Brightness;
                    Y = Math.Max(Math.Min(Y, 255), 0);

                    Cb = (int) ((double) (Cb - 128 ) * (double) (Saturation + 100) / 100.0) + 128;
                    Cr = (int) ((double)(Cr - 128) * (double)(Saturation + 100) / 100.0) + 128;

                    ImgData[x, y, 0] = (int)((double)Y + 1.402 * (double)(Cr - 128));
                    ImgData[x,y,0] = Math.Max(Math.Min(ImgData[x,y,0], 255), 0);
                    ImgData[x, y, 1] = (int)((double)Y - 0.34414 * (double)(Cb - 128) - 0.71414 * (double)(Cr - 128));
                    ImgData[x,y,1] = Math.Max(Math.Min(ImgData[x,y,1], 255), 0);
                    ImgData[x, y, 2] = (int)((double)Y + 1.772 * (double)(Cb - 128));
                    ImgData[x,y,2] = Math.Max(Math.Min(ImgData[x,y,2], 255), 0);
                }
            }
        }

        private void btnSaveImg_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            string curDir;
            curDir = Directory.GetCurrentDirectory();

            saveFileDialog1.InitialDirectory = curDir;

            saveFileDialog1.Filter = "JPG File|*.jpg";
            saveFileDialog1.Title = "儲存影像檔";
            saveFileDialog1.FilterIndex = 3;
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {

                saveJpeg(saveFileDialog1.FileName, myBitmap, 85);
            }

        }
        private void saveJpeg(string path, Bitmap img, long quality)
        {
            // Encoder parameter for image quality
            EncoderParameter qualityParam = new EncoderParameter(Encoder.Quality, quality);

            // Jpeg image codec
            ImageCodecInfo jpegCodec = this.getEncoderInfo("image/jpeg");


            if (jpegCodec == null)
                return;

            EncoderParameters encoderParams = new EncoderParameters(1);
            encoderParams.Param[0] = qualityParam;

            img.Save(path, jpegCodec, encoderParams);
        }

        private ImageCodecInfo getEncoderInfo(string mimeType)
        {
            // Get image codecs for all image formats
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
            // Find the correct image codec
            for (int i = 0; i < codecs.Length; i++)
                if (codecs[i].MimeType == mimeType)
                    return codecs[i];
            return null;
        }
       
      
        private void trackBarBright_Scroll(object sender, EventArgs e)
        {
            lblBrightValue.Text = String.Format("{0:D}", trackBarBright.Value);
        }

        private void trackBarContrast_Scroll(object sender, EventArgs e)
        {
            lblContrastValue.Text = String.Format("{0:D}", trackBarContrast.Value);
        }

        private void trackBarSaturation_Scroll(object sender, EventArgs e)
        {
            lblSaturationValue.Text = String.Format("{0:D}", trackBarSaturation.Value);
        }
        private void ResetImageSettings()
        {
            trackBarBright.Value = 0; trackBarContrast.Value = 0; trackBarSaturation.Value = 0;
            lblBrightValue.Text = String.Format("{0:D}", trackBarBright.Value);
            lblContrastValue.Text = String.Format("{0:D}", trackBarContrast.Value);
            lblSaturationValue.Text = String.Format("{0:D}", trackBarSaturation.Value);
        }
    }
}


參考文章:

ColorMatrix Image Hue Saturation Contrast Brightness in C# .NET GDI+

台長: Chris C.S Huang

您可能對以下文章有興趣

人氣(5,234) | 回應(1)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: [C#] 影像處理 |
此分類上一篇:[C#] Image Histogram

AES
請問這有更詳細的說明嗎
例如 元件的屬性名稱等等
2012-07-14 23:59:04
是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文