C# 指標法24點陣圖轉8位
阿新 • • 發佈:2019-02-13
用指標操作,將24位的彩色影象轉換位8位的灰度圖
試了速度是9ms,比之前的那種方法快了很多。
注意unsafe,勾選允許不安全的程式碼。
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; using System.Diagnostics; namespace my24to8Sec { public partial class Form1 : Form { Bitmap mypic; Stopwatch st; public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { OpenFileDialog op = new OpenFileDialog(); if (op.ShowDialog() == DialogResult.OK) { mypic = (Bitmap)Bitmap.FromFile(op.FileName); pictureBox1.Image = mypic; } } private void button2_Click(object sender, EventArgs e) { if(mypic!=null) { st = new Stopwatch(); st.Start(); int w=mypic.Width; int h=mypic.Height; int gray = 0; Bitmap bit = new Bitmap(w, h, PixelFormat.Format8bppIndexed); BitmapData dataIn = mypic.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); BitmapData dataOut = bit.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); unsafe { byte* pIn = (byte*)(dataIn.Scan0.ToPointer()); //指向原始檔首地址 byte* pOut = (byte*)(dataOut.Scan0.ToPointer()); //指向目標檔案首地址 for (int y = 0; y < dataIn.Height; y++) //列掃描 { for (int x = 0; x < dataIn.Width; x++) //行掃描 { // gray = (pIn[0] * 19595 + pIn[1] * 38469 + pIn[2] * 7472) >> 16; //灰度計算公式 這個借鑑別人,這種運算方式能提高部分速度 gray = (int)(pIn[0] * 0.299 + pIn[1] * 0.587 + pIn[2] * 0.114); pOut[0] = (byte)gray; pIn += 3; pOut += 1; } pIn += dataIn.Stride - dataIn.Width * 3; pOut += dataOut.Stride - dataOut.Width; } } ColorPalette tempPalette; { using (Bitmap tempBmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed)) { tempPalette = tempBmp.Palette; } for (int i = 0; i < 256; i++) { tempPalette.Entries[i] = Color.FromArgb(i, i, i); } bit.Palette = tempPalette; } bit.UnlockBits(dataOut); mypic.UnlockBits(dataIn); st.Stop(); textBox1.Text = st.ElapsedMilliseconds.ToString(); pictureBox1.Image = bit; } } } }