C# Bitmap、Image怎么能快速的获取:Stream(流)、或是byte[],哪位高手能帮小弟我优化一下这代码段
C# Bitmap、Image如何能快速的获取:Stream(流)、或是byte[],谁能帮我优化一下这代码段。
就是想优化获取流,或是二进制数据的问题。现在这方法感觉太慢了。
------解决方案--------------------
建议你用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
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);