在将向量地图API移植到Windows Mobile平台时,发现Windows Mobile Compact Framework缺少2D绘图库,这给绘制道路(折线)和区域(多边形)带来了困难。线帽和线连接不支持。因此,决定也移植Graphics2D库。
Guidebee Graphics 2D Library是一个免费的高效2D绘图库,为Windows Mobile填补了这一空白。它的接口与.NET Framework桌面版本相似。
Graphics2D API使用Graphics2D类作为其绘图画布,实际上它在一个整型数组中渲染图片。这种设计使其具有一定的平台独立性。
在Graphics2D画布上绘制完图片后,需要将其渲染到实际屏幕上。Windows Mobile没有提供直接绘制RGB整型数组的API。
以下是在屏幕上绘制整型RGB数组的方法。每个RGB整型是一个32位整数,代表Alpha、红色、绿色和蓝色分量。
private readonly Graphics2D graphics2D;
private readonly int screenWidth;
private readonly int screenHeight;
screenWidth = Width;
screenHeight = Height;
graphics2D = new Graphics2D(screenWidth, screenHeight);
在Windows Mobile上绘制图片的示例:
private void MainForm_Paint(object sender, PaintEventArgs e)
{
DrawRGB(e.Graphics, graphics2D.Argb, 0, 0, screenWidth, screenHeight);
}
private static void DrawRGB(Graphics graphics, int[] rgbData, int x, int y, int w, int h)
{
Bitmap bmp = new Bitmap(w, h);
System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
IntPtr ptr = bmpData.Scan0;
System.Runtime.InteropServices.Marshal.Copy(rgbData, 0, ptr, rgbData.Length);
bmp.UnlockBits(bmpData);
graphics.DrawImage(bmp, x, y);
}
以下是如何使用颜色绘制的示例:
Color redColor = new Color(0xffff0000, false);
Color greenColor = new Color(0x7800ff00, true);
Color blueColor = new Color(0x780000ff, true);
Color yellowColor = new Color(0x78ffff00, true);
int[] dashArray = { 20, 8 };
graphics2D.Reset();
graphics2D.Clear(Color.Black);
SolidBrush brush = new SolidBrush(redColor);
graphics2D.FillOval(brush, 30, 60, 80, 80);
brush = new SolidBrush(greenColor);
graphics2D.FillOval(brush, 60, 30, 80, 80);
Pen pen = new Pen(yellowColor, 10, Pen.CapButt, Pen.JoinMiter, dashArray, 0);
brush = new SolidBrush(blueColor);
graphics2D.SetPenAndBrush(pen, brush);
graphics2D.FillOval(null, 90, 60, 80, 80);
graphics2D.DrawOval(null, 90, 60, 80, 80);
Invalidate();
线帽示例展示了如何使用不同的线帽样式绘制线条:
Color blackColor = new Color(0x000000);
Color whiteColor = new Color(0xffffff);
graphics2D.Reset();
graphics2D.Clear(Color.White);
Pen pen = new Pen(blackColor, 20, Pen.CapButt, Pen.JoinMiter);
graphics2D.DrawLine(pen, 40, 60, 140, 60);
pen = new Pen(whiteColor, 1);
graphics2D.DrawLine(pen, 40, 60, 140, 60);
pen = new Pen(blackColor, 20, Pen.CapRound, Pen.JoinMiter);
graphics2D.DrawLine(pen, 40, 100, 140, 100);
pen = new Pen(whiteColor, 1);
graphics2D.DrawLine(pen, 40, 100, 140, 100);
pen = new Pen(blackColor, 20, Pen.CapSquare, Pen.JoinMiter);
graphics2D.DrawLine(pen, 40, 140, 140, 140);
pen = new Pen(whiteColor, 1);
graphics2D.DrawLine(pen, 40, 140, 140, 140);
Invalidate();
Ellipse circle, oval, leaf, stem;
Area circ, ov, leaf1, leaf2, st1, st2;
circle = new Ellipse();
oval = new Ellipse();
leaf = new Ellipse();
stem = new Ellipse();
circ = new Area(circle);
ov = new Area(oval);
leaf1 = new Area(leaf);
leaf2 = new Area(leaf);
st1 = new Area(stem);
st2 = new Area(stem);
graphics2D.Reset();
graphics2D.Clear(Color.White);
int w = screenWidth;
int h = screenHeight;
int ew = w / 2;
int eh = h / 2;
SolidBrush brush = new SolidBrush(Color.Green);
graphics2D.DefaultBrush = brush;
leaf.SetFrame(ew - 16, eh - 29, 15, 15);
leaf1 = new Area(leaf);
leaf.SetFrame(ew - 14, eh - 47, 30, 30);
leaf2 = new Area(leaf);
leaf1.Intersect(leaf2);
graphics2D.Fill(null, leaf1);
brush = new SolidBrush(Color.Black);
graphics2D.DefaultBrush = brush;
stem.SetFrame(ew, eh - 42, 40, 40);
st1 = new Area(stem);
stem.SetFrame(ew + 3, eh - 47, 50, 50);
st2 = new Area(stem);
st1.Subtract(st2);
graphics2D.Fill(null, st1);
brush = new SolidBrush(Color.Yellow);
graphics2D.DefaultBrush = brush;
circle.SetFrame(ew - 25, eh, 50, 50);
oval.SetFrame(ew - 19, eh - 20, 40, 70);
circ = new Area(circle);
ov = new Area(oval);
circ.Add(ov);
graphics2D.Fill(null, circ);
Invalidate();