㈠ 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);