Results 1 to 17 of 17

Thread: Bug with StretchImage in PictureBox?

  1. #1

    Thread Starter
    Member
    Join Date
    Mar 2002
    Posts
    40

    Bug with StretchImage in PictureBox?

    StrechImage SizeMode does not work as expected when I assign a code-generated gradient Bitmap to a PictureBox. The StrechImage function seems to add a row (or column) of gray pixels to the Bitmap before the Bitmap is stretched. To see what I'm talking about, do the following:

    1. Create a new WindowsForm Project
    2. In design mode, add a Button, a TextBox, and a PictureBox (keeping the original names for the controls)
    3. Set the SizeMode property of the PictureBox to StretchImage
    4. Copy and paste the following code to the Form1 class

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Me.TextBox1.Text = 1
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim i, j As Integer
    Dim c As Drawing.Color
    Dim c_Blue_Temp As Integer
    Dim Bmp As Drawing.Bitmap
    Const Bmp_Wid As Integer = 256 'Make sure that Bmp_Wid is not greater than 256!
    Dim Bmp_Ht As Integer = CInt(Me.TextBox1.Text)

    'Force the Width of PictureBox1 to be Bmp_Wid pixels wide so that there won't be any stretching in the x-direction
    Me.PictureBox1.Width = Bmp_Wid

    'Create a Bitmap
    Bmp = New Drawing.Bitmap(Bmp_Wid, Bmp_Ht, Drawing.Imaging.PixelFormat.Format32bppArgb)

    'Fill the Bitmap with a Gradient
    For i = 0 To Bmp_Wid - 1

    c_Blue_Temp = i
    c = c.FromArgb(255, 0, 0, c_Blue_Temp)

    For j = 0 To Bmp.Height - 1
    Bmp.SetPixel(i, j, c)
    Next j
    Next i

    'Assign the Bitmap to PictureBox1
    Me.PictureBox1.Image = Bmp
    End Sub


    5. Run the program and click the Button

    Notice that the colors in the lower half of PictureBox's image seem to be obtained by interpolating between the colors in our Bitmap and Gray. In other words, it is as if a row of gray pixels was added to our Bitmap BEFORE the image was stretched.

    Now, increment the value in the TextBox and press the Button after each increment. That phantom row of gray pixels is always present until the value in the TextBox equals or exceeds the height of the PictureBox.

    So why do I care? Well, I'm glad you asked. Stretched 1D Bitmaps update MUCH faster in a PictureBox than 2D Bitmaps that completely fill a PictureBox. Of course, creating a 1D Bitmap is also much faster than creating a 2D Bitmap. So, the above method is the best way that I've found for creating a permanent gradient image.

    A work around for this problem is to create a PictureBox inside of a Container. The, you could just make the height of the PictureBox larger than the container so that the interpolated gray region was not visible. But, lets face it, there must be a better way.

    Any ideas? Thanks.

  2. #2
    hellswraith
    Guest
    I followed your steps, and I see no grey line...maybe it is just me. I tried many different values, still no grey line.

    I am on Win XP, with the updated .Net Framework. Have you updated to the newest version of the Framework? I am also on a 14.1 inch LCD laptop display at 1024 X 768 res... if you want to know all that...lol. Good luck in finding your problem.

  3. #3

    Thread Starter
    Member
    Join Date
    Mar 2002
    Posts
    40
    Originally posted by hellswraith
    I followed your steps, and I see no grey line...maybe it is just me. I tried many different values, still no grey line.
    Thanks for the info. Just knowing that somebody else isn't noticing the problem is useful.

    I've tryied it on a PC (1024x768) and a laptop (1600x1200) with Win2k and .NET Framework SP1. So, maybe its Win2k?

    I've attached some screen captures so people can see what I'm observing.

    Thanks. Lance
    Attached Images Attached Images  

  4. #4
    hellswraith
    Guest
    Here is a screen capture from mine...I put the form bg to black so I could verify if it was the form or the image (the button is black too, but that doesn't matter does it..lol).
    Attached Images Attached Images  

  5. #5

    Thread Starter
    Member
    Join Date
    Mar 2002
    Posts
    40
    Originally posted by hellswraith
    Here is a screen capture from mine...I put the form bg to black so I could verify if it was the form or the image (the button is black too, but that doesn't matter does it..lol).
    Actually, setting the form bg to black has revealed something fairly important. The final color for interpolation is determined by the Backcolor of the PictureBox. To verify this I changed the Backcolor of my PictureBox from Gray to Red to Yellow, etc. In each case the image was interpolated to the Backcolor of the PictureBox.

    So, maybe one of you programming experts can tell me what this means. I can't imagine that this wasn't caught in the testing phases. Is there some advantage to having your image fade to a color that isn't part of the Bitmap? Personally, I'd prefer to include the colors when I want them and leave them out when I don't.

    Thanks again for the feedback!

  6. #6
    Tygur
    Guest

    Re: Bug with StretchImage in PictureBox?

    Originally posted by ljlevend
    So why do I care? Well, I'm glad you asked. Stretched 1D Bitmaps update MUCH faster in a PictureBox than 2D Bitmaps that completely fill a PictureBox. Of course, creating a 1D Bitmap is also much faster than creating a 2D Bitmap. So, the above method is the best way that I've found for creating a permanent gradient image.
    You're not quite correct here. It is actually faster to draw one big bitmap that takes up the whole picturebox than it is to stretch a smaller one. But you are right about it being quicker to actually create the smaller one.

  7. #7
    Tygur
    Guest
    So you're saying that you tested this out by just moving the picturebox and seeing a visual difference? That doesn't sound like a very accurate way of testing. I tried it and saw no visible difference in speed.

  8. #8

    Thread Starter
    Member
    Join Date
    Mar 2002
    Posts
    40
    Originally posted by Tygur
    So you're saying that you tested this out by just moving the picturebox and seeing a visual difference? That doesn't sound like a very accurate way of testing. I tried it and saw no visible difference in speed.
    Hey, who ever said anything about accuracy? Maybe you just didn’t look hard enough

    Anyway, here is some sample code that is a bit more quantitative. As it turns out, we both were right (which sounds a lot better than saying we both were wrong). The relative speed of Stretched vs. Normal (i.e., non-stretched) Bitmaps in a PictureBox depends on what you are doing with the PictureBox. The sample code test four scenarios. Here are the results on my computer (1.33MHz Athlon, 266DDR, GeForce3):

    1. Set PictureBox.Image = Nothing and then set PictureBox.Image = (Pre-made Bitmap): The Stretched image takes 10% longer to update.

    2. Move the PictureBox a small (i.e., <10 pixels) amount: The Normal image takes 150% - 170+% longer to update (the ratio increases as the distance that the PictureBoxes move decreases).

    3. Move the PictureBox off of the screen and then back on to the screen: The Stretched image takes 14% longer to update.

    4. Resize the PictureBox by a small amount: The Stretched image takes 40% - 50+% longer to update (the ratio increases as the length of the PictureBoxes increases).

    So there you have it. If you're Resizing a PictureBox, then is seems like it is faster to set SizeMode to Normal and use a Bitmap that fills the entire PictureBox. But, if you're moving a PictureBox, then it is faster to set SizeMode to StretchImage and use a 1D Bitmap.
    Attached Files Attached Files

  9. #9
    Addicted Member wolfofthenorth's Avatar
    Join Date
    Jan 2001
    Location
    Tatooine
    Posts
    169
    Hi,

    What the heck is a 1D bitmap?

    That which does not kill us, only makes us stronger.

  10. #10

    Thread Starter
    Member
    Join Date
    Mar 2002
    Posts
    40
    Originally posted by wolfofthenorth
    ...What the heck is a 1D bitmap?
    A "1D" Bitmap is a Bitmap with a width or height of 1. Sorry, I couldn't come up with a better way to refer to such a thing.

    The idea that I had is that you could create a 1D Bitmap with a linear gradient and then use a PictureBox's StretchImage SizeMode to quickly fill in the other dimension of the image. Unfortunately, this doesn't work all that well (see above posts).

  11. #11
    Addicted Member wolfofthenorth's Avatar
    Join Date
    Jan 2001
    Location
    Tatooine
    Posts
    169
    Thanks for explaining that to me.

    If you are interested in gradients, have you tryed the LinearGradientBrush and the PathGradientBrush. They look pretty good.

    That which does not kill us, only makes us stronger.

  12. #12
    hellswraith
    Guest
    LOL, your operating on a pretty slow processor....didn't know they made the Athlons that slow..lol
    1.33MHz Athlon

  13. #13
    Tygur
    Guest
    Originally posted by ljlevend
    So there you have it. If you're Resizing a PictureBox, then is seems like it is faster to set SizeMode to Normal and use a Bitmap that fills the entire PictureBox. But, if you're moving a PictureBox, then it is faster to set SizeMode to StretchImage and use a 1D Bitmap.
    These speed ratios actually make some sense after a bit of thought. Of course, I suggest that you look into using the LinearGradientBrush to make a full-sized bitmap and forget about stretching a smaller one

  14. #14

    Thread Starter
    Member
    Join Date
    Mar 2002
    Posts
    40
    Originally posted by hellswraith
    LOL, your operating on a pretty slow processor....didn't know they made the Athlons that slow..lol
    Ooops, did I say Athlon? I meant 286

    Originally posted by Tygur

    These speed ratios actually make some sense after a bit of thought. Of course, I suggest that you look into using the LinearGradientBrush to make a full-sized bitmap and forget about stretching a smaller one
    Is there a way to create a Bitmap from a LinearGradientBrush? I'm assuming your talking about using a LinearGradientBrush with the CreateGraphics thingy, but if not then PLEASE LET ME KNOW! I would love to be able to create a Bitmap from a LinearGradientBrush.

    The reason why I don't like to use a LinearGradientBrush with CreateGraphics is that then you have to make sure that your Graphics are updated after a Resize, a Move, or when a control with a lower ZOrder moves. In some cases this can cause problems because an event might not finish before the CreateGraphics is called so the resultant Graphic can use old information. Maybe there is a slick way to avoid this problem, but I haven't found it. (DoEvents scare me so I try to avoid them whenever possible.) With a Bitmap you only have to worry about the Resize event so Bitmaps are much easier for me to manage. Don't get me wrong, CreateGraphics is definitely my top pick when I'm sure that controls aren't moving.

  15. #15
    Addicted Member wolfofthenorth's Avatar
    Join Date
    Jan 2001
    Location
    Tatooine
    Posts
    169
    Try this

    Dim myBitMap As New Bitmap(Me.Width, Me.Height)
    Dim myRect As New Rectangle(10, 10, 400, 200)
    Dim myBrush As New LinearGradientBrush(myRect, Color.Purple, Color.Red, LinearGradientMode.Horizontal)

    Me.BackgroundImage = myBitMap
    Dim G As Graphics = Graphics.FromImage(myBitMap)
    G.Clear(Me.BackColor)

    G.FillRectangle(myBrush, myRect)
    That which does not kill us, only makes us stronger.

  16. #16

    Thread Starter
    Member
    Join Date
    Mar 2002
    Posts
    40
    wolfofthenorth, you just made my day! THANKS!

  17. #17
    Addicted Member wolfofthenorth's Avatar
    Join Date
    Jan 2001
    Location
    Tatooine
    Posts
    169
    Glad I could help.
    That which does not kill us, only makes us stronger.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width