• 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;
                }
            }  
  • 相关阅读:
    Jmeter 04 JMeter 负载与监听
    《Python 机器学习》笔记(四)
    《动手学深度学习(李沐)》笔记3
    《动手学深度学习(李沐)》笔记2
    《动手学深度学习(李沐)》笔记1
    Latex排版全解(转)
    《Python机器学习》笔记(三)
    《数据挖掘导论》笔记(四)
    Latex技巧:在图表序号中加入章节号(实现诸如“图1.1.2”这样的图表序号)
    Latex技巧:插入参考文献
  • 原文地址:https://www.cnblogs.com/tlduck/p/6146267.html
Copyright © 2020-2023  润新知