C++中依像素读取BMP文件并显示,显示的问题
在此先行谢谢帮助我的大侠了!
我在C++中用自定义的BITMAPFILEHEADER和BITMAPINFOHEADER读取BMP,然后用SetPixel()显示出来。为了清楚地解释我遇到的问题,请看下面的图:
这是256*256的lena.bmp。左边是原图,右边是我程序的输出。请您看最左边有一个长条矩形,本来这一条应该是图的最右侧才对。
还有另外一个问题,请看:
这个图是146*146的bmp,是我随便截屏来的。下面这幅图是程序输出,不仅仍是最右侧的一条跑到最左侧来了,而且颜色也变得很奇怪。这如果是程序的问题的话,为什么lena里没有出现呢?如果是图片本身的问题,那么应该是什么问题呢?
我的代码如下,可以直接跑的:
/*****BMP.h*****/#include <fstream>#include <Windows.h>#define N 384using namespace std;typedef struct { WORD bfType; /* Magic identifier */ DWORD bfSize; /* File size in bytes */ WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; /* Offset to image data, bytes */} HEADER;typedef struct { DWORD biSize; /* Header size in bytes */ LONG biWidth; /* Width and height of image */ LONG biHeight; WORD biPlanes; /* Number of colour planes */ WORD biBitCount; /* Bits per pixel */ DWORD biCompression; /* Compression type */ DWORD biSizeImage; /* Image size in bytes */ LONG biXPelsPerMeter; /* Pixels per meter */ LONG biYPelsPerMeter; DWORD biClrUsed; /* Number of colours */ DWORD biClrImportant; /* Important colours */} INFOHEADER;
#include "BMP.h"HEADER bmfh; //bitmap file headerINFOHEADER bmih; //bitmap info headerBYTE R[N][N], G[N][N], B[N][N]; //RGB value of every pixelCOLORREF color[N][N]; //colorextern "C" WINBASEAPI HWND WINAPI GetConsoleWindow (); //initialize the screenvoid ReadBmp(char *BmpFileName);void GetColor(int i, int j);void main(){ HWND hwnd; //handlers HWND and HDC HDC hdc; char BmpFileName[10]; int i, j; hwnd = GetConsoleWindow(); //initialize the screen hdc = GetDC(hwnd); scanf("%s", BmpFileName); ReadBmp(BmpFileName); //read the BMP file for(i = 0; i < bmih.biHeight; i++) for(j = 0; j < bmih.biWidth; j++) SetPixel(hdc, i, j, color[bmih.biWidth - j][i]); //draw the BMP image ReleaseDC(hwnd,hdc);}void ReadBmp(char *BmpFileName) //read the BMP file{ int patch; //number of 0s for complement in every row ifstream in(BmpFileName, ios_base::binary); //open the BMP file in.read((char *)(&bmfh), sizeof(bmfh) - 2); //read in BITMAPFILEHEADER. Here sizeof returns a value larger than struct size, so "-2" if(bmfh.bfType != 0x4d42) //if not BMP, exit { printf("File type is not BMP!\n"); exit(1); } in.read((char *)(&bmih),sizeof(bmih)); //read in BITMAPINFOHEADER in.seekg(bmfh.bfOffBits, ios_base::beg); //seek bitmap data patch = (4 - (bmih.biWidth * 3) % 4) % 4; //calculate number of 0s for complement in every row for(int i = 0; i < abs(bmih.biHeight); i++) { for(int j = 0; j < abs(bmih.biWidth); j++) { in.read((char *)(&R[i][j]), 1); //read in data pixel by pixel in.read((char *)(&G[i][j]), 1); in.read((char *)(&B[i][j]), 1); GetColor(i, j); //obtain the original and greyscaled color } in.seekg(patch, ios_base::cur); //skip 0s for complement in every row }}void GetColor(int i, int j) //obtain the original and greyscaled color{ int iB, iG, iR; iB = (int)(B[i][j]); iG = (int)(G[i][j]); iR = (int)(R[i][j]); color[i][j] = RGB(iB, iG, iR); //original color}
[解决办法]
Qt中也一样
#pragma pack(push)
#pragma pack(1)
//结构体定义
#pragma pack(pop)