读书人

取BMP图像像素程序的有关问题

发布时间: 2012-03-02 14:40:29 作者: rapoo

取BMP图像像素程序的问题。在线等
我从网上找了一取BMP图像的代码,按照他的提示一步一步做的,可是编译后出现如下问题,期待高手解答。
faceDoc.obj : error LNK2005: "void * m_hDIB " (?m_hDIB@@3PAXA) already defined in face.obj
faceDoc.obj : error LNK2005: "class CPalette * m_palDIB " (?m_palDIB@@3PAVCPalette@@A) already defined in face.obj
faceDoc.obj : error LNK2005: "class CSize m_sizeDoc " (?m_sizeDoc@@3VCSize@@A) already defined in face.obj
faceView.obj : error LNK2005: "void * m_hDIB " (?m_hDIB@@3PAXA) already defined in face.obj
faceView.obj : error LNK2005: "class CPalette * m_palDIB " (?m_palDIB@@3PAVCPalette@@A) already defined in face.obj
faceView.obj : error LNK2005: "class CSize m_sizeDoc " (?m_sizeDoc@@3VCSize@@A) already defined in face.obj
Debug/face.exe : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.

[解决办法]
我有一个读取bmp文件的程序,只用了最基本的数据类型来读取,没用如UINT之类的,你可以看一下:
#ifndef _BMPLOAD_H_
#define _BMPLOAD_H_
#include <iostream>
#include <stdio.h>
using namespace std;

/*-------------
类型定义
--------------*/

// 纹理图像结构
typedef struct {
int imgWidth; // 纹理宽度
int imgHeight; // 纹理高度
unsigned int rgbType; // 每个象素对应的字节数,3:24位图,4:带alpha通道的24位图
unsigned char *data; // 纹理数据
} TEXTUREIMAGE;

// BMP文件头
typedef struct {
unsigned short bfType; // 文件类型
unsigned long bfSize; // 文件大小
unsigned short bfReserved1; // 保留位
unsigned short bfReserved2; // 保留位
unsigned long bfOffBits; // 数据偏移位置
} BMPFILEHEADER;

// BMP信息头
typedef struct {
unsigned long biSize; // 此结构大小
long biWidth; // 图像宽度
long biHeight; // 图像高度
unsigned short biPlanes; // 调色板数量
unsigned short biBitCount; // 每个象素对应的位数,24:24位图,32:带alpha通道的24位图
unsigned long biCompression; // 压缩
unsigned long biSizeImage; // 图像大小
long biXPelsPerMeter;// 横向分辨率
long biYPelsPerMeter;// 纵向分辨率
unsigned long biClrUsed; // 颜色使用数
unsigned long biClrImportant; // 重要颜色数
} BMPINFOHEADER;

// 读取BMP文件创建纹理
GLboolean LoadBmp(char *filename, TEXTUREIMAGE *textureImg) {
int i, j;
FILE *file;
BMPFILEHEADER bmpFile;
BMPINFOHEADER bmpInfo;
int pixel_size;

// 初始化纹理数据
textureImg-> imgWidth = 0;
textureImg-> imgHeight = 0;
textureImg-> rgbType = 0;
if (textureImg-> data != NULL) {
delete []textureImg-> data;
}

// 打开文件
file = fopen(filename, "rb ");
if (file == NULL) {
cout < < "Open File Error " < <endl;
return false;

}

// 获取文件头
rewind(file);
fread(&bmpFile, sizeof(BMPFILEHEADER)-2, 1, file);
//因为C语言对结构按四位对齐,所以不能直接用sizeof(BMPFILEHEADER)
fread(&bmpInfo, sizeof(BMPINFOHEADER), 1, file);

// 验证文件类型
if (bmpFile.bfType != 0x4D42) {
cout < < "File Type Error " < <endl;
fclose(file);
return false;
}

// 获取图像色彩数
pixel_size = bmpInfo.biBitCount > > 3;



// 读取文件数据
textureImg-> data = new unsigned char[bmpInfo.biWidth * bmpInfo.biHeight * pixel_size];
if (textureImg-> data == NULL) {
fclose(file);
return false;
}
rewind(file);
fseek(file, 54L, 0);
for (i = 0; i < bmpInfo.biHeight; i++) {
for (j = 0; j < bmpInfo.biWidth; j++) {
// 红色分量
fread(
textureImg-> data + (i * bmpInfo.biWidth + j) * pixel_size + 2,
sizeof(unsigned char), 1, file);
// 绿色分量
fread(
textureImg-> data + (i * bmpInfo.biWidth + j) * pixel_size + 1,
sizeof(unsigned char), 1, file);
// 蓝色分量
fread(textureImg-> data + (i * bmpInfo.biWidth + j) * pixel_size + 0,
sizeof(unsigned char), 1, file);
// Alpha分量
if (pixel_size == 4) {
fread(textureImg-> data + (i * bmpInfo.biWidth + j) * pixel_size + 3,
sizeof(unsigned char), 1, file);
}
}
}

// 记录图像相关参数
textureImg-> imgWidth = bmpInfo.biWidth;
textureImg-> imgHeight = bmpInfo.biHeight;
textureImg-> rgbType = pixel_size;
fclose(file);
return false;
}

#endif

[解决办法]
这段时间正好跟导师做目标识别的项目,其中我有写了个小程序读取BMP文件,现将代码贴于此,供参考。程序可以读取1,2,4,8,16,24位BMP图片。


如何读取bmp位图信息及bmp位图格式简介(代码在vs2005编译测试通过)2007-06-01 00:19这是我们参加目标识别项目的测试题,现公开于此。希望能为你提供帮助!

BMP图形的存储格式
0-1文件类型标志,一般为字符 "BM "的ASCII码.
2-5一个由低字节向高字节排放的二进制数,表示该BMP文件的长度.
10-13一个由低字节向高字节排放的二进制数,表示图象数据的起始位置,也可以
理解为文件描述头的长度(单位为字节)
18-19一个由低字节向高字节排放的二进制数,表示图象的宽度.
22-23一个由低字节向高字节排放的二进制数,表示图象的高度.
28每象素所占的位数
48调色板中的颜色数
54~ 从这里开始为调色板(B,G,R,RES)
图象数据

注意:图象的实际宽度width在第18-19字节给出,但读取图象数据时应注意,当width
不是8的整数(好像也是32的倍数)倍时,应将width=(width/8+1)*8,即两行图象数数之间的间隔不是width 而是width '.
调色板的颜色数与图象数据的起始位置,每象素所占的位数是相关的.
调节器色板中每四个字节表示一个颜色,分别给出B,G,R,RES分量,所以调色板的
大小=颜色数*四个字节.
图象区存放的数据是象素颜色在调色板中的序号,值得指出的是存取时象素的
排列是自左而右,从上而下的.


下面是根据此格式写的程序,在vs2005编译测试通过。

//author:zheng jianbin
//ReadBitMap
//
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>


#define WIDTHBYTES(bits) (((bits)+31)/32*4)

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef long LONG;


//位图文件头信息结构定义
//其中不包含文件类型信息(由于结构体的内存结构决定,要是加了的话将不能正确读取文件信息)

typedef struct tagBITMAPFILEHEADER {

DWORD bfSize; //文件大小
WORD bfReserved1; //保留字,不考虑
WORD bfReserved2; //保留字,同上
DWORD bfOffBits; //实际位图数据的偏移字节数,即前三个部分长度之和
} BITMAPFILEHEADER;


//信息头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;


//调色板Palette,当然,这里是对那些需要调色板的位图文件而言的。24位和32位是不需要调色板的。
//(似乎是调色板结构体个数等于使用的颜色数。)



typedef struct tagRGBQUAD {
//public:
BYTE rgbBlue; //该颜色的蓝色分量
BYTE rgbGreen; //该颜色的绿色分量
BYTE rgbRed; //该颜色的红色分量
BYTE rgbReserved; //保留值
} RGBQUAD;


void showBmpHead(BITMAPFILEHEADER* pBmpHead)
{
printf( "位图文件头:\n ");
printf( "文件大小:%d\n ",pBmpHead-> bfSize);
printf( "保留字:%d\n ",pBmpHead-> bfReserved1);
printf( "保留字:%d\n ",pBmpHead-> bfReserved2);
printf( "实际位图数据的偏移字节数:%d\n ",pBmpHead-> bfOffBits);

}


void showBmpInforHead(tagBITMAPINFOHEADER* pBmpInforHead)
{
printf( "位图信息头:\n ");
printf( "结构体的长度:%d\n ",pBmpInforHead-> biSize);
printf( "位图宽:%d\n ",pBmpInforHead-> biWidth);
printf( "位图高:%d\n ",pBmpInforHead-> biHeight);
printf( "biPlanes平面数:%d\n ",pBmpInforHead-> biPlanes);
printf( "biBitCount采用颜色位数:%d\n ",pBmpInforHead-> biBitCount);
printf( "压缩方式:%d\n ",pBmpInforHead-> biCompression);
printf( "biSizeImage实际位图数据占用的字节数:%d\n ",pBmpInforHead-> biSizeImage);
printf( "X方向分辨率:%d\n ",pBmpInforHead-> biXPelsPerMeter);
printf( "Y方向分辨率:%d\n ",pBmpInforHead-> biYPelsPerMeter);
printf( "使用的颜色数:%d\n ",pBmpInforHead-> biClrUsed);
printf( "重要颜色数:%d\n ",pBmpInforHead-> biClrImportant);
}

void showRgbQuan(tagRGBQUAD* pRGB)
{
printf( "(%-3d,%-3d,%-3d) ",pRGB-> rgbRed,pRGB-> rgbGreen,pRGB-> rgbBlue);

}


读书人网 >C++

热点推荐