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

高分求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_REVERSE

class 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;
    }
};