亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

BMP位圖文件結構及平滑縮放

2019-09-06 23:33:58
字體:
來源:轉載
供稿:網友

                    -- 用普通方法顯示BMP位圖,占內存大,速度慢,在圖形縮小時,失真嚴重,在低顏色位數的設備上顯示高顏色位數的圖形圖形時失真大。本文采用視頻函數顯示BMP位圖,可以消除以上的缺點。

---- 一、BMP文件結構

---- 1. BMP文件組成

---- BMP文件由文件頭、位圖信息頭、顏色信息和圖形數據四部分組成。

---- 2. BMP文件頭

---- BMP文件頭數據結構含有BMP文件的類型、文件大小和位圖起始位置等信息。

---- 其結構定義如下:

typedef struct tagBITMAPFILEHEADER
{
WORDbfType;   // 位圖文件的類型,必須為BM
DWORD   bfSize;   // 位圖文件的大小,以字節為單位
WORDbfReserved1;  // 位圖文件保留字,必須為0
WORDbfReserved2;  // 位圖文件保留字,必須為0
DWORD   bfOffBits; // 位圖數據的起始位置,以相對于位圖
// 文件頭的偏移量表示,以字節為單位
} BITMAPFILEHEADER;


---- 3. 位圖信息頭 ----
BMP位圖信息頭數據用于說明位圖的尺寸等信息。
typedef struct tagBITMAPINFOHEADER{
  DWORD  biSize;   // 本結構所占用字節數
  LONGbiWidth;  // 位圖的寬度,以像素為單位
  LONGbiHeight; // 位圖的高度,以像素為單位
  WORD   biPlanes; // 目標設備的級別,必須為1
  WORD   biBitCount// 每個像素所需的位數,必須是1(雙色),
 // 4(16色),8(256色)或24(真彩色)之一
  DWORD  biCompression;   // 位圖壓縮類型,必須是 0(不壓縮),
 // 1(BI_RLE8壓縮類型)或2(BI_RLE4壓縮類型)之一
  DWORD  biSizeImage; // 位圖的大小,以字節為單位
  LONGbiXPelsPerMeter; // 位圖水平分辨率,每米像素數
  LONGbiYPelsPerMeter;  // 位圖垂直分辨率,每米像素數
  DWORD  biClrUsed;// 位圖實際使用的顏色表中的顏色數
  DWORD  biClrImportant;// 位圖顯示過程中重要的顏色數
} BITMAPINFOHEADER;


---- 4. 顏色表
---- 顏色表用于說明位圖中的顏色,它有若干個表項,每一個表項是一個RGBQUAD類型的結構,定義一種顏色。RGBQUAD結構的定義如下:

typedef struct tagRGBQUAD {
BYTErgbBlue;// 藍色的亮度(值范圍為0-255)
BYTErgbGreen;   // 綠色的亮度(值范圍為0-255)
BYTErgbRed; // 紅色的亮度(值范圍為0-255)
BYTErgbReserved;// 保留,必須為0
} RGBQUAD;
顏色表中RGBQUAD結構數據的個數有biBitCount來確定:
當biBitCount=1,4,8時,分別有2,16,256個表項;
當biBitCount=24時,沒有顏色表項。
  位圖信息頭和顏色表組成位圖信息,BITMAPINFO結構定義如下:
typedef struct tagBITMAPINFO {
  BITMAPINFOHEADER bmiHeader;   // 位圖信息頭
  RGBQUAD  bmiColors[1];  // 顏色表
} BITMAPINFO;


---- 5. 位圖數據
---- 位圖數據記錄了位圖的每一個像素值,記錄順序是在掃描行內是從左到右,掃描行之間是從下到上。位圖的一個像素值所占的字節數:

當biBitCount=1時,8個像素占1個字節;
當biBitCount=4時,2個像素占1個字節;
當biBitCount=8時,1個像素占1個字節;
當biBitCount=24時,1個像素占3個字節;
Windows規定一個掃描行所占的字節數必須是
4的倍數(即以long為單位),不足的以0填充,
一個掃描行所占的字節數計算方法:
DataSizePerLine= (biWidth* biBitCount+31)/8;  
// 一個掃描行所占的字節數
DataSizePerLine= DataSizePerLine/4*4; // 字節數必須是4的倍數
位圖數據的大小(不壓縮情況下):
DataSize= DataSizePerLine* biHeight;


---- 二、BMP位圖一般顯示方法
---- 1. 申請內存空間用于存放位圖文件

---- GlobalAlloc(GHND,FileLength);

---- 2. 位圖文件讀入所申請內存空間中

---- LoadFileToMemory( mpBitsSrc,mFileName);

---- 3. 在OnPaint等函數中用創建顯示用位圖

---- 用CreateDIBitmap()創建顯示用位圖,用CreateCompatibleDC()創建兼容DC,

---- 用SelectBitmap()選擇顯示位圖。

---- 4. 用BitBlt或StretchBlt等函數顯示位圖

---- 5. 用DeleteObject()刪除所創建的位圖

---- 以上方法的缺點是: 1)顯示速度慢; 2) 內存占用大; 3) 位圖在縮小顯示時圖形失真大,(可通過安裝字體平滑軟件來解決); 4) 在低顏色位數的設備上(如256顯示模式)顯示高顏色位數的圖形(如真彩色)圖形失真嚴重。

---- 三、BMP位圖縮放顯示

---- 用DrawDib視頻函數來顯示位圖,內存占用少,速度快,而且還可以對圖形進行淡化(Dithering)處理。淡化處理是一種圖形算法,可以用來在一個支持比圖像所用顏色要少的設備上顯示彩色圖像。BMP位圖顯示方法如下:

---- 1. 打開視頻函數DrawDibOpen(),一般放在在構造函數中

---- 2. 申請內存空間用于存放位圖文件

---- GlobalAlloc(GHND,FileLength);

---- 3. 位圖文件讀入所申請內存空間中

---- LoadFileToMemory( mpBitsSrc,mFileName);

---- 4. 在OnPaint等函數中用DrawDibRealize(),DrawDibDraw()顯示位圖

---- 5. 關閉視頻函數DrawDibClose(),一般放在在析構函數中

---- 以上方法的優點是: 1)顯示速度快; 2) 內存占用少; 3) 縮放顯示時圖形失真小,4) 在低顏色位數的設備上顯示高顏色位數的圖形圖形時失真小; 5) 通過直接處理位圖數據,可以制作簡單動畫。

---- 四、CViewBimap類編程要點

---- 1. 在CViewBimap類中添加視頻函數等成員

HDRAWDIB  m_hDrawDib;  // 視頻函數
HANDLEmhBitsSrc; // 位圖文件句柄(內存)
LPSTR mpBitsSrc;  // 位圖文件地址(內存)
BITMAPINFOHEADER  *mpBitmapInfo;   // 位圖信息頭


---- 2. 在CViewBimap類構造函數中添加打開視頻函數
---- m_hDrawDib= DrawDibOpen();

---- 3. 在CViewBimap類析構函數中添加關閉視頻函數

if( m_hDrawDib != NULL)
 {
 DrawDibClose( m_hDrawDib);
 m_hDrawDib = NULL;
 }


---- 4. 在CViewBimap類圖形顯示函數OnPaint中添加GraphicDraw()
voidCViewBitmap::OnPaint()
{
CPaintDC dc(this); // device context for painting
GraphicDraw( );
}

voidCViewBitmap::GraphicDraw( void )
{
CClientDC  dc(this); // device context for painting
BITMAPFILEHEADER  *pBitmapFileHeader;
ULONG  bfoffBits= 0;
CPoint  Wid;

// 圖形文件名有效 (=0 BMP)
if( mBitmapFileType <  ID_BITMAP_BMP ) return;

// 圖形文件名有效 (=0 BMP)
// 準備顯示真彩位圖
pBitmapFileHeader= (BITMAPFILEHEADER *) mpBitsSrc;
bfoffBits= pBitmapFileHeader->bfOffBits;

// 使用普通函數顯示位圖

if( m_hDrawDib == NULL || mDispMethod == 0)
 {
 HBITMAP hBitmap=::CreateDIBitmap(dc.m_hDC,
mpBitmapInfo, CBM_INIT, mpBitsSrc+bfoffBits,
 (LPBITMAPINFO) mpBitmapInfo,DIB_RGB_COLORS);  
// 建立位圖
HDC hMemDC=::CreateCompatibleDC(dc.m_hDC);// 建立內存
HBITMAP hBitmapOld= SelectBitmap(hMemDC, hBitmap);  // 選擇對象
// 成員CRect mDispR用于指示圖形顯示區域的大小.
// 成員CPoint mPos用于指示圖形顯示起始位置坐標.
if( mPos.x  > (mpBitmapInfo- >biWidth - mDispR.Width() ))
mPos.x= mpBitmapInfo->biWidth - mDispR.Width() ;
 if( mPos.y  > (mpBitmapInfo- >biHeight- mDispR.Height()))
mPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
 if( mPos.x <  0 ) mPos.x= 0;
 if( mPos.y <  0 ) mPos.y= 0;

 if( mFullViewTog == 0)
{
// 顯示真彩位圖
::BitBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
hMemDC,mPos.x,mPos.y, SRCCOPY);
} else {
::StretchBlt(dc.m_hDC,0,0, mDispR.Width(), mDispR.Height(),
hMemDC,0,0, mpBitmapInfo- >biWidth, mpBitmapInfo-
>biHeight, SRCCOPY);
}
 // 結束顯示真彩位圖
 ::DeleteObject(SelectObject(hMemDC,hBitmapOld));  
// 刪 除 位 圖
 } else {

 // 使用視頻函數顯示位圖

 if( mPos.x  > (mpBitmapInfo- >biWidth - mDispR.Width() ))
mPos.x= mpBitmapInfo- >biWidth - mDispR.Width() ;
 if( mPos.y  > (mpBitmapInfo- >biHeight- mDispR.Height()))
mPos.y= mpBitmapInfo- >biHeight- mDispR.Height();
 if( mPos.x <  0 ) mPos.x= 0;
 if( mPos.y <  0 ) mPos.y= 0;

 // 顯示真彩位圖
 DrawDibRealize( m_hDrawDib, dc.GetSafeHdc(), TRUE);

 if( mFullViewTog == 0)
{
Wid.x= mDispR.Width();
Wid.y= mDispR.Height();
// 1:1 顯示時, 不能大于圖形大小
if( Wid.x  > mpBitmapInfo- >biWidth )
Wid.x = mpBitmapInfo- >biWidth;
if( Wid.y  > mpBitmapInfo- >biHeight)
Wid.y = mpBitmapInfo- >biHeight;

DrawDibDraw( m_hDrawDib, dc.GetSafeHdc()
, 0, 0, Wid.x, Wid.y,
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),
mPos.x, mPos.y, Wid.x, Wid.y, DDF_BACKGROUNDPAL);
} else {
DrawDibDraw( m_hDrawDib, dc.GetSafeHdc(),
0, 0, mDispR.Width(), mDispR.Height(),
mpBitmapInfo, (LPVOID) (mpBitsSrc+bfoffBits),
0, 0, mpBitmapInfo- >biWidth, mpBitmapInfo- >biHeight,
DDF_BACKGROUNDPAL);
}
 }
return;
}


---- 五、使用CViewBimap類顯示BMP位圖
---- 1. 在Visual C++5.0中新建一個名稱為mymap工程文件,類型為MFC AppWizard[exe]。在編譯運行通過后,在WorkSpace(如被關閉,用Alt_0打開)點擊ResourceView,點擊Menu左側的+符號展開Menu條目,雙擊IDR_MAINFRAME條目,進入菜單資源編輯,在'“查看(V)”下拉式菜單(英文版為View下拉式菜單)的尾部添加“ViewBitmap”條目,其ID為ID_VIEW_BITMAP。

---- 2. 在Visual C++5.0中點擊下拉式菜單Project- >Add To project- >Files...,將Bitmap0.h和Bitmap0.cpp添加到工程文件中。

---- 3. 在Visual C++5.0中按Ctrl_W進入MFC ClassWizard,選擇類名稱為CMainFrame,ObjectIDs: ID_VIEW_BITMAP,Messages選擇Command,然后點擊Add Fucction按鈕,然后輸入函數名為OnViewBimap。在添加OnViewBimap后,在Member functions: 中點擊OnViewBimap條目,點擊Edit Code按鈕編輯程序代碼。代碼如下:

void CMainFrame::OnViewBitmap()
{
// TODO: Add your command handler code here
CViewBitmap  *pViewBitmap= NULL;

pViewBitmap= new CViewBitmap( "BITMAP.BMP", this);
pViewBitmap- >ShowWindow( TRUE);
}


---- 并在該程序的頭部添加#include "bitmap0.h",然后編譯運行。
---- 4. 找一個大一點的真彩色的BMP位圖,將它拷貝到BITMAP.BMP中。

---- 5. 運行時,點擊下拉式菜單“查看(V)- >ViewBitmap”(英文版為View- > ViewBitmap)即可顯示BITMAP.BMP位圖。

---- 六、CViewBimap類功能說明

---- 1. 在客戶區中帶有水平和垂直滾動條。在位圖大小大于顯示客戶區時,可以使用滾動條;在位圖大小小于顯示客戶區或全屏顯示時,滾動條無效。

---- 2. 在客戶區中底部帶有狀態條。狀態條中的第一格為位圖信息,第二格為位圖顯示方法,可以是使用普通函數或使用視頻函數。在第二格區域內點擊鼠標,可在兩者之間接換。第三格為位圖顯示比例,可以是1;1顯示或全屏顯示。在第三格區域內點擊鼠標,可在兩者之間接換。在全屏顯示時,如果位圖比客戶區小,則對位圖放大; 如果位圖比客戶區大,則對位圖縮小。

---- 3. 支持文件拖放功能??梢詮馁Y源管理器中拖動一個位圖文件到客戶區,就可以顯示該位圖。

---- 程序調試通過后,可以找一個較大的真彩色位圖或調整客戶區比位圖小,在全屏顯示方式下,比較使用普通函數與使用視頻函數的差別??梢钥闯?,位圖放大時兩者差別不大,但在位圖縮小時,兩者差別明顯; 使用視頻函數時位圖失真小,顯示速度快。

---- 還可以從控制面板中將屏幕顯示方式從真彩色顯示模式切換到256色顯示模式,再比較使用普通函數與使用視頻函數顯示同一個真彩色位圖的差別?,F在可以體會到使用視頻函數的優越性了吧。

---- 在全屏顯示時,位圖的xy方向比例不相同,如要保持相同比例,可在顯示程序中加以適當調整即可,讀者可自行完成.
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
尤物九九久久国产精品的分类| 日韩亚洲欧美成人| 九九视频直播综合网| 亚洲福利视频网站| 日韩av在线免费看| 欧美一二三视频| 日韩免费黄色av| 日韩av在线影院| 亚洲免费影视第一页| 国产欧美一区二区三区久久人妖| 岛国av在线不卡| 日韩av理论片| 日韩视频在线一区| 国产日产久久高清欧美一区| 久久人人爽人人爽爽久久| 26uuu日韩精品一区二区| 日韩精品欧美激情| 国产91露脸中文字幕在线| 国产一区二区三区久久精品| 久久久黄色av| 亚洲一区二区中文| 91精品久久久久久久久久久| 久久精品中文字幕| 91人人爽人人爽人人精88v| 国产拍精品一二三| 国产精品一区二区女厕厕| 国产亚洲精品美女| 日韩欧美在线国产| 精品久久久久久国产| 久久免费视频网站| 国产一区二区三区久久精品| 精品久久久免费| 日韩性xxxx爱| 精品中文字幕乱| 日本高清视频一区| 日韩精品一二三四区| 久久免费国产精品1| 亚洲成人激情小说| 91在线无精精品一区二区| 久久久久北条麻妃免费看| 成人h猎奇视频网站| 精品国产一区二区三区久久狼5月| 欧美性猛交99久久久久99按摩| 91豆花精品一区| 亚洲日韩欧美视频| 热门国产精品亚洲第一区在线| 国产精品久久久久91| 午夜精品久久久久久久99黑人| 精品国产网站地址| 成人97在线观看视频| 国产精品户外野外| 亚洲www视频| 国产精品美乳一区二区免费| 欧美激情xxxx| 色老头一区二区三区| 欧美激情免费看| 亚洲天堂网在线观看| 欧美视频在线看| 成人精品久久一区二区三区| 国产精品免费小视频| 日韩欧美中文第一页| 亚洲一区二区三区四区视频| 国语自产精品视频在线看一大j8| 欧美午夜精品久久久久久浪潮| 日韩免费av片在线观看| 国产精品亚洲网站| 波霸ol色综合久久| 精品美女久久久久久免费| 亚洲色在线视频| 欧美日韩不卡合集视频| 亚洲www在线| 久久国产精品电影| 精品视频偷偷看在线观看| 久久久av电影| 亚洲乱码一区二区| 日本韩国欧美精品大片卡二| 欧美国产日韩精品| 久久精品视频一| 在线免费观看羞羞视频一区二区| 亚洲欧美日韩国产中文| 亚洲视频一区二区| 91国产精品91| 欧美亚洲国产视频小说| 亚洲三级 欧美三级| 中文字幕精品网| 亚洲尤物视频网| 国产精品羞羞答答| 日韩美女免费线视频| 欧美日韩免费网站| 中文字幕欧美专区| 91久久嫩草影院一区二区| 国产精品色悠悠| 欧美大胆在线视频| 欧美电影免费看| 国产精品ⅴa在线观看h| 操91在线视频| 国产视频一区在线| 久久久精品视频在线观看| 久久免费少妇高潮久久精品99| 国产热re99久久6国产精品| 91在线无精精品一区二区| 久久99国产综合精品女同| 久久免费视频在线| 欧美电影在线播放| 亚洲福利视频在线| 国产在线久久久| 国产+人+亚洲| 国产成人精品网站| 久久69精品久久久久久久电影好| 欧美在线视频免费观看| 久久精品一偷一偷国产| 精品无人区太爽高潮在线播放| 精品无人区太爽高潮在线播放| 欧美大尺度电影在线观看| xxxxx成人.com| 国产精品白嫩初高中害羞小美女| 欧美最顶级丰满的aⅴ艳星| 亚洲美女av网站| 在线日韩中文字幕| 亚洲白拍色综合图区| 亚洲xxx自由成熟| 欧洲永久精品大片ww免费漫画| 亚洲国产私拍精品国模在线观看| 国产精品高清免费在线观看| 97av视频在线| 成人美女免费网站视频| 色婷婷**av毛片一区| 激情av一区二区| 亚洲新中文字幕| 日本老师69xxx| 国产精品aaaa| 久久国内精品一国内精品| 综合久久五月天| 亚洲午夜未满十八勿入免费观看全集| 久久伊人精品一区二区三区| 日韩在线视频观看正片免费网站| 欧美专区在线视频| 成人在线国产精品| 激情久久av一区av二区av三区| 欧美精品激情在线观看| 亚洲伊人久久综合| 国产精品青草久久久久福利99| 日韩av免费在线| 久久综合五月天| 57pao精品| 国产精品网红直播| 91精品中国老女人| 亚洲视频欧美视频| 色先锋资源久久综合5566| 欧美午夜xxx| 日韩精品视频在线观看网址| 日韩国产在线播放| 久久久久久高潮国产精品视| 欧美成人午夜视频| 国产91在线高潮白浆在线观看| 日韩视频在线观看免费| 亚洲欧洲在线免费| 色综合色综合久久综合频道88| 57pao成人永久免费视频| 欧美午夜丰满在线18影院| 国产成人免费av电影| 精品视频久久久久久久| 欧美精品福利视频| 国产成人中文字幕|