首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

C# Bitmap、Image怎么能快速的获取:Stream(流)、或是byte[],哪位高手能帮小弟我优化一下这代码段

2012-04-01 
C# Bitmap、Image如何能快速的获取:Stream(流)、或是byte[],谁能帮我优化一下这代码段。C# codeprivate void

C# Bitmap、Image如何能快速的获取:Stream(流)、或是byte[],谁能帮我优化一下这代码段。

C# code
        private void button_AsyncWriteFileTest_Click(object sender, EventArgs e)        {            Image image = pictureBox_Image.Image;//54MB左右的大图            Stopwatch st = new Stopwatch();            st.Reset();            st.Start();            //Bitmap、Image如何能快速的获取:Stream(流)、或是byte[]            //以下是为了获取Stream流对象            MemoryStream ms = new MemoryStream();            image.Save(ms, image.RawFormat);//4467,4秒多,很慢            st.Stop();            MessageBox.Show(st.ElapsedMilliseconds.ToString());            st.Reset();            st.Start();            //以下是为了获取byte[]二进制数据            byte[] bytes = ms.ToArray();//28,0.028秒,很快            st.Stop();            MessageBox.Show(st.ElapsedMilliseconds.ToString());            int stateObjBufferSize = 1024;            FileStream fs = new FileStream(                Application.StartupPath + "\\TestAsyncWriteFile.test",                FileMode.OpenOrCreate, System.Security.AccessControl.FileSystemRights.FullControl,                FileShare.None, stateObjBufferSize, FileOptions.Asynchronous);            AsyncWorkStateObj<FileStream> workStateObj = new AsyncWorkStateObj<FileStream>(fs, bytes.Length);            workStateObj.Buffer = bytes;            fs.BeginWrite(workStateObj.Buffer, 0, workStateObj.BufferSize, new AsyncCallback(BeginWrite), workStateObj);        }        private void BeginWrite(IAsyncResult ia)        {            AsyncWorkStateObj<FileStream> awso = ia.AsyncState as AsyncWorkStateObj<FileStream>;            FileStream fs = awso.Worker;            fs.EndWrite(ia);            MessageBox.Show("写文件成功");            fs.Close();            fs = null;        }


就是想优化获取流,或是二进制数据的问题。现在这方法感觉太慢了。

[解决办法]
建议你用Bitmap.LockBits方法,数据在BitmapData.Scan0中,不过你要用unsafe的指针操作来提取数据,

PixelFormat eFormat = PixelFormat.Format24bppRgb;

Rectangle rcTargetLock=new Rectangle(0,0,rTargetBitmap.Width,rTargetBitmap.Height);
BitmapData rTargetBd = rTargetBitmap.LockBits(rcTargetLock, ImageLockMode.WriteOnly, eFormat);

[解决办法]
// バイト配列をImageオブジェクトに変換
 public static Image ByteArrayToImage(byte[] b) {
ImageConverter imgconv = new ImageConverter();
Image img = (Image)imgconv.ConvertFrom(b);
return img;
 }
 
// Imageオブジェクトをバイト配列に変換
 public static byte[] ImageToByteArray(Image img) {
ImageConverter imgconv = new ImageConverter();
byte[] b = (byte[])imgconv.ConvertTo(img, typeof(byte[]));
return b;
 }
 
[解决办法]
BitmapData
lock
scan0 操作
unlock
[解决办法]
C# code
Bitmap bmp = new Bitmap("c:\\fakePhoto.jpg");     // Lock the bitmap's bits.      Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);     System.Drawing.Imaging.BitmapData bmpData =         bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,         bmp.PixelFormat);     // Get the address of the first line.    IntPtr ptr = bmpData.Scan0;     // Declare an array to hold the bytes of the bitmap.     // This code is specific to a bitmap with 24 bits per pixels.     int bytes = bmp.Width * bmp.Height * 3;     byte[] rgbValues = new byte[bytes];     // Copy the RGB values into the array.     System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);     // Set every red value to 255.      for (int counter = 0; counter < rgbValues.Length; counter+=3)         rgbValues[counter] = 255;     // Copy the RGB values back to the bitmap     System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);     // Unlock the bits.     bmp.UnlockBits(bmpData);     // Draw the modified image.     e.Graphics.DrawImage(bmp, 0, 150); 

热点排行