将椭圆绘制到位图。适用于 .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 似乎使用没有新绘制的圆圈的位图的原始版本,并且通过在自身上绘制它删除它们。

所以删除不必要的行,一切都应该很好..