将椭圆绘制到位图。适用于 .NET,不适用于 Mono
Drawing Ellipses to a Bitmap. Works in .NET, does not work in Mono
我在 .NET 4.0 C# WinForms 应用程序 运行ning on mono 4.6.2 on Raspbian 9 (stretch) 中将椭圆绘制到位图时遇到了一些问题。
所讨论的方法在黑屏上生成一个由 5 个指定直径的白色圆圈组成的位图。屏幕每个角一个圆圈,中间一个圆圈。位图旨在包含整个屏幕,因此我通过 Screen.Bounds() 将位图的大小设置为矩形,这反过来又给出了 Res.Width 和 Res.Height。
此代码在 .NET 中的 Windows 中按预期工作(这是它最初编写和测试的目的)但是 运行通过单声道在 Raspbian 上运行 exe,简单地用白色填充位图。我还发现 运行 在 Windows (v5.10.0.160) 的单声道中,生成的圆圈最终小于在 .NET 中 运行 时生成的圆圈。
private Bitmap GenerateCirclesBitmap(int diam)
{
Bitmap bmp = GenerateColorBitmap(Color.Black);
Graphics g = Graphics.FromImage(bmp);
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
Brush whiteBrush = new SolidBrush(Color.White);
g.FillEllipse(whiteBrush, diam/7, diam/7, diam, diam); //Top Left Corner
g.FillEllipse(whiteBrush, diam/7, (Res.Height - diam)-(diam/7), diam, diam); //Bottom Left Corner
g.FillEllipse(whiteBrush, (Res.Width - diam) - (diam / 7), (Res.Height - diam) - (diam / 7), diam, diam); //Bottom Right Corner
g.FillEllipse(whiteBrush, (Res.Width - diam) - (diam / 7), diam/7, diam, diam); //Top Right Corner
g.FillEllipse(whiteBrush, (Res.Width / 2) - (diam / 2), (Res.Height / 2) - (diam / 2), diam, diam); //Center
g.DrawImage(bmp, Res.Width, Res.Height);
return bmp;
}
我在想可能是屏幕尺寸的问题,Res.Width and/or Res.Height,但如果是这样的话,我希望我的方法能够生成颜色酒吧也会有问题。然而,这段代码在两个版本的单声道以及 .NET 中都按预期工作(8 个颜色条,每个颜色条占总屏幕宽度的 1/8),这让我认为 Res.Width 是可以的:
private Bitmap GenerateBarsBitmap(Color bar1, Color bar2, Color bar3, Color bar4, Color bar5, Color bar6)
{
Bitmap bmp = GenerateColorBitmap(Color.Black);
int barwidth = Res.Width / 8;
Color[] colors = new Color[8];
Brush b = new SolidBrush(Color.White);
Graphics g = Graphics.FromImage(bmp);
colors[0] = Color.White;
colors[1] = bar1;
colors[2] = bar2;
colors[3] = bar3;
colors[4] = bar4;
colors[5] = bar5;
colors[6] = bar6;
colors[7] = Color.Black;
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
for (int colornum = 0; colornum < colors.Length; colornum++)
{
b = new SolidBrush(colors[colornum]);
g.FillRectangle(b, barwidth * colornum, 0, barwidth, Res.Height);
b.Dispose();
}
return bmp;
}
如有任何想法或见解,我们将不胜感激。谢谢!
你的两个例程之间的一个区别是行
g.DrawImage(bmp, Res.Width, Res.Height);
在您画完圆后。因此,在一个完全兼容的世界中,Mono 框架应该像 .NET 一样做,即用所有新内容绘制位图 覆盖自身 .
但完全兼容并不仅仅是困难。考虑到 GDI、.NET 等悠久历史中的所有古怪之处,它实际上是不可能的..
Mono 似乎使用没有新绘制的圆圈的位图的原始版本,并且通过在自身上绘制它删除它们。
所以删除不必要的行,一切都应该很好..
我在 .NET 4.0 C# WinForms 应用程序 运行ning on mono 4.6.2 on Raspbian 9 (stretch) 中将椭圆绘制到位图时遇到了一些问题。 所讨论的方法在黑屏上生成一个由 5 个指定直径的白色圆圈组成的位图。屏幕每个角一个圆圈,中间一个圆圈。位图旨在包含整个屏幕,因此我通过 Screen.Bounds() 将位图的大小设置为矩形,这反过来又给出了 Res.Width 和 Res.Height。
此代码在 .NET 中的 Windows 中按预期工作(这是它最初编写和测试的目的)但是 运行通过单声道在 Raspbian 上运行 exe,简单地用白色填充位图。我还发现 运行 在 Windows (v5.10.0.160) 的单声道中,生成的圆圈最终小于在 .NET 中 运行 时生成的圆圈。
private Bitmap GenerateCirclesBitmap(int diam)
{
Bitmap bmp = GenerateColorBitmap(Color.Black);
Graphics g = Graphics.FromImage(bmp);
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
Brush whiteBrush = new SolidBrush(Color.White);
g.FillEllipse(whiteBrush, diam/7, diam/7, diam, diam); //Top Left Corner
g.FillEllipse(whiteBrush, diam/7, (Res.Height - diam)-(diam/7), diam, diam); //Bottom Left Corner
g.FillEllipse(whiteBrush, (Res.Width - diam) - (diam / 7), (Res.Height - diam) - (diam / 7), diam, diam); //Bottom Right Corner
g.FillEllipse(whiteBrush, (Res.Width - diam) - (diam / 7), diam/7, diam, diam); //Top Right Corner
g.FillEllipse(whiteBrush, (Res.Width / 2) - (diam / 2), (Res.Height / 2) - (diam / 2), diam, diam); //Center
g.DrawImage(bmp, Res.Width, Res.Height);
return bmp;
}
我在想可能是屏幕尺寸的问题,Res.Width and/or Res.Height,但如果是这样的话,我希望我的方法能够生成颜色酒吧也会有问题。然而,这段代码在两个版本的单声道以及 .NET 中都按预期工作(8 个颜色条,每个颜色条占总屏幕宽度的 1/8),这让我认为 Res.Width 是可以的:
private Bitmap GenerateBarsBitmap(Color bar1, Color bar2, Color bar3, Color bar4, Color bar5, Color bar6)
{
Bitmap bmp = GenerateColorBitmap(Color.Black);
int barwidth = Res.Width / 8;
Color[] colors = new Color[8];
Brush b = new SolidBrush(Color.White);
Graphics g = Graphics.FromImage(bmp);
colors[0] = Color.White;
colors[1] = bar1;
colors[2] = bar2;
colors[3] = bar3;
colors[4] = bar4;
colors[5] = bar5;
colors[6] = bar6;
colors[7] = Color.Black;
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
for (int colornum = 0; colornum < colors.Length; colornum++)
{
b = new SolidBrush(colors[colornum]);
g.FillRectangle(b, barwidth * colornum, 0, barwidth, Res.Height);
b.Dispose();
}
return bmp;
}
如有任何想法或见解,我们将不胜感激。谢谢!
你的两个例程之间的一个区别是行
g.DrawImage(bmp, Res.Width, Res.Height);
在您画完圆后。因此,在一个完全兼容的世界中,Mono 框架应该像 .NET 一样做,即用所有新内容绘制位图 覆盖自身 .
但完全兼容并不仅仅是困难。考虑到 GDI、.NET 等悠久历史中的所有古怪之处,它实际上是不可能的..
Mono 似乎使用没有新绘制的圆圈的位图的原始版本,并且通过在自身上绘制它删除它们。
所以删除不必要的行,一切都应该很好..