高分求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两种压缩类型的存储格式。
------解决方案--------------------
假如我知道一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; } };