zoukankan      html  css  js  c++  java
  • C#中使用byte[]数据,生成Bitmap(256色 灰度 BMP位图)源代码

    /// <summary>
            /// 使用byte[]数据,生成256色灰度 BMP 位图
            /// </summary>
            /// <param name="originalImageData"></param>
            /// <param name="originalWidth"></param>
            /// <param name="originalHeight"></param>
            /// <returns></returns>
            public static Bitmap CreateBitmap(byte[] originalImageData, int originalWidth, int originalHeight)
            {
                //指定8位格式,即256色
                Bitmap resultBitmap = new Bitmap(originalWidth, originalHeight, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);

                //将该位图存入内存中
                MemoryStream curImageStream = new MemoryStream();
                resultBitmap.Save(curImageStream, System.Drawing.Imaging.ImageFormat.Bmp);
                curImageStream.Flush();

                //由于位图数据需要DWORD对齐(4byte倍数),计算需要补位的个数
                int curPadNum = ((originalWidth * 8 + 31) / 32 * 4) - originalWidth;

                //最终生成的位图数据大小
                int bitmapDataSize = ((originalWidth * 8 + 31) / 32 * 4) * originalHeight;

                //数据部分相对文件开始偏移,具体可以参考位图文件格式
                int dataOffset = ReadData(curImageStream, 10, 4);


                //改变调色板,因为默认的调色板是32位彩色的,需要修改为256色的调色板
                int paletteStart = 54;
                int paletteEnd = dataOffset;
                int color = 0;

                for (int i = paletteStart; i < paletteEnd; i += 4)
                {
                    byte[] tempColor = new byte[4];
                    tempColor[0] = (byte)color;
                    tempColor[1] = (byte)color;
                    tempColor[2] = (byte)color;
                    tempColor[3] = (byte)0;
                    color++;

                    curImageStream.Position = i;
                    curImageStream.Write(tempColor, 0, 4);
                }

                //最终生成的位图数据,以及大小,高度没有变,宽度需要调整
                byte[] destImageData = new byte[bitmapDataSize];
                int destWidth = originalWidth + curPadNum;

                //生成最终的位图数据,注意的是,位图数据 从左到右,从下到上,所以需要颠倒
                for (int originalRowIndex = originalHeight - 1; originalRowIndex >= 0; originalRowIndex--)
                {
                    int destRowIndex = originalHeight - originalRowIndex - 1;

                    for (int dataIndex = 0; dataIndex < originalWidth; dataIndex++)
                    {
                        //同时还要注意,新的位图数据的宽度已经变化destWidth,否则会产生错位
                        destImageData[destRowIndex * destWidth + dataIndex] = originalImageData[originalRowIndex * originalWidth + dataIndex];
                    }
                }


                //将流的Position移到数据段   
                curImageStream.Position = dataOffset;

                //将新位图数据写入内存中
                curImageStream.Write(destImageData, 0, bitmapDataSize);

                curImageStream.Flush();

                //将内存中的位图写入Bitmap对象
                resultBitmap = new Bitmap(curImageStream);

                return resultBitmap;
            }

            /// <summary>
            /// 从内存流中指定位置,读取数据
            /// </summary>
            /// <param name="curStream"></param>
            /// <param name="startPosition"></param>
            /// <param name="length"></param>
            /// <returns></returns>
            public static int ReadData(MemoryStream curStream, int startPosition, int length)
            {
                int result = -1;

                byte[] tempData = new byte[length];
                curStream.Position = startPosition;
                curStream.Read(tempData, 0, length);
                result = BitConverter.ToInt32(tempData, 0);

                return result;
            }

            /// <summary>
            /// 向内存流中指定位置,写入数据
            /// </summary>
            /// <param name="curStream"></param>
            /// <param name="startPosition"></param>
            /// <param name="length"></param>
            /// <param name="value"></param>
            public static void WriteData(MemoryStream curStream, int startPosition, int length, int value)
            {
                curStream.Position = startPosition;
                curStream.Write(BitConverter.GetBytes(value), 0, length);
            }

  • 相关阅读:
    python使用openpyxl操作execl
    python 修改、读取图片元数据
    python 利用pyttsx3文字转语音(转)
    SQL学习——SELECT INTO和INSERT INTO SELECT
    iOS开发环境搭建 及 编写1个hello world
    xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance
    头疼3-4次的问题,数据从DB导出到EXCEL,再从EXCEL导入到DB,数据格式发生错误 ,导致 程序出错。
    安卓自动打包持续集成
    jenkins实现master变化时,才触发构建(过滤分支)
    配置github的pull request触发jenkins自动构建
  • 原文地址:https://www.cnblogs.com/wwwbdabc/p/11653637.html
Copyright © 2011-2022 走看看