C# byte数组转成Bitmap对象

Posted 淹死的鸭子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
            }
        }  

 

以上是关于C# byte数组转成Bitmap对象的主要内容,如果未能解决你的问题,请参考以下文章

C#图片灰度处理(位深度24→位深度8),用灰度数组byte[]新建一个8位灰度图像Bitmap 。

C# 字节数组与字符串互相转换

通过BitmapFactory.decodeByteArray把byte[]转成Bitmap出现的OOM的解决方法

C# Bitmap类型与Byte[]类型相互转化

如何将interface 转成struct数组

(C#)把一个byte数组转换成一个二进制流!