已知图片的调色板数据 byte[]数组
以及图片的实际数据 
请问如何生成位图?

解决方案 »

  1.   


    你是要通过已有数据创建一个 BMP 位图文件么?我前面有个帖子里提供了方法。
      

  2.   


    //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;
    }
    这段代码应该不是很难看懂吧
      

  3.   

    再不行,就下载我写的一个程序,慢慢消化。。http://d.download.csdn.net/down/3064078/TandyT
      

  4.   

    是的,我现在已有2进制的调色板数据以及位图数据,长宽等信息也有
    我想用这个创建位图
    我按BMP的文件格式自己创建了文件头以及信息头,然后写入调色板数据+位图数据,但是出来的图像不对
      

  5.   

    我把问题简化一下
    已知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++;
    }运行就出错了
      

  6.   

    清楚下面概念:
       位图组成
       1)BITMAPINFOHEADER
       2)调色板(24bit叫"零"调色板,即没有)
       3)图像的数据
        4)有以上三部分可以通过m_hBitmap  = ::CreateDIBSection()
        5)通过mDC.BitBlt()函数将图像放映出.还有很多其它函数,知道上面脉洛就不难理解了.
      

  7.   

    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];
    }//这样创建颜色表不就可以了么?
    还有,你那个说 运行就出错,是指编译过程出错还是编译能通过但是一运行就出错啊?
      

  8.   

    对了,如果你的 temp[] 容量是255 ,那么我上面的代码那里的循环条件要修改为 
    for(int i=0;i<255;i++),否则会出现访问越界,内存不可读。
      

  9.   

    结贴,问题出在调色板数据上, 我的这个文件里调色板数据并不是24位的,而是带了alpha通道的32位颜色
    转换一下颜色就对了