读书人

高分求BMP的简单操作,该如何处理

发布时间: 2012-03-06 20:47:55 作者: rapoo

高分求BMP的简单操作
假如我知道一BMP图片的名字如:1.bmp 如何把这张图片(1.bmp)读进来并保存它的基本信息(如,长度,宽度,各像素)。用这个函数实现

void ReadImage(char *ImageFileName, char *oImage,int wImage, int hImage); //读取图像信息并保存在oImage中,wImage放宽度,hImage放长度

[解决办法]
你的函数参数不对,int wImage, int hImage 只能传入,不能传出

看一下bmp文件格式然后自己写吧,不难的:
网上也能搜到很多代码的,还是自己写一遍比较好。


1. bmp图象
   · 位图文件头(BITMAPHEADER)数据结构
   · 位图信息(BITMAPINFO)数据结构
   · 位图阵列

  1)位图文件头数据结构包含BMP图象文件的类型、显示内容等信息。
  Typedef struct{
      Int bfType; //must be "BM"
      Long bfSize; //位图大小
      Int bfReserved1;//must be "0"
      Int bfReserved2;//must be "0"
      Long bfOffBits;//位图阵列的起始位置
  }BITMAPEFILEHEADER;

  2)位图信息数据结构由BITMAPINFOHEADER和RGBQUAD两个数据结构组成,
  typedef struct{
      BITMAPINFOHEADER bmiHeader;
      RGBQUAD bmiColors[];
  }BITMAPINFO

  其中BITMAPINFOHEADER数据结构包含了有关BMP图象的宽、高、压缩方法等信息。
  数据结构RGBQUAD定义一种颜色。

  3)位图阵列
  位图阵列记录了图象的每一个象素值。从图象的左下角开始逐行扫描图象。从左到右,从上到下,将图象的象素值逐一记录下来,这些记录象素值的字节组成了位图阵列。
  位图阵列数据的存储格式有压缩和非压缩两种格式。
  1. 非压缩格式 位图中的每一个点的象素值对应与位图阵列的若干位,而位图阵列的若干位由图象的高度、宽度及图象的颜色数决定。
  2. 压缩格式 在bmp格式文件中,Windows支持BI-RLE8和BI-RLE4两种压缩类型的存储格式。


[解决办法]

C/C++ code
#define IMG_REVERSEclass BMPFile{public:    static bool SaveBMP(unsigned char* pBits, int width, int height, int channel, const char *fileName)    {        using std::ifstream;        using std::ofstream;        if(width <= 0 || height <= 0 || NULL == pBits)             return false;        ofstream out(fileName, std::ios::binary);        if(!out) return false;        BITMAPFILEHEADER bfh;        BITMAPINFOHEADER bih;        RGBQUAD quad[256];        DWORD dwPaletteSize = 0;        memset(&bfh, 0, sizeof(bfh));        memset(&bih, 0, sizeof(bih));        if(channel == 1)        {                        for(int i = 0; i < 256; ++ i)            {                quad[i].rgbRed = (BYTE)i;                quad[i].rgbGreen = (BYTE)i;                quad[i].rgbBlue = (BYTE)i;                quad[i].rgbReserved = 0;            }            dwPaletteSize = sizeof(quad);        }        bfh.bfType = 0x4D42; // bmp file        bfh.bfOffBits = sizeof(bfh) + sizeof(bih) + dwPaletteSize;                WORD wBitCount = channel * 8;        bih.biSize = sizeof(BITMAPINFOHEADER);        bih.biWidth = width;        bih.biHeight = height;        bih.biPlanes = 1;        bih.biBitCount = wBitCount;                int rowWidth = ((int)(width * wBitCount + 31) >> 5) << 2;        DWORD dwBmBitsSize = DWORD(rowWidth * height);        bfh.bfSize = bfh.bfOffBits + dwBmBitsSize;                int nBytes = width * channel;        int nAdd = rowWidth - nBytes;        std::auto_ptr<char> buf;        if(nAdd)         {            buf.reset(new char[nAdd]);            memset(buf.get(), 0, nAdd);        }        out.write((const char *)&bfh, sizeof(bfh));        out.write((const char *)&bih, sizeof(bih));        if(dwPaletteSize)            out.write((const char *)quad, sizeof(quad));#ifndef IMG_REVERSE        for(int i = 0; i < height; ++ i)#else        for(int i = height - 1; i >= 0; -- i)#endif        {            unsigned char* ptr = pBits + i * nBytes;            out.write((const char *)ptr, nBytes);            if(nAdd)            {                out.write(buf.get(), nAdd);            }        }        out.close();        return true;    }    static bool loadBMP(unsigned char*&pBits, int&width, int&height, const char* fileName)    {        using std::ifstream;        using std::ofstream;        ifstream in(fileName, std::ios::binary);        if(!in) return false;        BITMAPFILEHEADER bfh;        BITMAPINFOHEADER bih;        RGBQUAD quad[256];        DWORD dwPaletteSize = 0;        typedef char* bufType;        in.read((bufType)&bfh, sizeof(bfh));        in.seekg(0, std::ios::end);        if(bfh.bfType != 0x4D42 || bfh.bfSize != in.tellg())        {            in.close();            return false;        }                        in.clear();        in.seekg(sizeof(bfh), std::ios_base::beg);        in.read((bufType)&bih, sizeof(bih));        width = bih.biWidth;        height = bih.biHeight;                std::auto_ptr<unsigned char> buf;        DWORD img_size;        if(bih.biSizeImage != 0)            img_size = bih.biSizeImage;        else         {            img_size = bfh.bfSize - bfh.bfOffBits;        }        unsigned char *ptr;        buf.reset(ptr = new unsigned char[(int)img_size+10]);        if(NULL == ptr)         {            in.close();            return false;        }        in.seekg(bfh.bfOffBits, std::ios_base::beg);        in.read((bufType)ptr, img_size);                DWORD nSrcWidth = ((int)(width * bih.biBitCount + 31) >> 5) << 2;        DWORD nSize = width * height * 3;        DWORD nDestWidth;        DWORD nAddSize;        unsigned char *ptrDest;        unsigned char *ptrSrc;        size_t index;        switch(bih.biBitCount)        {        case 4:            in.seekg(bfh.bfOffBits - sizeof(RGBQUAD) * 16, std::ios_base::beg);// read palette information            in.read((bufType)quad, sizeof(RGBQUAD) * 16);            try            {                pBits = new unsigned char[nSize];            }            catch(...)            {                in.close();                return false;            }            ptrDest = pBits;            ptrSrc = buf.get();            index = 0;            nDestWidth = width * 3;            nAddSize = nSrcWidth - (width+1)/2;#ifndef IMG_REVERSE            for(int y = 0; y < height; ++ y)#else            for(int y = height - 1; y >= 0; -- y)#endif            {                ptrSrc = buf.get() + y * nSrcWidth + nAddSize;                for(int x = 0; x < width; ++ x)                {                    index  = (x&0x01) ? (ptrSrc[x/2] & 0x0F) : (ptrSrc[x/2] >> 4);                    *(ptrDest ++) = quad[index].rgbBlue;                    *(ptrDest ++) = quad[index].rgbGreen;                    *(ptrDest ++) = quad[index].rgbRed;                }            }            break;        case 8:            in.seekg(bfh.bfOffBits - sizeof(RGBQUAD) * 256, std::ios_base::beg);// read palette information            in.read((bufType)quad, sizeof(RGBQUAD) * 256);            try            {                pBits = new unsigned char[nSize];            }            catch(...)            {                in.close();                return false;            }            ptrDest = pBits;            ptrSrc = buf.get();            index = 0;            nDestWidth = width * 3;            nAddSize = nSrcWidth - width;#ifndef IMG_REVERSE            for(int y = 0; y < height; ++ y)#else            for(int y = height - 1; y >= 0; -- y)#endif            {                ptrSrc = buf.get() + y * nSrcWidth + nAddSize;                for(int x = 0; x < width; ++ x)                {                    index  = ptrSrc[x];                    *(ptrDest ++) = quad[index].rgbBlue;                    *(ptrDest ++) = quad[index].rgbGreen;                    *(ptrDest ++) = quad[index].rgbRed;                }            }            break;        case 24:            nDestWidth = width * 3;            nAddSize = nSrcWidth - nDestWidth;            try            {                pBits = new unsigned char[nSize];                memset(pBits, 0, nSize);            }            catch(...)            {                pBits = NULL;                in.close();                return false;            }            ptrDest = pBits;#ifdef IMG_REVERSE            for(int y = height - 1; y >= 0; -- y)#else            for(int y = 0; y < height; ++ y)#endif            {                memcpy(ptrDest, buf.get() + nSrcWidth * y + nAddSize, nDestWidth);                ptrDest += nDestWidth;            }            break;        }                in.close();        return true;    }}; 

读书人网 >软件架构设计

热点推荐