㈠ c语言 读取一副BMP格式的图像文件,并将并将其旋转180度后输出一个新的BMP格式的图
先去看看bmp图片的格式,一般就是文件头信息和文件数据信息。
你需要做的是先从bmp图片中解析出头信息,找到是什么格式的888,565,555这种,然后还需要找到宽高,旋转180°就是将数据左右对称,上下对称。
最后把头信息和你改过的数据信息组合起来就可以了
㈡ 用C语言编写程序处理图片bmp文件 1.读取图片的宽度,高度,每个像素所需的位数,水平分辨率,垂直
#include<windows.h>
//读bmp图片需要两个结构
#pragmapack(push,enter_defBM,1)//指定内存对齐单位为1。
typedefstructtagBmpFileHeader
{
WORDbfType;//文件类型BM
DWORDbfSize;//文件大小
WORDbfReserved1;//保留字
WORDbfReserved2;//保留字
DWORDbfOffBits;//位图的数据信息离文件头的偏移量
}BFH;
typedefstructtagBmpImgHeader
{
DWORDbiSize;//表示本结构的大小,0X28
LONGbiWidth;//位图的宽度
LONGbiHeight;//位图的高度
WORDbiPlanes;//位面数永远为1
WORDbiBitCount;//位图的位数
DWORDbiCompression;//压缩类型
DWORDbiSizeImage;//表示位图数据区域的大小
LONGbiXPelsPerMeter;//表示显示设备的水平分辨率
LONGbiYPelsPerMeter;//表示显示设备的垂直分辨率
DWORDbiClrUsed;//实际使用的颜色数目
DWORDbiClrImportant;//重要的颜色数量
}BIH;
#pragmapack(pop,enter_defBM)//恢复默认内存对齐单位。
#defineHDIBHANDLE//位图句柄
DWORDWINAPIDIBNumColors(BYTE*data)
{
WORDwBitCount;
DWORDdwClrUsed=((BIH*)data)->biClrUsed;
if(dwClrUsed!=0)return(WORD)dwClrUsed;
wBitCount=((BIH*)data)->biBitCount;
return1<<wBitCount;
}
WORDWINAPIPaletteSize(BYTE*data)
{
return(WORD)(::DIBNumColors(data)*sizeof(RGBQUAD));
}
BYTE*WINAPIFindDIBBits(BYTE*data)
{
return(data+*(DWORD*)data+::PaletteSize(data));
}
//获取Bmp的宽度
DWORDFARDIBWidth(constBYTE*data)
{
BIH*pbmi;
pbmi=(BIH*)data;
if(pbmi->biSize==sizeof(BIH))returnpbmi->biWidth;
elsereturn-1;
}
//获取Bmp的高度
DWORDFARDIBHeight(constBYTE*data)
{
BIH*pbmi;
pbmi=(BIH*)data;
if(pbmi->biSize==sizeof(BIH))returnpbmi->biHeight;
elsereturn-1;
}
//从文件读取Bmp图像数据
HDIBWINAPIReadDIBFile(FILE*fp)
{
BFHbmf;
HDIBhDIB;
BYTE*pData;
rewind(fp);
if(fread(&bmf,sizeof(BFH),1,fp)!=1)returnNULL;//文件读取错误
if(bmf.bfType!=19778)returnNULL;//文件类型错误
hDIB=(HDIB)::GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,bmf.bfSize);//为DIB分配内存
if(hDIB==0)returnNULL;//内存分配失败。
pData=(BYTE*)::GlobalLock((HGLOBAL)hDIB);//锁定
if(fread(pData,1,bmf.bfSize-sizeof(BFH),fp)!=(bmf.bfSize-sizeof(BFH)))//文件读取错误
{
::GlobalUnlock((HGLOBAL)hDIB);//解除锁定
::GlobalFree((HGLOBAL)hDIB);//释放内存
returnNULL;
}
::GlobalUnlock((HGLOBAL)hDIB);//解除锁定
returnhDIB;//返回DIB句柄
}
BOOLWINAPIPaintDIB(HDChDC,intposX,intposY,HDIBhDIB)
{
BYTE*pDIBHd;//BITMAPINFOHEADER指针
BYTE*pDIBBits;//DIB象素指针
BOOLbSuccess=FALSE;//成功标志
HPALETTEhPal=NULL;//DIB调色板
//HPALETTEhOldPal=NULL;//以前的调色板
if(hDIB==NULL)returnFALSE;//判断DIB对象是否为空
pDIBHd=(BYTE*)::GlobalLock((HGLOBAL)hDIB);//锁定DIB
pDIBBits=::FindDIBBits(pDIBHd);//找到DIB图像象素起始位置
::SetStretchBltMode(hDC,COLORONCOLOR);//设置显示模式
//调用SetDIBitsToDevice()来绘制DIB对象
bSuccess=::SetDIBitsToDevice(hDC,//hDC
posX,posY,
((BIH*)pDIBHd)->biWidth,//nDestWidth
((BIH*)pDIBHd)->biHeight,//nDestHeight
0,//SrcX
0,//SrcY
0,//nStartScan
(WORD)DIBHeight(pDIBHd),//nNumScans
pDIBBits,//lpBits
(LPBITMAPINFO)pDIBHd,//lpBitsInfo
DIB_RGB_COLORS);//wUsage
::GlobalUnlock((HGLOBAL)hDIB);//解除锁定
returnbSuccess;
}
//打印位图信息
VOIDWINAPIPrintDIBInfo(HDIBhDIB)
{
BYTE*pDIBHd=(BYTE*)::GlobalLock((HGLOBAL)hDIB);
BIH*pbmi=(BIH*)pDIBHd;
constchar*lp[]=
{
"位图信息长度:%d ",
"位图图像大小:%dx%d ",
"位面数:%d ",
"位图颜色深度:%d ",
"位图数据压缩类型:%d ",
"位图数据区域大小:%d ",
"位图分辨率:水平%ddpi,垂直%ddpi ",
};
printf("WindowsV3cBitmapInfoHeader信息 ");
printf(lp[0],pbmi->biSize);
printf(lp[1],pbmi->biWidth,pbmi->biHeight);
printf(lp[2],pbmi->biPlanes);
printf(lp[3],pbmi->biBitCount);
printf(lp[4],pbmi->biCompression);
printf(lp[5],pbmi->biSizeImage);
printf(lp[6],(LONG)(pbmi->biXPelsPerMeter*0.0254f+0.5f),(LONG)(pbmi->biYPelsPerMeter*0.0254f+0.5f));
::GlobalUnlock((HGLOBAL)hDIB);//解除锁定
}intmain(intargc,char*argv[])
{
HDIBx;
FILE*fp=fopen("1.bmp","rb");
if(fp==NULL)return-1;
x=ReadDIBFile(fp);
printf("DIBhandle%u",x);
PaintDIB(GetDC(NULL),0,0,x);
PrintDIBInfo(x);
return0;
}
㈢ 怎样用c语言对bmp图像进行线性拉伸
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
usingnamespacestd;
usingnamespacecv;
MatXianChange(Mat&img,doublealt,intbase)//灰度线性变化、
{
CV_Assert(img.depth()!=sizeof(uchar));//声明只对深度8bit的图像操作
Mattemp=img.clone();
intchannels=img.channels();//获取图像channel
intnrows=img.rows;//矩阵的行数
intncols=img.cols*channels;//矩阵的总列数=列数*channel分量数
if(img.isContinuous())//判断矩阵是否连续,若连续,我们相当于只需要遍历一个一维数组
{
ncols*=nrows;
nrows=1;//一维数组
}
//遍历像素点灰度值
for(inti=0;i<nrows;i++)
{
uchar*p=temp.ptr<uchar>(i);//获取行地址
for(intj=0;j<ncols;j++)
{
p[j]=alt*p[j]+base;//修改灰度值
if(p[j]>255)
p[j]=255;
if(p[j]<0)
p[j]=0;
}
}
returntemp;
}
MatXianStretch(Mat&img,inta,intb,intc,intd)//线性灰度拉伸,将[a,b]拉伸到[c,d]
{
CV_Assert(img.depth()!=sizeof(uchar));//声明只对深度8bit的图像操作
Mattemp=img.clone();
intchannels=img.channels();//获取图像channel
intnrows=img.rows;//矩阵的行数
intncols=img.cols*channels;//矩阵的总列数=列数*channel分量数
if(img.isContinuous())//判断矩阵是否连续,若连续,我们相当于只需要遍历一个一维数组
{
ncols*=nrows;
nrows=1;//一维数组
}
//遍历像素点灰度值
for(inti=0;i<nrows;i++)
{
uchar*p=temp.ptr<uchar>(i);//获取行地址
for(intj=0;j<ncols;j++)
{
if(p[j]<a)
p[j]=c/b*p[j];
elseif(p[j]>a&&p[j]<b)
p[j]=(d-c)/(b-a)*(p[j]-a)+c;
else
p[j]=(255-d)/(255-b)*(p[j]-b)+d;
}
}
returntemp;
}
MatHistogramEqu(Mat&img)//直方均衡
{
CV_Assert(img.depth()!=sizeof(uchar));//声明只对深度8bit的图像操作
Mattemp=img.clone();
intgrayNum[260]={0};
intgrayMap[260]={0};
intchannels=img.channels();//获取图像channel
intnrows=img.rows;//矩阵的行数
intncols=img.cols*channels;//矩阵的总列数=列数*channel分量数
intallPixel=nrows*ncols;//图像的像素总数
intc;//用于计算累积分布概率
if(img.isContinuous())//判断矩阵是否连续,若连续,我们相当于只需要遍历一个一维数组
{
ncols*=nrows;
nrows=1;//一维数组
}
//遍历像素点灰度值
for(inti=0;i<nrows;i++)
{
uchar*p=temp.ptr<uchar>(i);//获取行地址
for(intj=0;j<ncols;j++)
{
grayNum[p[j]]++;//原图像的直方图
}
}
for(inti=0;i<256;i++)//重新定义新的直方图
{
c=0;
for(intj=0;j<=i;j++)
{
c+=grayNum[j];
grayMap[i]=int(255*c/allPixel);
}
//printf("%d%d ",i,grayMap[i]);
} for(inti=0;i<nrows;i++)//重新定义新的直方图
{
uchar*p=temp.ptr<uchar>(i);//获取行地址
for(intj=0;j<ncols;j++)
{
p[j]=grayMap[p[j]];
}
}
returntemp;
}
intmain()
{
stringpicName="lena256.jpg";
MatA=imread(picName,CV_LOAD_IMAGE_GRAYSCALE);//读入灰度图像
imshow("变换前",A);
MatB=XianChange(A,1,20);//根据需要设置不同的参数
imshow("线性变换后",B);
MatC=XianStretch(A,10,100,20,50);//根据需要设置不同的参数
imshow("线性拉伸后",C);
MatD=HistogramEqu(A);
imshow("直方均衡后",D);
waitKey();
return0;
}
㈣ C语言 BMP文件
BMP格式文件是位图,里面保存的是像素点的红\绿\蓝三原色的亮度,并没有保存什么特定的图形,所以BMP文件不能直接读取出特定图形的个数.
当然通过图形识别技术,也是可以识别出直线,圆等几何信息.
文字识别技术可以识别出其中包含的文字信息
脸部识别技术可以识别出人脸部的特征信息.
这些算法都比较复杂.都是不能直接识别的.
当然也有能直接读出特定图形的文件格式,这些格式统称矢量图,比如.dwg(AutoCAD), .dxf, .wmf等.
其文件内容就是记录图片的什么地方有什么图形.
㈤ 利用c语言怎样对bmp图像进行平移的操作
位图平移没有这方面的库函数,必须自己来实现,下面是位图平移的参考代码:
#include "stdafx.h"
#include<windows.h>
#include<stdio.h>
#include<math.h>
int _tmain(int argc, _TCHAR* argv[])
{
int width;
int height;
RGBQUAD *pTableColor;
unsigned char *pBmpBuf1,*pBmpBuf2;
BITMAPFILEHEADER bfhead;
BITMAPINFOHEADER bihead;
//读出源图像的信息
FILE *fpr=fopen("E:\picture\dog.bmp","rb");
if(fpr==0)
return 0;
fread(&bfhead,14,1,fpr);
fread(&bihead,40,1,fpr);
width=bihead.biWidth;
height=bihead.biHeight;
int LineByte=(width*8/8+3)/4*4;
pTableColor=new RGBQUAD[256];
fread(pTableColor,sizeof(RGBQUAD),256,fpr);
pBmpBuf1=new unsigned char[LineByte*height];
fread(pBmpBuf1,LineByte*height,1,fpr);
fclose(fpr);
//将处理后的图像赋值为白色
pBmpBuf2=new unsigned char[LineByte*height];
for(int i=0;i<height;i++)
for(int j=0;j<width;j++)
{
unsigned char *p;
p=(unsigned char*)(pBmpBuf2+LineByte*i+j);
(*p)=255;
}
//左右平移功能的实现
int t;
printf("请输入左平移或右平移的大小t(左移t<0,右移t>0):");
scanf("%d",&t);
int k=abs(t);
printf("%d",k);
if(t<0)
{
if(t>=(-width))
{
for(int i=0;i<height;i++)
for(int j=0;j<(width-k);j++)
{
unsigned char *p1,*p2;
p1=pBmpBuf1+LineByte*i+j+k;
p2=pBmpBuf2+LineByte*i+j;
(*p2)=(*p1);
}
}
}
else
{
if(t<=width)
{
for(int i=0;i<height;i++)
for(int j=k;j<width;j++)
{
unsigned char *p1,*p2;
p1=pBmpBuf1+LineByte*i+j-k;
p2=pBmpBuf2+LineByte*i+j;
(*p2)=(*p1);
}
}
}
//保存处理后的图像
FILE *fpw=fopen("dog.bmp","wb");
fwrite(&bfhead,14,1,fpw);
fwrite(&bihead,40,1,fpw);
fwrite(pTableColor,sizeof(RGBQUAD),256,fpw);
fwrite(pBmpBuf2,LineByte*height,1,fpw);
fclose(fpw);
return 0;
}
㈥ BMP图片分析和显示 c语言 压缩,解压缩
bmp是一种简单的图片格式,但要解释清楚也不是件容易的事。
一个bmp文件可以分为4个部分,第一部分是文件信息,第二部分是图片信息,第三部分是调色板,第四部分就是图片的数据了。
第一部分主要是说,我就是bmp格式的文件,我的大小是多少,我的图片数据存在什么地方。
第二部分主要是说,我这张图片宽度和长度分别是多少,颜色深度有几位,有没有压缩等信息。
颜色深度8bit 4bit 1bit的意思是说,大自然存在无穷的颜色,但计算机的存储是有限的,我只能每个像素点保存1bit的信息,也就是说,我只能保存两种颜色的信息。如果每个像素点保存4bit的信息,我就可以保存16种颜色了。如果每个像素点保存8bit的信息,我就可以保存256种颜色了。由此可见bit越长可以保存的颜色种类就越多。
第三部分要根据第二部分的来表示的。上面说了如果颜色深度是8bit,就可以保存256种颜色了,但具体是哪种颜色呢,这就要靠第三部分调色板来告诉你了,根据不同的bit长度,调色板的长度也不同,比如1bit,此部分就是有两种颜色,4bit就是16种颜色,8bit就是256种颜色,16bit时就就不再告诉大家各种颜色是什么了,因为颜色种类太多了。这时这部分反而只有三个数据,分别告诉大家,三个颜色分别在一个16bit数据的具体位置。如果图像深度是24bit,这部分就没有了,因为计算机只能显示24Bit的颜色。
第四部分就是存储具体图像数据的地方了,这个地方告诉我们,图片中的每一个像素点的颜色是什么。但是对于8bit 4bit 1bit的图像,他存的只是索引,告诉我们这个地方的颜色就是调色板里的第几个颜色。对于24bit的颜色就是保存颜色的身。而16位的就比较复杂,要通过一些位移运算来确定具体是什么颜色。
具体代码,网上多的是。我就不提供了。
㈦ 用C语言怎么把bmp格式的图片放大,因为在做图片识别需要放大截取的放大为统一大小。
原型:
int WINAPI icePub_imgZoom(char *strImgFilename,char *strBmpFilename,int newWidth,int newHeight,int flag)
输入:strImgFilename 待处理图像文件名
strBmpFilename 结果bmp文件名
newWidth 新图宽
newHeight 新图高
flag 0 等比缩放; 1 完全缩放
输出:
typedef int (WINAPI ICEPUB_IMGZOOM)(char *strImgFilename,char *strBmpFilename,int newWidth,int newHeight,int flag);
ICEPUB_IMGZOOM *icePub_imgZoom = 0;
HINSTANCE hDLLDrv = LoadLibrary("icePubDll.dll");
if(hDLLDrv)
{
icePub_imgZoom=(ICEPUB_IMGZOOM *)GetProcAddress(hDLLDrv,"icePub_imgZoom");
}
if(icePub_imgZoom)
{
icePub_imgZoom("a.jpg","a1.bmp",100,100,0);
icePub_imgZoom("d.png", "d1.bmp",50.80,1);
}
if(hDLLDrv)
FreeLibrary(hDLLDrv);