【问题标题】:Generated Bitmap Displays Weirdly in PictureBox生成的位图在 PictureBox 中显示异常
【发布时间】:2014-02-19 00:37:55
【问题描述】:

我似乎无法以编程方式创建要在 PictureBox 中显示的彩色位图。位图通常保存为文件,但在 PictureBox 中显示时边缘会变淡。以下是用于创建和显示位图的简化代码(在实际代码中,位图的生成与表单完全分开,因此无法强制位图大小与图片框大小匹配):

    Bitmap Bmp = new Bitmap(4, 4, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
    using (Graphics gfx = Graphics.FromImage(Bmp))
    using (SolidBrush brush = new SolidBrush(Color.BlueViolet))
    {
        gfx.FillRectangle(brush, 0, 0, 4, 4);
    }

然后将 PictureBox 上的Image 值设置为生成的位图:

    pictureBox1.Image = Bmp;

这是显示在 300x300 图片框中的结果位图:

如何在 PictureBox 上设置图像,以便正确显示彩色位图(全实线)?

编辑:我仅限于生成较小的源位图,因此升级为 PictureBox 是不可避免的。当生成的源位图为 4px 或 100px 正方形时会出现问题,所以我相信这些是相关案例。

编辑:应该将 PictureBox 缩放设置为拉伸或缩放以使问题显现。在本例中,4x4 源位图被拉伸到 300x300。

编辑: 基本问题是 PictureBox 无法将小位图放大为大控件。这是令人困惑的,因为位图很好地升级为PictureBox.Background 图像。除非您有一个可以解决图像放大问题的灵丹妙药,否则我认为最好在您的答案中采用清晰简单的解决方法。

【问题讨论】:

  • 我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。
  • 单色位图拉伸应该没有问题。你应该做的是在 Photoshop 或任何其他程序中打开原始的 4x4 位图,看看每个像素是否确实具有相同的颜色。好像没有
  • @valter 我确认保存的位图是一个实心正方形。同样,将生成的位图保存到磁盘,然后从磁盘加载并放入 PictureBox 显示时,也可以得到相同的结果。

标签: c# .net windows winforms picturebox


【解决方案1】:

您正在生成一个 4x4 位图并且它正在被拉伸。指定尺寸以匹配图片框:

        int width = pictureBox1.Width;
        int height = pictureBox1.Height;
        var Bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
        using (Graphics gfx = Graphics.FromImage(Bmp))
        using (var brush = new SolidBrush(Color.BlueViolet))
        {
            gfx.FillRectangle(brush, 0, 0, width, height);
        }
        pictureBox1.Image = Bmp;

【讨论】:

  • 不幸的是,在我的例子中,生成位图的 actual 代码不知道表单大小。位图会很小,因为它们将通过网络传输,并且表格可以以各种方式拉伸,因此放大位图是不可避免的。谢谢你的回答,我会澄清这个问题。
【解决方案2】:

您需要关闭抗锯齿功能。此外,既然您对整个图片框使用一种颜色,为什么不将位图设为 1x1?如果您需要 4x4,请将示例顶部的 int 从 1 更改为 4。

int hw = 1;
Bitmap Bmp = new Bitmap(hw, hw, 
                        System.Drawing.Imaging.PixelFormat.Format24bppRgb);
using (Graphics gfx = Graphics.FromImage(Bmp))
{
  // Turn off anti-aliasing and draw an exact copy
  gfx.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
  gfx.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;

  using (SolidBrush brush = new SolidBrush(Color.BlueViolet))
  {
    gfx.FillRectangle(brush, 0, 0, hw, hw);
  }
}
pictureBox1.Image = Bmp;

更新

由于将图片框设置为图像仍然存在相同的问题,因此您必须从图片框中获取图形对象并直接在其上绘制。

代码非常相似。

using (Graphics gfx = Graphics.FromImage(pictureBox1.Image))
{
  // Turn off anti-aliasing and draw an exact copy
  gfx.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
  gfx.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;

  using (SolidBrush brush = new SolidBrush(Color.BlueViolet))
  {
    gfx.FillRectangle(brush, 0, 0, 
                      pictureBox11.Width - 1, 
                      pictureBox11.Height - 1);
  }
}

// Force the picturebox to redraw with the new image.
// You could also use pictureBox11.Refresh() to do the redraw.
pictureBox11.Invalidate();

【讨论】:

  • 不高兴,抱歉。位图以模糊边缘显示。此外,当我尝试 gfx.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half; 时,我得到了相同的结果
  • 这种方法通过假设图片框具有“种子”位图并通过已知颜色值更新来规避放大问题。机制很好用!不幸的是,Bitmap 并不总是统一的颜色,在通用位图的情况下实现这个机制就等于重新创建 PictureBox 组件,所以我不再继续。
  • 我能想到的最后一件事是在将位图应用到图片框之前调整其大小。你想要一个如何做到这一点的例子吗?
【解决方案3】:

我尝试测试您的代码并且图像已正确显示。
但是当我使用这段代码时:

Rectangle srcRect = New Rectangle(0, 0, Bmp.Width, Bmp.Height);
Rectangle dstRect = New Rectangle(0, 0, PictureBox1.Width, PictureBox1.Height);
g = PictureBox1.CreateGraphics;
g.DrawImage(Bmp, dstRect, srcRect, GraphicsUnit.Pixel);
g.Dispose();

我确实得到了你的结果。为了解决它:

Rectangle srcRect = New Rectangle(0, 0, Bmp.Width - 1, Bmp.Height - 1);
Rectangle dstRect = New Rectangle(0, 0, PictureBox1.Width, PictureBox1.Height);
g = PictureBox1.CreateGraphics;
g.DrawImage(Bmp, dstRect, srcRect, GraphicsUnit.Pixel);
g.Dispose();

编辑:

所以你有位图,你想拉伸它。并且位图具有纯色。执行此操作:

Color pixelColor = Bmp.GetPixel(0, 0);
PictureBox1.BackColor = pixelColor;

变态

【讨论】:

  • 不知道为什么它适用于你而不是我......这是c#代码吗?图形对象劫持对我有用。不幸的是,我不能接受答案,因为这不会在 PictureBox 本身上设置图像(因此在调整表单大小并且未正确应用 PictureBox 缩放参数时,更改不会持续存在)。不过,您的 src 到 dst 缩放技巧帮助缩小了我的问题。我尝试将位图旋转 180 度,然后将其设置为图片框上的图像,并且图像以相同的方向显示,因此图片框放大似乎导致了问题。
  • @Waterbear 我知道我的方法不会产生永久图形,但我无法重现您的问题。有趣的是,当我使用pictureBox1.Image = Bmp; 时,位图无论如何都不会被拉伸,但如果我将其更改为pictureBox1.BackgroundImage= Bmp;,一切正常。
  • 当图片框缩放设置为缩放或拉伸时会出现问题。我继续澄清了这个问题。我很欣赏关于背景图片的建议。我发现当设置为背景图像(缩放比例)时,位图实际上正确缩放。在很多情况下,这个答案可能是一个很好的解决方法。
  • 我最终使用了背景图像解决方法(如果生成的位图设置为背景图像,则缩放工作正常)。如果您想将其设置为您的答案(背景图片,而不是背景颜色),我想给您的答案功劳。
  • @Waterbear 不需要。知道您最终找到了解决方案就足够了。还是谢谢。
猜你喜欢
  • 1970-01-01
  • 2011-01-12
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
  • 1970-01-01
  • 2020-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多