C#中使用byte[]数据,生成Bitmap(256色 灰度 BMP位图)源代码

转载 2007年09月21日 22:58:00

摸索了3天,终于成功实现了使用已知byte[]数据,生成Bitmap256灰度 BMP位图)。

其中遇到了很多问题:

如何在C#(GDI+)中操作Bitmap,获取位图的各种数据,就像在C++|中一样

如何修改Bitmap的调色板

如何解决位图显示错位的问题,即位图的4字节对齐问题

如何用数据生成位图

总结一下,希望对需要的朋友有所帮助,少走弯路。


 /// <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, 104);


            
//改变调色板,因为默认的调色板是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, 
04);
            }

            
//最终生成的位图数据,以及大小,高度没有变,宽度需要调整
            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);
        }
 

C#由指定数据生成灰度位图或者彩色位图

在C#中用已知数据创建指定大小的灰度位图或者彩色位图
  • sirenxiaohuayuan
  • sirenxiaohuayuan
  • 2015年12月17日 19:32
  • 2379

256色图像不一定是灰度图像。

256色图像属于伪彩色图像,但是他也是8位的呀,他和256灰度图有什么差别?256色图像是如何表示颜色的?   灰度图像:每个像素由一个字节,即是八位,共256种色,且红绿蓝三...
  • caiqi1123
  • caiqi1123
  • 2011年12月15日 14:07
  • 1266

位图(Bitmap)16色,256色,24位位图表达的意思

 我们常说:Windows95/98处于16色或256色状态,它的意思是屏幕上最多能显示多少种颜色。   你看,在16色下显示黑白的文本或简单的色彩线条是非常正常的,但如果我们要想看多于16种颜色的画...
  • gwwgle
  • gwwgle
  • 2009年11月26日 16:42
  • 9629

MFC下256色BMP位图的保存

一、BMP位图的文件格式 BMP文件的数据按照从文件头开始的先后顺序分为四个部分: ◆ 位图文件头(bmp file header):  提供文件的格式、大小等信息 ◆ 位图信息头(bitmap...
  • qq_22531295
  • qq_22531295
  • 2017年02月22日 15:00
  • 476

彩色BMP转换成灰度图的原理

彩色BMP转换成灰度图的原理
  • wesleyluo
  • wesleyluo
  • 2011年03月08日 14:45
  • 20025

BMP图片格式详细解析--以256色为例还原256色BMP图像数据

256色bmp图像还原记录: 通过分析bmp图片的格式,可以完成BMP图片的打开和保存 一、bmp格式: 典型的 BMP 图像文件由四部分组成: 1 . 位图文件头数据结构 ,它包含 BMP...
  • cnzaicom
  • cnzaicom
  • 2016年04月28日 21:51
  • 1393

BMP位图调色板

原文地址:http://blog.csdn.net/qsycn/article/details/7801145 BMP位图调色板是BMP位图文件的组成成分之一,调色板是单色(调色板中含有两种颜色,也就...
  • kkkkkkkkq
  • kkkkkkkkq
  • 2016年12月26日 20:11
  • 690

用Qt来进行256色位图的转换

接着上次的一篇文章关于“在一个图片上写字并保存”,上次说到
  • prompty
  • prompty
  • 2016年12月30日 10:00
  • 877

ps制作256色(8位)bmp图片的步骤

说明:我常用VC开发,VC自带的有图形编辑器,但是只支持256色,颜色再多了显示不出来,现在做界面一般用其他工具做如ps,能做的漂亮,设计好了之后再加载到VC工程来使用,用的最多的是.bmp文件,那么...
  • zipper9527
  • zipper9527
  • 2009年05月14日 13:27
  • 10517

24bits bitmap 文件到256色bitmap 的转换

{**********************************************************}{                                       ...
  • linmaochen
  • linmaochen
  • 2003年04月01日 09:03
  • 1287
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C#中使用byte[]数据,生成Bitmap(256色 灰度 BMP位图)源代码
举报原因:
原因补充:

(最多只允许输入30个字)