一个很简单的问题

langzi8818 2005-08-17 03:57:46
下面这个函数是把一张图片截成指定大小的图片,不过怎么也得不到,请高手指定那里错了?

BOOL SaveDIBAsSize(LPCSTR lpszDestName, LPCSTR lpszSourceName, DWORD dwWidth, DWORD dwHigh)
{
CFile file;

if(!file.Open(lpszSourceName, CFile::modeRead))
{
return FALSE;
}

BITMAPFILEHEADER bmpFileHead;
BITMAPINFOHEADER bmpInfoHead;

file.Read(&bmpFileHead, sizeof(bmpFileHead));
file.Read(&bmpInfoHead, sizeof(bmpInfoHead));

bmpFileHead.bfSize = 54+dwWidth * dwHigh;//8位,所以一个象素就是一个字节.

const int ImageSize = dwWidth * dwHigh;
BYTE* pImageSize = new BYTE[ImageSize];
memset(pImageSize, 0, ImageSize);
DWORD Seekto = (bmpInfoHead.biHeight - dwHigh)/2-1 + (bmpInfoHead.biWidth - dwWidth)/2;
file.Seek(Seekto, CFile::current);//移动到要读的地方
BYTE *p = pImageSize;
for(DWORD i = 0; i < dwHigh; i++)//逐行把数据读进去
{
file.Read(p, dwWidth);
p += dwWidth;
file.Seek(bmpInfoHead.biWidth - dwWidth, CFile::current);
}

//改变文件信息的内容
bmpInfoHead.biWidth = dwWidth;
bmpInfoHead.biHeight = dwHigh;
bmpInfoHead.biSize = dwWidth * dwHigh;

file.Close();

if(!file.Open(lpszDestName, CFile::modeWrite | CFile::modeCreate | CFile::modeNoTruncate))
{
delete []pImageSize;
return FALSE;
}

file.Write(&bmpFileHead, sizeof(bmpFileHead));
file.Write(&bmpInfoHead, sizeof(bmpInfoHead));
file.WriteHuge(pImageSize, ImageSize);
file.Close();
delete []pImageSize;
return TRUE;
}
...全文
115 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
langzi8818 2005-08-18
  • 打赏
  • 举报
回复
这个是我改后的,但是截取的图片不行,显示的时候就是一个颜色,比如红色。不知道那里错了
langzi8818 2005-08-18
  • 打赏
  • 举报
回复
BOOL SaveDIBAsSize(LPCSTR lpszDestName, LPCSTR lpszSourceName, DWORD dwWidth, DWORD dwHigh)
{
CFile file;

if(!file.Open(lpszSourceName, CFile::modeRead))
{
return FALSE;
}

BITMAPFILEHEADER bmpFileHead;
BITMAPINFOHEADER bmpInfoHead;

file.Read(&bmpFileHead, sizeof(bmpFileHead));
file.Read(&bmpInfoHead, sizeof(bmpInfoHead));
if(bmpFileHead.bfType != 0x4d42)
{
return FALSE;
}

int nColorSize = 1;
DWORD ImageSize = dwWidth * dwHigh * bmpInfoHead.biBitCount/8;
BYTE* pImageSize = new BYTE[ImageSize];
BYTE* pPalette = NULL;
DWORD Seekto = ( (bmpInfoHead.biHeight - dwHigh)/2-1 + (bmpInfoHead.biWidth - dwWidth)/2 ) * bmpInfoHead.biBitCount/8;

if( bmpInfoHead.biBitCount == 1 || bmpInfoHead.biBitCount == 4 || bmpInfoHead.biBitCount == 8)
{
for(int i = 0; i < bmpInfoHead.biBitCount; i++)
nColorSize = nColorSize * 2;

bmpFileHead.bfSize = 54+ImageSize + sizeof(RGBQUAD) * nColorSize;
bmpInfoHead.biWidth = dwWidth;
bmpInfoHead.biHeight = dwHigh;
bmpInfoHead.biSizeImage = ImageSize;

pPalette = new BYTE[sizeof(RGBQUAD) * nColorSize];
file.ReadHuge(pPalette, sizeof(RGBQUAD) * nColorSize);
}

else
{
bmpFileHead.bfSize = 54+ImageSize;
bmpInfoHead.biWidth = dwWidth;
bmpInfoHead.biHeight = dwHigh;
bmpInfoHead.biSizeImage = ImageSize;
}

file.Seek(Seekto, CFile::current);//移动到要读的地方
BYTE *p = pImageSize;
for(DWORD i = 0; i < dwHigh; i++)//逐行把数据读进去
{
file.ReadHuge(p, dwWidth * bmpInfoHead.biBitCount/8);
p += dwWidth * bmpInfoHead.biBitCount/8;
file.Seek( (bmpInfoHead.biWidth - dwWidth) * bmpInfoHead.biBitCount/8, CFile::current);
}

//改变文件信息的内容

file.Close();

if(!file.Open(lpszDestName, CFile::modeWrite | CFile::modeCreate | CFile::modeNoTruncate))
{
delete []pImageSize;
delete []pPalette;
return FALSE;
}

file.WriteHuge(&bmpFileHead, sizeof(bmpFileHead));
file.WriteHuge(&bmpInfoHead, sizeof(bmpInfoHead));
if(pPalette != NULL)
file.WriteHuge(pPalette, sizeof(RGBQUAD) * nColorSize);
file.WriteHuge(pImageSize, ImageSize);
file.Close();
delete []pImageSize;
delete []pPalette;
return TRUE;
}
vcmute 2005-08-17
  • 打赏
  • 举报
回复
最好 bmpInfoHead.biWidth 和 dwWidth 都是4的倍数,否则可能会有所偏差
vcmute 2005-08-17
  • 打赏
  • 举报
回复
不用添加 bmpFileHead.bfOffBits = bmpFileHead.bfSize - dwWidth * dwHigh ;
因为本来就是对的,hehe
vcmute 2005-08-17
  • 打赏
  • 举报
回复
bmpFileHead.bfSize = 54+dwWidth * dwHigh + sizeof(RGBQUAD) * 256
添加 bmpFileHead.bfOffBits = bmpFileHead.bfSize - dwWidth * dwHigh ;
去掉 memset(pPalette, 0, sizeof(RGBQUAD) * 256);
langzi8818 2005-08-17
  • 打赏
  • 举报
回复
BOOL SaveDIBAsSize(LPCSTR lpszDestName, LPCSTR lpszSourceName, DWORD dwWidth, DWORD dwHigh)
{
CFile file;

if(!file.Open(lpszSourceName, CFile::modeRead))
{
return FALSE;
}

BITMAPFILEHEADER bmpFileHead;
BITMAPINFOHEADER bmpInfoHead;

file.Read(&bmpFileHead, sizeof(bmpFileHead));
file.Read(&bmpInfoHead, sizeof(bmpInfoHead));

bmpFileHead.bfSize = 54+dwWidth * dwHigh;//8位,所以一个象素就是一个字节.

const int ImageSize = dwWidth * dwHigh;
BYTE* pImageSize = new BYTE[ImageSize];
BYTE* pPalette = new BYTE[sizeof(RGBQUAD) * 256];

file.ReadHuge(pPalette, sizeof(RGBQUAD) * 256);
memset(pPalette, 0, sizeof(RGBQUAD) * 256);
memset(pImageSize, 0, ImageSize);

DWORD Seekto = (bmpInfoHead.biHeight - dwHigh)/2-1 + (bmpInfoHead.biWidth - dwWidth)/2;
file.Seek(Seekto, CFile::current);//移动到要读的地方
BYTE *p = pImageSize;
for(DWORD i = 0; i < dwHigh; i++)//逐行把数据读进去
{
file.Read(p, dwWidth);
p += dwWidth;
file.Seek(bmpInfoHead.biWidth - dwWidth, CFile::current);
}

//改变文件信息的内容
bmpInfoHead.biWidth = dwWidth;
bmpInfoHead.biHeight = dwHigh;
bmpInfoHead.biSize = dwWidth * dwHigh;

file.Close();

if(!file.Open(lpszDestName, CFile::modeWrite | CFile::modeCreate | CFile::modeNoTruncate))
{
delete []pImageSize;
delete []pPalette;
return FALSE;
}

file.Write(&bmpFileHead, sizeof(bmpFileHead));
file.Write(&bmpInfoHead, sizeof(bmpInfoHead));
file.WriteHuge(pPalette, sizeof(RGBQUAD) * 256);
file.WriteHuge(pImageSize, ImageSize);
file.Close();
delete []pImageSize;
delete []pPalette;
return TRUE;
}

这个是小弟修改后的,还是不行;请高手牺牲点时间指点一下~
langzi8818 2005-08-17
  • 打赏
  • 举报
回复
就是还要加入调色板了,大小应该是结构*256吧
vcmute 2005-08-17
  • 打赏
  • 举报
回复
bmpInfoHead.biSize = dwWidth * dwHigh;
用的256色的索引?定位就错了,前面有调色板的
dirdirdir3 2005-08-17
  • 打赏
  • 举报
回复
8位的话好像还有colortable的内容阿,要另外读取得,写入哦。

19,468

社区成员

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

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