求助关于bmp的问题。(图像截取出错)

liujianwish 2009-02-20 02:21:04
自己写的代码用来熟悉一下bmp结构
我写了一个GetSquareBMP想要截取图像的某部分,并且截取了出来,但是截取的图像有问题(右边一部分显示在了左边,不是左右颠倒的问题)。。请大虾看一下。最好能执行以下(只能截取32位的bmp

下面是三个文件:class: .h .cpp 以及 一个 main: .cpp

class Color_BM:

#pragma once
#include <iostream>
#include "windows.h"
using namespace std;
struct RGBex
{
BYTE b;
BYTE g;
BYTE r;
BYTE a;
};
class Color_BM
{
public:
Color_BM(FILE*);
~Color_BM(void);
void infoshow();
private:
FILE *pBM;
tagBITMAPFILEHEADER INIT;
tagBITMAPINFOHEADER INFO;
private:
void* pSource;
int WriteToFile(FILE *pfile,void **pTar,tagBITMAPFILEHEADER *Winit=NULL,tagBITMAPINFOHEADER *Winfo=NULL);
long ImageSize;
public:
int GetSquareBMP(int X, int Y, int W, int L);
};


class .cpp

#include "Color_BM.h"
Color_BM::Color_BM(FILE* source)
: pSource(NULL)
, ImageSize(0)
{
long SizeFixel,SizeBit;
SizeFixel=INFO.biHeight*INFO.biWidth;
SizeBit=INFO.biHeight*INFO.biWidth*INFO.biBitCount/8;
pBM=source;
fread(&INIT,sizeof(BITMAPFILEHEADER),1,pBM);
fread(&INFO,sizeof(tagBITMAPINFOHEADER),1,pBM);
pSource=new char[SizeBit];
fread(pSource,SizeBit,1,pBM);
}

Color_BM::~Color_BM(void)
{
if(pSource!=NULL)delete pSource;
}


void Color_BM::infoshow()
{
cout<<"head:"<<(char*)(&this->INIT.bfType)<<endl;
cout<<"size:"<<this->INIT.bfSize<<endl;
// cout<<"bfReserved1:"<<this->INIT.bfReserved1<<endl;
// cout<<"bfReserved2:"<<this->INIT.bfReserved2<<endl;
cout<<"headlenth:"<<INIT.bfOffBits<<endl<<endl;

cout<<"biBitCount:"<<INFO.biBitCount<<endl;
cout<<"biClrImportant:"<<INFO.biClrImportant<<endl;
cout<<"biClrUsed:"<<INFO.biClrUsed<<endl;
cout<<"biCompression:"<<INFO.biCompression<<endl;
cout<<"biHeight:"<<INFO.biHeight<<endl;
cout<<"biPlanes:"<<INFO.biPlanes<<endl;
cout<<"biSize:"<<INFO.biSize<<endl; cout<<"biSizeImage:"<<INFO.biSizeImage<<endl;
cout<<"biWidth:"<<INFO.biWidth<<endl;
cout<<"biXPelsPerMeter:"<<INFO.biXPelsPerMeter<<endl;
cout<<"biYPelsPerMeter:"<<INFO.biYPelsPerMeter<<endl<<endl;
}
void Color_BM::overturn(void)
{
long i;
RGBex *sourceRGB=(RGBex*)pSource;
char *tarRGBtemp=new char[INFO.biHeight*INFO.biWidth*INFO.biBitCount/8];
RGBex *tarRGB=(RGBex*)tarRGBtemp;
for(i=0;i<INFO.biSizeImage/4;i++)
{
tarRGB[INFO.biSizeImage/4-i].a=sourceRGB[i].a;
tarRGB[INFO.biSizeImage/4-i].b=sourceRGB[i].b;
tarRGB[INFO.biSizeImage/4-i].g=sourceRGB[i].g;
tarRGB[INFO.biSizeImage/4-i].r=sourceRGB[i].r;
}
FILE *ptarBM=fopen("test.bmp","wb+");
void* ptar=(void*)tarRGB;
WriteToFile(ptarBM,&ptar);
// if(tarRGB!=NULL)delete tarRGB;
}

int Color_BM::GetSquareBMP(int X, int Y, int W, int L)
{
long Gwidth,Gheight,Gsize,x,y,z;
RGBex *sourceRGB=(RGBex*)pSource;
RGBex *Gcolor;
tagBITMAPFILEHEADER Ginit;
tagBITMAPINFOHEADER Ginfo;

Gwidth=W;
Gheight=L;
z=0;

Gsize=Gwidth*Gheight*INFO.biBitCount/8;
Gcolor=new RGBex[Gwidth*Gheight];
for(y=Y;y<Y+L;y++)
{
for(x=X;x<X+W;x++)
{
Gcolor[z].a=sourceRGB[x+y*INFO.biWidth].a;
Gcolor[z].b=sourceRGB[x+y*INFO.biWidth].b;
Gcolor[z].g=sourceRGB[x+y*INFO.biWidth].g;
Gcolor[z].r=sourceRGB[x+y*INFO.biWidth].r;
z++;
}
}
Ginit.bfType=INIT.bfType;
Ginit.bfSize=sizeof(tagBITMAPFILEHEADER)+sizeof(tagBITMAPINFOHEADER)+Gsize;
Ginit.bfOffBits=sizeof(BITMAPFILEHEADER);
Ginit.bfReserved1=0;
Ginit.bfReserved2=0;

Ginfo.biSize=sizeof(BITMAPINFOHEADER);
Ginfo.biWidth=Gwidth;
Ginfo.biHeight=Gheight;
Ginfo.biPlanes=1;
Ginfo.biBitCount=32;
Ginfo.biCompression=BI_RGB;
Ginfo.biXPelsPerMeter=INFO.biXPelsPerMeter;
Ginfo.biYPelsPerMeter=INFO.biYPelsPerMeter;
Ginfo.biClrUsed=INFO.biClrUsed;
Ginfo.biClrImportant=INFO.biClrImportant;
Ginfo.biSizeImage=Gsize;

void *pbit=(void*)Gcolor;
FILE *pftar=fopen("GetSquare.bmp","wb+");
WriteToFile(pftar,&pbit,&Ginit,&Ginfo);
fclose(pftar);
pbit=NULL;
if(Gcolor!=NULL)delete Gcolor;
return 0;
}



main:

void main()
{
char s[50];
do
{
cout<<"BMP name:";
cin>>s;
FILE *pf1;
if((pf1=fopen(s,"rb"))==NULL)
{
cout<<"can't open!"<<endl;
return;
}
cout<<"test1"<<endl;
Color_BM color1(pf1);
color1.infoshow();
color1.GetSquareBMP(100,100,200,200);
}while(!(s[0]=='Q' && s[1]=='U'));
}

...全文
201 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
实达诚实 2009-02-25
  • 打赏
  • 举报
回复
Mark一下!

有时间再看!
liujianwish 2009-02-25
  • 打赏
  • 举报
回复
这代段码只是测试32位图的。提问中注明了。
请大虾在帮忙看看
liujianwish 2009-02-25
  • 打赏
  • 举报
回复

Color_BM::Color_BM(FILE* source)
: pSource(NULL)
, ImageSize(0)
{
long SizeFixel,SizeBit;
pBM=source;
fread(&INIT,sizeof(BITMAPFILEHEADER),1,pBM);
fread(&INFO,sizeof(tagBITMAPINFOHEADER),1,pBM);
SizeFixel=INFO.biHeight*INFO.biWidth;
SizeBit=(INFO.biWidth*INFO.biBitCount+31)/32*4*INFO.biHeight;
pSource=new char[SizeBit];
fread(pSource,SizeBit,1,pBM);
}

看了cnzdgs的回复作了如上修改,测试了几幅32位图,都能正常截图了(仅对32位图)。谢谢cnzdgs大虾。
各位大虾若发现还有什么问题欢迎指出。谢谢。
能提供关于各类图操作的大虾帮忙再发一下。。目前搜出来的都太零乱了。
cnzdgs 2009-02-24
  • 打赏
  • 举报
回复
Color_BM::Color_BM(FILE* source)
: pSource(NULL)
, ImageSize(0)
{
long SizeFixel,SizeBit;
SizeFixel=INFO.biHeight*INFO.biWidth; // 这时INFO尚未初始化
SizeBit=INFO.biHeight*INFO.biWidth*INFO.biBitCount/8; // 应该用每行的字节数((INFO.biWidth*INFO.biBitCount+31)/32*4)乘以高度
pBM=source;
fread(&INIT,sizeof(BITMAPFILEHEADER),1,pBM);
fread(&INFO,sizeof(tagBITMAPINFOHEADER),1,pBM);
pSource=new char[SizeBit]; // 没有考虑调色板数据(256色及以下)
fread(pSource,SizeBit,1,pBM);
}

先把上述问题改好再看有没有问题。
lllsui 2009-02-24
  • 打赏
  • 举报
回复
up
yc_8301 2009-02-24
  • 打赏
  • 举报
回复
up
梅文海 2009-02-24
  • 打赏
  • 举报
回复
看了半天没有发现问题,只发现了一个 bug
Color_BM::Color_BM(FILE* source)
: pSource(NULL)
, ImageSize(0)
{
long SizeFixel,SizeBit;
SizeFixel=INFO.biHeight*INFO.biWidth;
SizeBit=INFO.biHeight*INFO.biWidth*INFO.biBitCount/8;
pBM=source;
fread(&INIT,sizeof(BITMAPFILEHEADER),1,pBM);
fread(&INFO,sizeof(tagBITMAPINFOHEADER),1,pBM);
pSource=new char[SizeBit];
fread(pSource,SizeBit,1,pBM);
}
应该这样写:
Color_BM::Color_BM(FILE* source)
: pSource(NULL)
, ImageSize(0)
{
long SizeFixel,SizeBit;
pBM=source;
fread(&INIT,sizeof(BITMAPFILEHEADER),1,pBM);
fread(&INFO,sizeof(BITMAPINFOHEADER),1,pBM);
SizeFixel=INFO.biHeight*INFO.biWidth;
SizeBit=INFO.biHeight*INFO.biWidth*INFO.biBitCount/8;
pSource=new char[SizeBit];
fread(pSource,SizeBit,1,pBM);
}
liujianwish 2009-02-20
  • 打赏
  • 举报
回复
少贴出来了。。不好意思。
补上
WriteToFile:

int Color_BM::WriteToFile(FILE *pfile,void **pTar,tagBITMAPFILEHEADER *Winit,tagBITMAPINFOHEADER *Winfo)
{
if(Winit==NULL)Winit=&INIT;
if(Winfo==NULL)Winfo=&INFO;
fseek(pfile,0,SEEK_SET);
fwrite(Winit,sizeof(tagBITMAPFILEHEADER),1,pfile);
fwrite(Winfo,sizeof(tagBITMAPINFOHEADER),1,pfile);
fwrite(*pTar,Winfo->biSizeImage,1,pfile);
fclose(pfile);
return 1;
}

Chivalry 2009-02-20
  • 打赏
  • 举报
回复
没有贴出来WriteToFile
Sharp1070329152 2009-02-20
  • 打赏
  • 举报
回复
WriteToFile() 函数提供一下吗

19,464

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧