方法一:
/// <summary> /// 將數組轉換成彩色圖片 /// </summary> /// <param name="rawValues">圖像的byte數組</param> /// <param name="width">圖像的寬</param> /// <param name="height">圖像的高</param> /// <returns>Bitmap對象</returns> public Bitmap ToColorBitmap(byte[] rawValues, int width, int height) { //// 申請目標位圖的變量,並將其內存區域鎖定 try { if (width != oldPicWidth || height != oldPicHeight)//如果圖像尺寸發生變化,則需要重新new一下Bitmap對象 { if (m_currBitmap != null) m_currBitmap = null; m_currBitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb); m_rect = new Rectangle(0, 0, width, height); m_bitmapData = m_currBitmap.LockBits(m_rect, ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); } IntPtr iptr = m_bitmapData.Scan0; // 獲取bmpData的內存起始位置 //// 用Marshal的Copy方法,將剛才得到的內存字節數組復制到BitmapData中 System.Runtime.InteropServices.Marshal.Copy(rawValues, 0, iptr, width * height * 3); if (width != oldPicWidth || height != oldPicHeight) { m_currBitmap.UnlockBits(m_bitmapData); oldPicWidth = width; oldPicHeight = height; } //// 算法到此結束,返回結果 return m_currBitmap; } catch (System.Exception ex) {
return null; } }
上述方法有個問題,如果是從在線視頻流中取數據,如果在短時間內,多次調用此方法,則會拋GDI+異常,或者提示Bitmap對象被占用。為了解決這個問題,后來想到了用Bitmap數組來解決。
方法如下
方法二:
private Bitmap[] m_pBitmaps = new Bitmap[15]; private int m_nCurrBitmapIdx = -1; public Bitmap ToColorBitmap2(byte[] rawValues, int width, int height) { // 申請目標位圖的變量,並將其內存區域鎖定 //初始化Bitmap數組 if (m_bFrmSizeChange || m_nCurrBitmapIdx < 0) { for (int i = 0; i < 15; i++) { m_pBitmaps[i] = new Bitmap(width, height, PixelFormat.Format24bppRgb); } m_nCurrBitmapIdx = 0; m_bFrmSizeChange = false; } Bitmap bmp = m_pBitmaps[m_nCurrBitmapIdx]; m_nCurrBitmapIdx++; if (m_nCurrBitmapIdx >= 15) m_nCurrBitmapIdx = 0; try { //Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb); BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); //// 獲取圖像參數 //int stride = bmpData.Stride; // 掃描線的寬度 IntPtr iptr = bmpData.Scan0; // 獲取bmpData的內存起始位置 //int scanBytes = stride * height;// 用stride寬度,表示這是內存區域的大小 //// 用Marshal的Copy方法,將剛才得到的內存字節數組復制到BitmapData中 System.Runtime.InteropServices.Marshal.Copy(rawValues, 0, iptr, width * height * 3); bmp.UnlockBits(bmpData); // 解鎖內存區域 //// 算法到此結束,返回結果 return bmp; } catch (System.Exception e) { //Tools.m_CreateLogTxt("ToColorBitmap2", e.ToString(), Index); return null; } }