C++图片处理小问题

djjlove_2008 2010-07-23 10:18:07
#include <stdafx.h>
#include <Windows.h>
#include <ctime>
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
//---------------------------------------------------------------------------------------
//以下该模块是完成BMP图像(彩色图像是24bit RGB各8bit)的像素获取,并存在文件名为xiang_su_zhi.txt中
unsigned char *pBmpBuf;//读入图像数据的指针
unsigned char *pResult;

int bmpWidth;//图像的宽
int bmpHeight;//图像的高

int main()
{
FILE *fp=fopen("D:\\Raw.BMP","r+b");//二进制读方式打开指定的图像文件

if(fp==0)
return 0;

//跳过位图文件头结构BITMAPFILEHEADER

fseek(fp, sizeof(BITMAPFILEHEADER),0);

//定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中

BITMAPINFOHEADER head;

fread(&head, sizeof(BITMAPINFOHEADER),1,fp); //获取图像宽、高、每像素所占位数等信息

bmpWidth = head.biWidth;

bmpHeight = head.biHeight;

//申请位图数据所需要的空间,读位图数据进内存

pBmpBuf=new unsigned char[(bmpWidth + 2) * (bmpHeight+2)];
pResult = new unsigned char[(bmpWidth+2)*(bmpHeight+2)];
fseek(fp,0 - (bmpWidth+2) *(bmpHeight+2),SEEK_END);
fread(pBmpBuf,1,(bmpWidth+2) *(bmpHeight+2),fp);


for(int i = 2; i < bmpWidth - 2; ++i)
{
for(int j = 2; j < bmpHeight - 2; ++j)
{
pBmpBuf[i * bmpWidth + j] += pBmpBuf[(i - 2) * bmpWidth + j] + pBmpBuf[(i + 2) * bmpWidth + j]
+ pBmpBuf[i * bmpWidth + j - 2] + pBmpBuf[i * bmpWidth + j + 2];
pResult[i*bmpWidth+j] = pBmpBuf[i * bmpWidth + j];
}

}



/* //另一种方式处理
int nonce[5] = {0};
for(int i=4;i<bmpHeight-4;i++)
{
for(int j=4;j<bmpWidth-4;j++)
{
nonce[0] = pBmpBuf[i*bmpWidth+j];
nonce[1] = pBmpBuf[i*bmpWidth+j + 2]+pBmpBuf[i*bmpWidth+j + 4];
nonce[2] = pBmpBuf[i*bmpWidth+j - 2]+pBmpBuf[i*bmpWidth+j + 4];
nonce[3] = pBmpBuf[(i + 2)*bmpWidth+j]+pBmpBuf[(i + 4)*bmpWidth+j];
nonce[4] = pBmpBuf[(i - 2)*bmpWidth+j]+pBmpBuf[(i + 4)*bmpWidth+j];
int nValue;
nValue = (int)nonce[0] + (int)nonce[1] + (int)nonce[2] + (int)nonce[3] + (int)nonce[4];
if (nValue >=255)
{
nValue = 255;
}
pResult[i*bmpWidth+j] = (unsigned char)nValue;
}

}*/


fseek(fp,0 - bmpWidth *bmpHeight,SEEK_END);
fwrite(pResult,1,bmpWidth *bmpHeight,fp);
fclose(fp);

system("pause");
return 0;
}

在我的D盘下有个Raw.BMP图像,这段程序用来简单处理这个图像,为什么有错,刚入门,呵呵。
...全文
87 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
zmshy2128 2010-07-23
  • 打赏
  • 举报
回复
BMP文件格式,

文件头 + 图像头 + 调色板(真彩色图像没有这部分) + 像素数据

pBmpBuf=new unsigned char[(bmpWidth + 2) * (bmpHeight+2)];
pResult = new unsigned char[(bmpWidth+2)*(bmpHeight+2)];
为什么加2呢?

pBmpBuf[i * bmpWidth + j] += pBmpBuf[(i - 2) * bmpWidth + j] + pBmpBuf[(i + 2) * bmpWidth + j]
+ pBmpBuf[i * bmpWidth + j - 2] + pBmpBuf[i * bmpWidth + j + 2];
这一段的目的何在呢,而且代码肯定有错
如果是真彩色图像, 保存的是B0 G0 R0 B1 G1 R1 B2 G2 R2 的顺序
djjlove_2008 2010-07-23
  • 打赏
  • 举报
回复
你们帮我看看,这道程序运行时会有点报错,关于图像的原理我也不太明白。。。。
chengzhe 2010-07-23
  • 打赏
  • 举报
回复
彩色 灰度 还是二值图像 调色板怎么没有读呀
zmshy2128 2010-07-23
  • 打赏
  • 举报
回复
上面代码对非真彩色图像,也是读取失败的。
xushuai0794 2010-07-23
  • 打赏
  • 举报
回复
给你个完整的读入函数(你自己在后面加个fwrite就OK):

typedef unsigned char BYTE;

BYTE *pBmpBuf;//读入图像数据的指针
BYTE *pResult;

int biWeigh;//图像的宽
int biHeight;//图像的高

bool Read24bitBmp(char *fileName)
{
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
FILE *fp = fopen(fileName, "rb");
if(fp == NULL)
return false;

fread(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);
fread(&bih, 1, sizeof(BITMAPINFOHEADER), fp);

if(bfh.bfType != 0x4D42 || bih.biCompression != 0 || bih.biBitCount != 24)
{
fclose(fp);
return false;
}

bitcount = (BYTE)bih.biBitCount;
height = bih.biHeight;
width = bih.biWidth;

if(texData != NULL)
{
delete [](texData), (texData) == NULL;
}
if(bmpData != NULL)
{
delete [](bmpData), (bmpData) == NULL;
}

int Ppels = bitcount >> 3;
int bmpLineCount = (width * Ppels + 3) & ~0x3;
int texLineCount = width * Ppels;
bmpData = new BYTE [bmpLineCount * height];
texData = new BYTE [texLineCount * height];
fseek(fp, bfh.bfOffBits, SEEK_SET);
fread(bmpData, 1, bmpLineCount * height, fp);
fclose(fp);

BYTE *bmpPtr = bmpData;
BYTE *texPtr = texData;
for(int j = 0; j < height; j++)
{
for(int i = 0; i < texLineCount; i += Ppels)
{
texPtr[i + 0] = bmpPtr[i + 2];
texPtr[i + 1] = bmpPtr[i + 1];
texPtr[i + 2] = bmpPtr[i + 0];
}
texPtr += texLineCount;
bmpPtr += bmpLineCount;
}

delete [](bmpData), (bmpData) = NULL;
return true;
}
xushuai0794 2010-07-23
  • 打赏
  • 举报
回复
你的代码书写有很多问题,第一就是要检测是不是BMP图像,这是一个必须的,也是一个很好的习惯。。。
其次就是你拿定义的两个BUFFER
int bmpLineCount = (bmpWidth* Ppels + 3) & ~0x3; //经过处理的(要求一行图像信息必须是4的整数倍)
int texLineCount = bmpWidth* Ppels;
pBmpBuf=new unsigned char bmpLineCount * bmpHeight];
pResult = new unsigned char [bmpLineCount * height];
texData = new unsigned char [texLineCount * height];
fread(bmpData, 1, bmpLineCount * height, fp);
fclose(fp);

还有就是你的feek前后要注意,如果是用SEEK_END的形式,读完后指针指向末尾了。。。。

64,632

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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