.NET Compact Framework圖形開(kāi)發(fā)常見(jiàn)問(wèn)題

2010-08-28 10:49:44來(lái)源:西部e網(wǎng)作者:

1. 如何創(chuàng)建 Graphics 對(duì)象?

圖形對(duì)象根據(jù)其用途有幾種創(chuàng)建方式:

通過(guò) OnPaint,使用 PaintEventArgs 中提供的對(duì)象:

//C#

protected override void OnPaint(PaintEventArgs e)
{
  e.Graphics.DrawLine(...);
}

'VB

Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
    e.Graphics.DrawLine(...)
End Sub 'OnPaint

通過(guò)代碼中的其他區(qū)域,該函數(shù)是 Control 的一個(gè)方法,可以用來(lái)創(chuàng)建任何控件的圖形對(duì)象:

//C#

using System.Drawing;

Graphics g = this.CreateGraphics();

'VB

Imports System.Drawing

Dim g As Graphics = Me.CreateGraphics()

直接在一個(gè)位圖中繪制:

//C#

using System.Drawing;

Bitmap bm = new Bitmap(10,10);
Graphics g = Graphics.FromImage(bm);

'VB

Imports System.Drawing

Dim bm As New Bitmap(10, 10)
Dim g As Graphics = Graphics.FromImage(bm)

2. 可以怎樣優(yōu)化 GDI+ 呈現(xiàn)?

當(dāng)使用 Graphics 繪畫調(diào)用時(shí),有幾種基本的編碼實(shí)踐可以幫助提高繪畫速度:

只創(chuàng)建一個(gè) Graphics 對(duì)象(或者使用來(lái)自 OnPaint 中的 PaintEventArgs 的 Graphics 對(duì)象)。

在屏幕外的位圖中完成所有繪畫,然后拖曳該位圖,使它一次全部顯示出來(lái)。

只重畫圖像的更改部分。

盡可能使繪制的源和目的大小相同(不要拉伸等等)。

也許最重要的實(shí)踐是保留需要重畫的項(xiàng)目的痕跡以便使出現(xiàn)的繪畫量盡可能少。例如,如果拖曳光標(biāo)跨過(guò)圖像,就不需要重畫整個(gè)圖像。相反,只需重畫前一個(gè)光標(biāo)位置覆蓋的圖像部分。

3. 如何在窗體中繪制圖像?

此示例顯示了如何將一個(gè)圖形作為窗體的背景圖像顯示:
http://samples.gotdotnet.com/quickstart/CompactFramework/doc/bkgndimage.aspx

4. 如何繪制具有透明度的圖像?

繪制有透明度的圖像需要一個(gè)指定透明顏色的 ImageAttributes 對(duì)象。當(dāng)前,.NET Compact Framework 支持單種顏色的原色調(diào)透明度。雖然 SetColorKey 函數(shù)允許一個(gè)顏色范圍,但最小和最大的顏色必須相同,否則會(huì)產(chǎn)生運(yùn)行時(shí) ArgumentException:

//C#

using System.Drawing.Imaging;

ImageAttributes attr = new ImageAttributes();

'VB

Imports System.Drawing.Imaging

Dim attr As New ImageAttributes()

以下代碼演示了如何根據(jù)圖像的左上像素設(shè)置透明色調(diào)。

//C#

attr.SetColorKey(bmp.GetPixel(0,0), bmp.GetPixel(0,0));

'VB

attr.SetColorKey(bmp.GetPixel(0,0), bmp.GetPixel(0,0))

也可以按照如下所述方法顯式設(shè)置顏色:

//C#

attr.SetColorKey(Color.FromArgb(255,0,255),Color.FromArgb(255,0,255));
attr.SetColorKey(Color.Fuchsia, Color.Fuchsia);

'VB

attr.SetColorKey(Color.FromArgb(255,0,255),Color.FromArgb(255,0,255))
attr.SetColorKey(Color.Fuchsia, Color.Fuchsia)

然后可以用重載的 Graphics.DrawImage 函數(shù)(它將 ImageAttributes 對(duì)象作為一個(gè)參數(shù))來(lái)繪制圖像:

//C#

Rectangle dstRect = new Rectangle(0, 0, bmp.Width, bmp.Height);
g.DrawImage(bmp, dstRect, 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, attr);

'VB

Dim dstRect As New Rectangle(0, 0, bmp.Width, bmp.Height)
g.DrawImage(bmp, dstRect, 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, attr)

5. 當(dāng)我在 TextBox 中調(diào)用 CreateGraphics 時(shí)它為什么會(huì)失。

只有 Control 和 Form 類支持 Control.CreateGraphics()。

6. 如何確定文本的屏幕大。

使用 Graphics 方法 MeasureString。以下代碼演示了如何在一些文本周圍繪制一個(gè)框:

//C#

using System.Drawing;

protected override void OnPaint(PaintEventArgs e)
{
  string s = "Hello World"

  Pen pen = new Pen(Color.Fuchsia);
  Font font = new Font("Arial", 18, FontStyle.Regular);
  Brush brush = new SolidBrush(Color.Black);

  SizeF sSize = e.Graphics.MeasureString(s, font);

  Rectangle r = new Rectangle(9, 199,(int)sSize.Width + 1, (int)sSize.Height + 1);

  e.Graphics.DrawRectangle(pen, r);
  e.Graphics.DrawString(s, font, brush, 10.0f, 200.0f);

  base.OnPaint (e);
}

'VB

Imports System.Drawing

Protected Overrides Sub OnPaint(e As PaintEventArgs)
  Dim s As String = "Hello World"
  
  Dim pen As New Pen(Color.Fuchsia)
  Dim font As New Font("Arial", 18, FontStyle.Regular)
  Dim brush = New SolidBrush(Color.Black)

  Dim sSize As SizeF = e.Graphics.MeasureString(s, font)

  Dim r As New Rectangle(9, 199, Fix(sSize.Width) + 1, Fix(sSize.Height) + 1)

  e.Graphics.DrawRectangle(pen, r)
  e.Graphics.DrawString(s, font, brush, 10F, 200F)

  MyBase.OnPaint(e)

End Sub 'OnPaint

7. 可以設(shè)置畫筆的寬度嗎?

.NET Compact Framework 中不可以設(shè)置畫筆寬度。有一些替代辦法,包括:

采用 Graphics.FillRectangle 方法繪制實(shí)心矩形

繪制多條并行線

采用 GAPI 編寫自定義圖形例程

8. 如何縮放圖像?

雖然沒(méi)有對(duì)縮放和拉伸單個(gè)圖像的內(nèi)在支持,但這些效果也可以很輕松地實(shí)現(xiàn),方法是使用相關(guān)的 Graphics 對(duì)象創(chuàng)建新的 Bitmap 對(duì)象,然后將原有 Bitmap 想要的部分復(fù)制到新建對(duì)象上。以下示例創(chuàng)建了兩個(gè)大小相同的位圖,其中第二個(gè)位圖包含第一個(gè)位圖經(jīng)放大的中心部分,并假定項(xiàng)目有一個(gè)名為 MyImage.bmp 的嵌入式資源。這樣的技術(shù)也可以用來(lái)拉伸圖像,方法是修改源和目的矩形以便它們沒(méi)有保留其原有的縱橫比。

//C#

using System.Drawing;
using System.Reflection;

Bitmap m_bmpOriginal;
Bitmap m_bmpZoom;

private void Form1_Load(object sender, System.EventArgs e)
{
    Assembly asm = Assembly.GetExecutingAssembly();
    m_bmpOriginal = new Bitmap(asm.GetManifestResourceStream(asm.GetName().Name
      + ".MyImage.bmp"));

    // Take the center quarter of m_bmpOriginal
    // and create stetch it into m_bmpZoom of the same size
    m_bmpZoom = new Bitmap(m_bmpOriginal.Width, m_bmpOriginal.Height);
    Graphics gZoom = Graphics.FromImage(m_bmpZoom);
    
    Rectangle srcRect = new Rectangle(m_bmpOriginal.Width / 4, m_bmpOriginal.Height / 4,
      m_bmpOriginal.Width / 2, m_bmpOriginal.Height / 2);
    Rectangle dstRect = new Rectangle(0, 0, m_bmpZoom.Width, m_bmpZoom.Height);
    gZoom.DrawImage(m_bmpOriginal, dstRect, srcRect, GraphicsUnit.Pixel);
}

protected override void OnPaint(PaintEventArgs e)
{
    e.Graphics.DrawImage(m_bmpOriginal, 0, 0);
    e.Graphics.DrawImage(m_bmpZoom, 125, 0);
    base.OnPaint (e);
}

'VB

Imports System.Drawing
Imports System.Reflection

Private m_bmpOriginal As Bitmap
Private m_bmpZoom As Bitmap

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim asm As [Assembly] = [Assembly].GetExecutingAssembly()
    m_bmpOriginal = New Bitmap(asm.GetManifestResourceStream((asm.GetName().Name _
      + ".MyImage.bmp")))

    ' Take the center quarter of m_bmpOriginal
    ' and create stetch it into m_bmpZoom of the same size
    m_bmpZoom = New Bitmap(m_bmpOriginal.Width, m_bmpOriginal.Height)
    Dim gZoom As Graphics = Graphics.FromImage(m_bmpZoom)

    Dim srcRect As New Rectangle(m_bmpOriginal.Width / 4, m_bmpOriginal.Height / 4, _
      m_bmpOriginal.Width / 2, m_bmpOriginal.Height / 2)
    Dim dstRect As New Rectangle(0, 0, m_bmpZoom.Width, m_bmpZoom.Height)
    gZoom.DrawImage(m_bmpOriginal, dstRect, srcRect, GraphicsUnit.Pixel)
End Sub 'Form1_Load

Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
    e.Graphics.DrawImage(m_bmpOriginal, 0, 0)
    e.Graphics.DrawImage(m_bmpZoom, 125, 0)
    MyBase.OnPaint(e)
End Sub 'OnPaint

9. 為什么我不能加載圖像?

確保 imgdecmp.dll 位于設(shè)備的 Windows 目錄。

有關(guān)更多信息,請(qǐng)參見(jiàn)本 FAQ 中的主題“ HYPERLINK \l "1.31" 1.31.如何將 imgdemp.dll 包括在模擬器映像中?”。

10. 如何使用 GAPI 創(chuàng)建圖形引擎?

這篇文章描述了如何創(chuàng)建包裝 GAPI (Game API) 的 DLL,使之與 .NET Compact Framework 兼容,并用它來(lái)創(chuàng)建和優(yōu)化托管代碼中的基本圖形庫(kù)。
http://msdn.microsoft.com/library/en-us/dnnetcomp/html/WrapGAPI1.asp

這篇文章實(shí)現(xiàn)了位圖的加載和顯示,從而擴(kuò)展了“Dancing Rectangles”示例。它還實(shí)現(xiàn)了一些更高級(jí)的功能,例如動(dòng)畫位圖、源和目的色調(diào)透明和 alpha 值混合處理(也就是半透明)。
http://msdn.microsoft.com/library/en-us/dnnetcomp/html/WrapGAPI2.asp

這篇文章實(shí)現(xiàn)了點(diǎn)、線和從 8 位位圖轉(zhuǎn)換而來(lái)的自定義 1 位字體的繪制,從而擴(kuò)展了“Dancing Zombies”示例。它還實(shí)現(xiàn)了一個(gè)重寫硬件按鈕功能和跟蹤按鈕狀態(tài)的輸入系統(tǒng)。
http://msdn.microsoft.com/library/en-us/dnnetcomp/html/WrapGAPI3.asp

關(guān)鍵詞:dotnet

贊助商鏈接: