BMP位图问题 已知图片的调色板数据 byte[]数组以及图片的实际数据 请问如何生成位图? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 你是要通过已有数据创建一个 BMP 位图文件么?我前面有个帖子里提供了方法。 //C代码//ReadBitMap//#include <stdio.h>#include <stdlib.h>#include <cstring>#include <malloc.h>#include <math.h>#define WIDTHBYTES(bits) (((bits)+31)/32*4)typedef unsigned char BYTE;//一个字节( Byte):用8位2进制表示typedef unsigned short WORD;//一个字:用双字节(16位2进制表示)typedef unsigned long DWORD;//双字:(32位2进制表示)typedef long LONG;//位图文件头信息结构定义//其中不包含文件类型信息typedef struct tagBITMAPFILEHEADER_ { WORD bfType;//文件类型,必须为 "BM"(0x4D42) DWORD bfSize;//文件大小 WORD bfReserved1; //保留字,不考虑 WORD bfReserved2; //保留字,同上 DWORD bfOffBits; //实际位图数据的偏移字节数,即前三个部分长度之和}BITMAPFILEHEADER_;//------------------------------------------------------------//为了在写入文件时方便,把位图文件类型单独定义到一个结构体里面//位图文件头信息结构定义,不包含文件类型信息typedef struct tagBITMAPFILEHEADER { DWORD bfSize; //文件大小 WORD bfReserved1; //保留字,不考虑 WORD bfReserved2; //保留字,同上 DWORD bfOffBits; //实际位图数据的偏移字节数,即前三个部分长度之和}BITMAPFILEHEADER;//上面定义的结构体长度刚好为12,4的倍数//单独的文件类型结构体typedef struct tagBITMAPFILETYPE{ WORD bfType;//文件类型,必须为 "BM"(0x4D42) }BITMAPFILETYPE;//------------------------------------------------------------//信息头BITMAPINFOHEADER,也是一个结构,其定义如下:typedef struct tagBITMAPINFOHEADER{ //public://默认的属性是共有,而类的默认属性是私有 DWORD biSize; //指定此结构体的长度,为40 LONG biWidth; //位图宽 LONG biHeight; //位图高 WORD biPlanes; //平面数,为1 WORD biBitCount; //采用颜色位数,可以是1,2,4,8,16,24,新的可以是32 DWORD biCompression; //压缩方式,可以是0,1,2,其中0表示不压缩 DWORD biSizeImage; //实际位图数据占用的字节数 LONG biXPelsPerMeter;//X方向分辨率 LONG biYPelsPerMeter;//Y方向分辨率 DWORD biClrUsed; //使用的颜色数,如果为0,则表示默认值(2^颜色位数) DWORD biClrImportant;//重要颜色数,如果为0,则表示所有颜色都是重要的}BITMAPINFOHEADER;typedef struct tagRGBQUAD { //public: BYTE rgbBlue; //蓝色分量 BYTE rgbGreen; //绿色分量 BYTE rgbRed; //红色分量 BYTE rgbReserved;//保留值,必须为0}RGBQUAD;void CreateBmpFile8(char *filename,long width,long height,BYTE bitCount,BYTE color );void CreateBmpFile24(char *filename,long width,long height,BYTE bitCount,BYTE color );void ReadFromBmpFile(char *srcFileName,char *dstFileName="999.bmp");typedef struct{ char filename[256]; long width; long height; BYTE bitCount; BYTE color;}CBMP;typedef struct{ char src[256]; char dst[256];}RBMP;int main(void){ char filename[]="test.bmp"; long width=640,height=480; BYTE bitCount=8,color=128;//color 表示灰度值 0-255 FILE *out; BITMAPFILETYPE bft; BITMAPFILEHEADER bfh; BITMAPINFOHEADER bih; RGBQUAD rgbquad[256]; DWORD LineByte,ImgSize; LineByte = WIDTHBYTES(width*bitCount);//计算位图一行的实际宽度并确保它为32的倍数 ImgSize=height*LineByte; for(int p=0;p<256;p++) { rgbquad[p].rgbBlue=(BYTE)p; rgbquad[p].rgbGreen=(BYTE)p; rgbquad[p].rgbRed=(BYTE)p; rgbquad[p].rgbReserved=(BYTE)0; } //-------------------------------------------- //write bmp file header's info //bmp file's type bft.bfType=0x4D42; //bmp fileheader's info bfh.bfSize=(DWORD)(54+4*256+ImgSize); bfh.bfReserved1=0; bfh.bfReserved2=0; bfh.bfOffBits=(DWORD)(54+4*256);//文件头距离像素数据的偏移量 //bmp file's infoheader bih.biSize=40;//本位图信息头的长度,为40字节 bih.biWidth=width; bih.biHeight=height; bih.biPlanes=1; bih.biBitCount=bitCount;//位图颜色位深 bih.biCompression=0;//是否压缩:0不压缩 bih.biSizeImage=ImgSize;//像素数据大小; bih.biXPelsPerMeter = 0; bih.biYPelsPerMeter = 0; bih.biClrUsed = 0;//用到的颜色数,为0则是 2^颜色位深 bih.biClrImportant = 0;//重要的颜色数,为0则全部都重要 //------------------------------------------------------- out = fopen(filename,"w+b"); if(out) { //write bmp file's type fwrite(&bft,sizeof(BITMAPFILETYPE),1,out); //write bmp file's header info fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,out); //write bmp file's infoheader fwrite(&bih,sizeof(BITMAPINFOHEADER),1,out);//write bmp file's RGBQUAD data fwrite(&rgbquad,sizeof(RGBQUAD),sizeof(rgbquad)/sizeof(RGBQUAD),out); //writing pix data to file //分配内存空间把源图存入内存 BYTE *Imgdata=(BYTE *)malloc(ImgSize); memset(Imgdata,color,ImgSize); fwrite(Imgdata,sizeof(BYTE),ImgSize,out); free(Imgdata); } if (out) fclose(out); //-------------------------------------- return 0;}这段代码应该不是很难看懂吧 再不行,就下载我写的一个程序,慢慢消化。。http://d.download.csdn.net/down/3064078/TandyT 是的,我现在已有2进制的调色板数据以及位图数据,长宽等信息也有我想用这个创建位图我按BMP的文件格式自己创建了文件头以及信息头,然后写入调色板数据+位图数据,但是出来的图像不对 我把问题简化一下已知255 *4长度的byte数据 如何利用这些数据创建调色板我的代码是这样byte tmp[255 * 4];//从文件读数据..LPLOGPALETTE pLogPal = (LPLOGPALETTE)new char[sizeof(LPLOGPALETTE) + 255 * sizeof(PALETTEENTRY)]; pLogPal->palVersion = 0x300; pLogPal->palNumEntries = 255; LPRGBQUAD lpRGB=(LPRGBQUAD)tmp; for (int i=0; i<255;i++) { pLogPal->palPalEntry[i].peRed = lpRGB->rgbRed; //pLogPal->palPalEntry[i].peGreen = lpRGB->rgbGreen; //pLogPal->palPalEntry[i].peBlue = lpRGB->rgbBlue; //pLogPal->palPalEntry[i].peFlags = 0; pLogPal++; }运行就出错了 清楚下面概念: 位图组成 1)BITMAPINFOHEADER 2)调色板(24bit叫"零"调色板,即没有) 3)图像的数据 4)有以上三部分可以通过m_hBitmap = ::CreateDIBSection() 5)通过mDC.BitBlt()函数将图像放映出.还有很多其它函数,知道上面脉洛就不难理解了. LPRGBQUAD lpRGB=(LPRGBQUAD)tmp;for (int i=0; i<255;i++){pLogPal->palPalEntry[i].peRed = lpRGB->rgbRed;//pLogPal->palPalEntry[i].peGreen = lpRGB->rgbGreen;//pLogPal->palPalEntry[i].peBlue = lpRGB->rgbBlue;//pLogPal->palPalEntry[i].peFlags = 0;pLogPal++;}没必要像上面这样来创建吧?你直接定义一个RGBQUAD prgb[256];然后,for (int i=0;i<256;i++){ prgb.rgbBlue=tmp[i*4+0]; prgb.rgbGreen=tmp[i*4+1]; prgb.rgbRed=tmp[i*4+2]; prgb.rgbReserved=tmp[i*4+3];}//这样创建颜色表不就可以了么?还有,你那个说 运行就出错,是指编译过程出错还是编译能通过但是一运行就出错啊? 对了,如果你的 temp[] 容量是255 ,那么我上面的代码那里的循环条件要修改为 for(int i=0;i<255;i++),否则会出现访问越界,内存不可读。 结贴,问题出在调色板数据上, 我的这个文件里调色板数据并不是24位的,而是带了alpha通道的32位颜色转换一下颜色就对了 vs c++问题 切断电脑电源时能捕到什么消息么? 首推 国内一款不错的RSS阅读器 100分求 模拟鼠标发送双击消息给CTreeCtrl中指定ITEM的代码 如何在CStatic上面的某一个区域显示一个图(图在本地的硬盘上,是一个文件)(急) <新手>两个简单的问题 ComBoBox 和 List Ctrl的简单问题 控件大小 按 对话框的大小 比例缩放的问题. 关于LOGFONT结构的字体高度 怎么提取mp3文件中的信息,比如歌手,专集,什么的? 如何把ActiveX 控件打包到动态链接库 请教一个关于宏的定义 基于MFC dialog 的多条数据曲线绘制与屏蔽问题请教
你是要通过已有数据创建一个 BMP 位图文件么?我前面有个帖子里提供了方法。
//C代码
//ReadBitMap
//
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include <malloc.h>
#include <math.h>#define WIDTHBYTES(bits) (((bits)+31)/32*4)typedef unsigned char BYTE;//一个字节( Byte):用8位2进制表示
typedef unsigned short WORD;//一个字:用双字节(16位2进制表示)
typedef unsigned long DWORD;//双字:(32位2进制表示)
typedef long LONG;
//位图文件头信息结构定义
//其中不包含文件类型信息
typedef struct tagBITMAPFILEHEADER_
{
WORD bfType;//文件类型,必须为 "BM"(0x4D42)
DWORD bfSize;//文件大小
WORD bfReserved1; //保留字,不考虑
WORD bfReserved2; //保留字,同上
DWORD bfOffBits; //实际位图数据的偏移字节数,即前三个部分长度之和
}BITMAPFILEHEADER_;
//------------------------------------------------------------
//为了在写入文件时方便,把位图文件类型单独定义到一个结构体里面
//位图文件头信息结构定义,不包含文件类型信息
typedef struct tagBITMAPFILEHEADER
{
DWORD bfSize; //文件大小
WORD bfReserved1; //保留字,不考虑
WORD bfReserved2; //保留字,同上
DWORD bfOffBits; //实际位图数据的偏移字节数,即前三个部分长度之和
}BITMAPFILEHEADER;
//上面定义的结构体长度刚好为12,4的倍数
//单独的文件类型结构体
typedef struct tagBITMAPFILETYPE
{
WORD bfType;//文件类型,必须为 "BM"(0x4D42)
}BITMAPFILETYPE;
//------------------------------------------------------------
//信息头BITMAPINFOHEADER,也是一个结构,其定义如下:
typedef struct tagBITMAPINFOHEADER
{
//public://默认的属性是共有,而类的默认属性是私有
DWORD biSize; //指定此结构体的长度,为40
LONG biWidth; //位图宽
LONG biHeight; //位图高
WORD biPlanes; //平面数,为1
WORD biBitCount; //采用颜色位数,可以是1,2,4,8,16,24,新的可以是32
DWORD biCompression; //压缩方式,可以是0,1,2,其中0表示不压缩
DWORD biSizeImage; //实际位图数据占用的字节数
LONG biXPelsPerMeter;//X方向分辨率
LONG biYPelsPerMeter;//Y方向分辨率
DWORD biClrUsed; //使用的颜色数,如果为0,则表示默认值(2^颜色位数)
DWORD biClrImportant;//重要颜色数,如果为0,则表示所有颜色都是重要的
}BITMAPINFOHEADER;
typedef struct tagRGBQUAD
{
//public:
BYTE rgbBlue; //蓝色分量
BYTE rgbGreen; //绿色分量
BYTE rgbRed; //红色分量
BYTE rgbReserved;//保留值,必须为0
}RGBQUAD;
void CreateBmpFile8(char *filename,long width,long height,BYTE bitCount,BYTE color );
void CreateBmpFile24(char *filename,long width,long height,BYTE bitCount,BYTE color );
void ReadFromBmpFile(char *srcFileName,char *dstFileName="999.bmp");typedef struct
{
char filename[256];
long width;
long height;
BYTE bitCount;
BYTE color;
}CBMP;
typedef struct
{
char src[256];
char dst[256];
}RBMP;int main(void)
{
char filename[]="test.bmp";
long width=640,height=480;
BYTE bitCount=8,color=128;//color 表示灰度值 0-255
FILE *out;
BITMAPFILETYPE bft;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
RGBQUAD rgbquad[256];
DWORD LineByte,ImgSize;
LineByte = WIDTHBYTES(width*bitCount);//计算位图一行的实际宽度并确保它为32的倍数
ImgSize=height*LineByte;
for(int p=0;p<256;p++)
{
rgbquad[p].rgbBlue=(BYTE)p;
rgbquad[p].rgbGreen=(BYTE)p;
rgbquad[p].rgbRed=(BYTE)p;
rgbquad[p].rgbReserved=(BYTE)0;
}
//--------------------------------------------
//write bmp file header's info
//bmp file's type
bft.bfType=0x4D42;
//bmp fileheader's info
bfh.bfSize=(DWORD)(54+4*256+ImgSize);
bfh.bfReserved1=0;
bfh.bfReserved2=0;
bfh.bfOffBits=(DWORD)(54+4*256);//文件头距离像素数据的偏移量
//bmp file's infoheader
bih.biSize=40;//本位图信息头的长度,为40字节
bih.biWidth=width;
bih.biHeight=height;
bih.biPlanes=1;
bih.biBitCount=bitCount;//位图颜色位深
bih.biCompression=0;//是否压缩:0不压缩
bih.biSizeImage=ImgSize;//像素数据大小;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;//用到的颜色数,为0则是 2^颜色位深
bih.biClrImportant = 0;//重要的颜色数,为0则全部都重要
//-------------------------------------------------------
out = fopen(filename,"w+b");
if(out)
{
//write bmp file's type
fwrite(&bft,sizeof(BITMAPFILETYPE),1,out);
//write bmp file's header info
fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,out);
//write bmp file's infoheader
fwrite(&bih,sizeof(BITMAPINFOHEADER),1,out);//write bmp file's RGBQUAD data
fwrite(&rgbquad,sizeof(RGBQUAD),sizeof(rgbquad)/sizeof(RGBQUAD),out);
//writing pix data to file
//分配内存空间把源图存入内存
BYTE *Imgdata=(BYTE *)malloc(ImgSize);
memset(Imgdata,color,ImgSize);
fwrite(Imgdata,sizeof(BYTE),ImgSize,out);
free(Imgdata);
}
if (out) fclose(out);
//--------------------------------------
return 0;
}
这段代码应该不是很难看懂吧
我想用这个创建位图
我按BMP的文件格式自己创建了文件头以及信息头,然后写入调色板数据+位图数据,但是出来的图像不对
已知255 *4长度的byte数据
如何利用这些数据创建调色板我的代码是这样
byte tmp[255 * 4];
//从文件读数据
..
LPLOGPALETTE pLogPal = (LPLOGPALETTE)new char[sizeof(LPLOGPALETTE) + 255 * sizeof(PALETTEENTRY)];
pLogPal->palVersion = 0x300;
pLogPal->palNumEntries = 255;
LPRGBQUAD lpRGB=(LPRGBQUAD)tmp; for (int i=0; i<255;i++)
{
pLogPal->palPalEntry[i].peRed = lpRGB->rgbRed;
//pLogPal->palPalEntry[i].peGreen = lpRGB->rgbGreen;
//pLogPal->palPalEntry[i].peBlue = lpRGB->rgbBlue;
//pLogPal->palPalEntry[i].peFlags = 0;
pLogPal++;
}运行就出错了
位图组成
1)BITMAPINFOHEADER
2)调色板(24bit叫"零"调色板,即没有)
3)图像的数据
4)有以上三部分可以通过m_hBitmap = ::CreateDIBSection()
5)通过mDC.BitBlt()函数将图像放映出.还有很多其它函数,知道上面脉洛就不难理解了.
{
pLogPal->palPalEntry[i].peRed = lpRGB->rgbRed;//pLogPal->palPalEntry[i].peGreen = lpRGB->rgbGreen;
//pLogPal->palPalEntry[i].peBlue = lpRGB->rgbBlue;
//pLogPal->palPalEntry[i].peFlags = 0;
pLogPal++;
}
没必要像上面这样来创建吧?你直接定义一个RGBQUAD prgb[256];然后,for (int i=0;i<256;i++)
{
prgb.rgbBlue=tmp[i*4+0];
prgb.rgbGreen=tmp[i*4+1];
prgb.rgbRed=tmp[i*4+2];
prgb.rgbReserved=tmp[i*4+3];
}//这样创建颜色表不就可以了么?
还有,你那个说 运行就出错,是指编译过程出错还是编译能通过但是一运行就出错啊?
for(int i=0;i<255;i++),否则会出现访问越界,内存不可读。
转换一下颜色就对了