C# byte數組轉成Bitmap對象


方法一:

        /// <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;
            }
        }  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM