1. 如何创建 Graphics 对象?
图形对象根据其用途有几种创建方式:
通过 OnPaint,使用 PaintEventArgs 中提供的对象:
//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
通过代码中的其他区域,该函数是 Control 的一个方法,可以用来创建任何控件的图形对象:
//C#
using System.Drawing; Graphics g = this.CreateGraphics();
'VB
Imports System.Drawing Dim g As Graphics = Me.CreateGraphics()
直接在一个位图中绘制:
//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. 可以怎样优化 GDI+ 呈现?
当使用 Graphics 绘画调用时,有几种基本的编码实践可以帮助提高绘画速度:
| • |
只创建一个 Graphics 对象(或者使用来自 OnPaint 中的 PaintEventArgs 的 Graphics 对象)。 |
| • |
在屏幕外的位图中完成所有绘画,然后拖曳该位图,使它一次全部显示出来。 |
| • |
只重画图像的更改部分。 |
| • |
尽可能使绘制的源和目的大小相同(不要拉伸等等)。 |
也许最重要的实践是保留需要重画的项目的痕迹以便使出现的绘画量尽可能少。例如,如果拖曳光标跨过图像,就不需要重画整个图像。相反,只需重画前一个光标位置覆盖的图像部分。
3. 如何在窗体中绘制图像?
此示例显示了如何将一个图形作为窗体的背景图像显示:
http://samples.gotdotnet.com/quickstart/CompactFramework/doc/bkgndimage.aspx
4. 如何绘制具有透明度的图像?
绘制有透明度的图像需要一个指定透明颜色的 ImageAttributes 对象。当前,.NET Compact Framework 支持单种颜色的原色调透明度。虽然 SetColorKey 函数允许一个颜色范围,但最小和最大的颜色必须相同,否则会产生运行时 ArgumentException:
//C#
using System.Drawing.Imaging; ImageAttributes attr = new ImageAttributes();
'VB
Imports System.Drawing.Imaging Dim attr As New ImageAttributes()
以下代码演示了如何根据图像的左上像素设置透明色调。
//C#
attr.SetColorKey(bmp.GetPixel(0,0), bmp.GetPixel(0,0));
'VB
attr.SetColorKey(bmp.GetPixel(0,0), bmp.GetPixel(0,0))
也可以按照如下所述方法显式设置颜色:
//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 函数(它将 ImageAttributes 对象作为一个参数)来绘制图像:
//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. 当我在 TextBox 中调用 CreateGraphics 时它为什么会失败?
只有 Control 和 Form 类支持 Control.CreateGraphics()。
6. 如何确定文本的屏幕大小?
使用 Graphics 方法 MeasureString。以下代码演示了如何在一些文本周围绘制一个框:
//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. 可以设置画笔的宽度吗?
.NET Compact Framework 中不可以设置画笔宽度。有一些替代办法,包括:
| • |
采用 Graphics.FillRectangle 方法绘制实心矩形 |
| • |
绘制多条并行线 |
| • |
采用 GAPI 编写自定义图形例程 |
8. 如何缩放图像?
虽然没有对缩放和拉伸单个图像的内在支持,但这些效果也可以很轻松地实现,方法是使用相关的 Graphics 对象创建新的 Bitmap 对象,然后将原有 Bitmap 想要的部分复制到新建对象上。以下示例创建了两个大小相同的位图,其中第二个位图包含第一个位图经放大的中心部分,并假定项目有一个名为 MyImage.bmp 的嵌入式资源。这样的技术也可以用来拉伸图像,方法是修改源和目的矩形以便它们没有保留其原有的纵横比。
//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 位于设备的 Windows 目录。
有关更多信息,请参见本 FAQ 中的主题“ HYPERLINK \l "1.31" 1.31.如何将 imgdemp.dll 包括在模拟器映像中?”。
10. 如何使用 GAPI 创建图形引擎?
这篇文章描述了如何创建包装 GAPI (Game API) 的 DLL,使之与 .NET Compact Framework 兼容,并用它来创建和优化托管代码中的基本图形库。
http://msdn.microsoft.com/library/en-us/dnnetcomp/html/WrapGAPI1.asp
这篇文章实现了位图的加载和显示,从而扩展了“Dancing Rectangles”示例。它还实现了一些更高级的功能,例如动画位图、源和目的色调透明和 alpha 值混合处理(也就是半透明)。
http://msdn.microsoft.com/library/en-us/dnnetcomp/html/WrapGAPI2.asp
这篇文章实现了点、线和从 8 位位图转换而来的自定义 1 位字体的绘制,从而扩展了“Dancing Zombies”示例。它还实现了一个重写硬件按钮功能和跟踪按钮状态的输入系统。
http://msdn.microsoft.com/library/en-us/dnnetcomp/html/WrapGAPI3.asp
