0

I cannot seem to programmatically create a colored bitmap to display in a PictureBox. The bitmap saves normally as a file, but is faded at the edges when displayed in a PictureBox. Here is simplified code used to create and display the Bitmap (in actual code, the bitmap generation is completely separate from the form, so forcing the bitmap size to match the picturebox size isn't possible):

    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);
    }

Then set the Image value on a PictureBox to the generated Bitmap:

    pictureBox1.Image = Bmp;

Here is the resulting bitmap displayed in a 300x300 picturebox:

Generated bitmap in a 300x300 PictureBox

How do I set the Image on the PictureBox so that it displays the colored bitmap properly (full solid)?

EDIT: I am restricted to generating smaller source bitmaps, so upscaling into a PictureBox is unavoidable. The problem appears when the generated source bitmap is 4px or 100px square, so I believe these are relevant cases.

EDIT: The PictureBox scaling should be set to stretch or zoom for the issue to manifest. In this example case the 4x4 source bitmap is stretched to 300x300.

EDIT: The basic problem is PictureBox's inability to upscale small bitmaps into large controls. This is confusing because the Bitmap upscales nicely into a PictureBox.Background image. Unless you have a magic bullet that will fix the image upscaling problem, I think it might be best to go for clear and simple workarounds in your answer.

3
  • I have edited your title. Please see, "Should questions include “tags” in their titles?", where the consensus is "no, they should not". Commented Feb 19, 2014 at 2:08
  • 1
    A one color bitmap should not have a problem stretching. What you should do is open the original 4x4 bitmap in photoshop or any other program to see if indeed every pixel has the same color. It seems that it doesn't Commented Feb 19, 2014 at 4:39
  • @valter I confirmed that the saved bitmap is a solid square. Also, get the same result when the generated bitmap is saved to disk, then loaded from disk and put into the PictureBox to display. Commented Feb 19, 2014 at 14:43

3 Answers 3

2

You are generating a 4x4 bitmap and it's being stretched. Specify the size to match the picture box instead:

        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;
Sign up to request clarification or add additional context in comments.

1 Comment

Unfortunately, in my case the actual code that generates the bitmap has no knowledge of the form size. Bitmaps will be small since they will be transferred over a network, and the form can be stretched in all manner of ways, so upscaling the bitmap is unavoidable. Thank you for your answer, I will clarify the question.
0

You will need to turn anti-aliasing off. Also, since you are using one color for the whole picturebox, why not make the bitmap 1x1? If you need it 4x4, change the int the top of the example from 1 to 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;

UPDATE

Since you are still having the same issue by setting the picturebox to the image, you will have to get the graphics object from the picturebox and draw directly on it.

The code is very similar.

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();

3 Comments

No joy, sorry to say. The bitmap is displayed with the fuzzy edge. Also, I get the same result when I try gfx.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
This approach circumvents the upscaling problem by assuming the picturebox has a 'seed' bitmap and is updated by a known color value. The mechanism works well! Unfortunately the Bitmap won't always be a uniform color, and implementing this mechanism in the case of a general bitmap would be tantamount to recreating the PictureBox component, so I won't pursue it further.
The last thing I can think to do is resize the bitmap before applying it to the picturebox. Do you want an example of how to do that?
0

I tried to test your code and the image were properly displayed.
But when i used this code:

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();

I did get exactly your result. In order to fix it:

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();

Edit:

So you have the bitmap and you want to stretch it. And the bitmap has ane solid color. Do this insted:

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

valter

5 Comments

Not sure why it works for you and not me ... is this c# code? The graphics object hijacking worked for me. Unfortunately I can't accept the answer since this doesn't set the Image on the PictureBox itself (so changes don't persist when form is resized and PictureBox scaling parameter isn't applied correctly). Your src to dst scaling trick helped narrow the problem for me though. I tried rotating the bitmap 180 deg before setting it as the image on the picturebox and the image showed up in the same orientation, therefore picturebox upscaling seems to be causing the problem.
@Waterbear I know that my method dont produce permanent graphics but i couldn't reproduce your problem. Funny thing is, when i am using pictureBox1.Image = Bmp; the bitmap is not stretched no matter what, but if i change it to pictureBox1.BackgroundImage= Bmp; everything works fine.
the problem shows up when the picturebox scaling is set to zoom or stretch. I went ahead and clarified the question. I appreciate the suggestion on Background image. I found the bitmap actually scaled properly when set as background image (zoom-scaled). This answer might be a good workaround in a lot of cases.
I ended up using the background image workaround (scaling works properly if the generated bitmap is set to the background image). I'd like to give your answer credit if you want to set that as your answer (background image, not BackColor).
@Waterbear No need. It is enough to know that you finaly found a solution. Thanks anyway.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.