DrawImage方法詳解(轉載)

原文地址爲:DrawImage方法詳解(轉載)

Image和Bitmap類概述

GDI+的Image類封裝了對BMP、GIF、JPEG、PNG、TIFF、WMF(Windows元文件)和EMF(增強WMF)圖像文件的調入、格式轉換以及簡單處理的功能。而Bitmap是從Image類繼承的一個圖像類,它封裝了Windows位圖操作的常用功能。例如,Bitmap::SetPixel和Bitmap::GetPixel分別用來對位圖進行讀寫像素操作,從而可以爲圖像的柔化和銳化處理提供一種可能。

3.DrawImage方法

DrawImage是GDI+的Graphics類顯示圖像的核心方法,它的重載函數有許多個。常用的一般重載函數有:

Status DrawImage( Image* image, INT x, INT y);

Status DrawImage( Image* image, const Rect& rect);

Status DrawImage( Image* image, const Point* destPoints, INT count);

Status DrawImage( Image* image, INT x, INT y,
                               INT srcx, INT srcy, INT srcwidth, INT srcheight, Unit srcUnit);

其中,(x,y)用來指定圖像image顯示的位置,這個位置和image圖像的左上角點相對應。rect用來指定被圖像填充的矩形區域, destPoints和count分別用來指定一個多邊形的頂點和頂點個數。若count爲3時,則表示該多邊形是一個平行四邊形,另一個頂點由系統自動給出。此時,destPoints中的數據依次對應於源圖像的左上角、右上角和左下角的頂點座標。srcx、srcy、srcwidth 和srcheight用來指定要顯示的源圖像的位置和大小,srcUnit用來指定所使用的單位,默認時使用PageUnitPixel,即用像素作爲度量單位。
調用和顯示圖像文件

在GDI+中調用和顯示圖像文件是非常容易的,一般先通過Image或Bitmap調入一個圖像文件構造一個對象,然後調用Graphics::DrawImage方法在指定位置處顯示全部或部分圖像。例如下面的代碼:

void CEx_GDIPlusView::OnDraw(CDC* pDC)

{

CEx_GDIPlusDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

using namespace Gdiplus;

Graphics graphics( pDC->m_hDC );

Image image(L"sunflower.jpg");

graphics.DrawImage(&image, 10,10);

Rect rect(130, 10, image.GetWidth(), image.GetHeight());

graphics.DrawImage(&image, rect);

}

結果如圖7.17所示,從圖中我們可以看出,兩次DrawImage的結果是不同的,按理應該相同,這是怎麼一回事?原來,DrawImage在不指定顯示區域大小時會自動根據設備分辨率進行縮放,從而造成顯示結果的不同。

當然,也可以使用Bitmap類來調入圖像文件來構造一個Bitmap對象,其結果也是一樣的。例如,上述代碼可改爲:

Bitmap bmp(L"sunflower.jpg");

graphics.DrawImage(&bmp, 10,10);

Rect rect(130, 10, bmp.GetWidth(), bmp.GetHeight());

graphics.DrawImage(&bmp, rect);

需要說明的是,Image還提供GetThumbnailImage的方法用來獲得一個縮略圖的指針,調用DrawImage後可將該縮略圖顯示,這在圖像預覽時極其有用。例如下面的代碼:

Graphics graphics( pDC->m_hDC );

Image image(L"sunflower.jpg");

Image* pThumbnail = image.GetThumbnailImage(50, 50, NULL, NULL);

// 顯示縮略圖

graphics.DrawImage(pThumbnail, 20, 20);

// 使用後,不要忘記刪除該縮略圖指針

delete pThumbnail;
圖像旋轉和拉伸

圖像的旋轉和拉伸通常是通過在DrawImage中指定destPoints參數來實現,destPoints包含對新的座標系定義的點的數據。圖7.18說明了座標系定義的方法。

從圖中可以看出,destPoints中的第一個點是用來定義座標原點的,第二點用來定義X軸的方法和圖像X方向的大小,第三個是用來定義Y軸的方法和圖像Y方向的大小。若destPoints定義的新座標系中兩軸方向不垂直,就能達到圖像拉伸的效果。

下面的代碼就是圖像旋轉和拉伸的一個示例,其結果如圖7.19所示。

Image image(L"sunflower.jpg");

graphics.DrawImage(&image, 10,10);

Point points[] = { Point(0, 0), Point(image.GetWidth(), 0),

Point(0, image.GetHeight())};

Matrix matrix(1,0,0,1,230,10); // 定義一個單位矩陣,座標原點在(230,10)

matrix.Rotate(30); // 順時針旋轉30度

matrix.Scale(0.63,0.6); // X 和 Y 方向分別乘以0.63和0.6比例因子

matrix.TransformPoints(points, 3); // 用該矩陣轉換points

graphics.DrawImage(&image, points, 3);

Point newpoints[] = {Point(450, 10), Point(510, 60), Point(350, 80)};

graphics.DrawImage(&image, newpoints, 3);

當然,對於圖像旋轉還可直接使用Graphics::RotateTransform來進行,例如下面的代碼。但這樣設置後,以後所有的繪圖結果均會旋轉,有時可能感覺不方便。

Image image(L"sunflower.jpg");

graphics.TranslateTransform(230,10); // 將原點移動到(230,10)

graphics.RotateTransform(30); // 順時針旋轉30度

graphics.DrawImage(&image, 0,0);
調整插補算法的質量

當圖像進行縮放時,需要對圖像像素進行插補,不同的插補算法其效果是不一樣的。Graphics:: SetInterpolationMode可以讓我們根據自己的需要使用不同質量效果的插補算法。當然,質量越高,其渲染時間越長。下面的代碼就是使用不同質量效果的插補算法模式,其結果如圖7.20所示。

Graphics graphics( pDC->m_hDC );

Image image(L"log.gif");

UINT width = image.GetWidth();

UINT height = image.GetHeight();

// 不進行縮放

graphics.DrawImage( &image,10,10);

// 使用低質量的插補算法

graphics.SetInterpolationMode(InterpolationModeNearestNeighbor);

graphics.DrawImage( &image,

Rect(170, 30, (INT)(0.6*width), (INT)(0.6*height)));

// 使用中等質量的插補算法

graphics.SetInterpolationMode(InterpolationModeHighQualityBilinear);

graphics.DrawImage( &image,

Rect(270, 30, (INT)(0.6*width), (INT)(0.6*height)));

// 使用高質量的插補算法

graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);

graphics.DrawImage( &image,

Rect(370, 30, (INT)(0.6*width), (INT)(0.6*height)));

事實上,Image功能還不止這些,例如還有不同格式文件之間的轉換等。但這些功能和MFC的新類CImage功能基本一樣,但CImage更符合MFC程序員的編程習慣,因此下一節中我們來重點介紹CImage的使用方法和技巧。

轉載請註明本文地址:DrawImage方法詳解(轉載)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章