|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Fastest way to update a Picturebox's imageI have an app (written in .NET 2.0) which updates a picturebox according to some user input (a slider control). when the user makes a change i loop through all of the pixels, do a calculation and update the picture. i currently use the GDI SetPixel method on each pixel of the Pictureboxes image. This is proving far to slow, about 1.5 seconds on average. This app needs to display the update as fast as possible. Has anyone got any ideas as to how to speed this up? i was thinking about trying to access the picturebox's memory space directly, pseudo code: For Each pixel in <PictureBox.Image's bytearray> <PictureBox.Image's bytearray> (pixel) = <new pixel value from calculation> Next This way you're only updating some byte values in memory rather than calling GDI method's. Am i barking up the wrong tree? Has anyone got any better solutions? Any help would be much appreciated. Alex On 24 Jul 2006 10:08:16 -0700, keba***@gmail.com wrote:
Show quoteHide quote >Hi, It would be helpful to know exactly what you are changing (i.e. Contrast, Saturation)?> >I have an app (written in .NET 2.0) which updates a picturebox >according to some user input (a slider control). when the user makes a >change i loop through all of the pixels, do a calculation and update >the picture. i currently use the GDI SetPixel method on each pixel of >the Pictureboxes image. This is proving far to slow, about 1.5 seconds >on average. This app needs to display the update as fast as possible. >Has anyone got any ideas as to how to speed this up? i was thinking >about trying to access the picturebox's memory space directly, pseudo >code: > >For Each pixel in <PictureBox.Image's bytearray> > <PictureBox.Image's bytearray> (pixel) = <new pixel value from >calculation> >Next > >This way you're only updating some byte values in memory rather than >calling GDI method's. > >Am i barking up the wrong tree? Has anyone got any better solutions? >Any help would be much appreciated. > >Alex Gene Hi gene,
The calculation is a bespoke alteration that matches the 3rd party software we're integrating with. in a nutshell for each RGB of every pixel i have to to a look up based on the starting byte value and the correction value. this look up gives a new byte value. so there are three lookups for each pixel that returns a new RGB value. what i need to know is the fasted possible way of setting this new pixel value to the picturebox. Hope that helps, Alex gene kelley wrote: Show quoteHide quote > On 24 Jul 2006 10:08:16 -0700, keba***@gmail.com wrote: > > >Hi, > > > >I have an app (written in .NET 2.0) which updates a picturebox > >according to some user input (a slider control). when the user makes a > >change i loop through all of the pixels, do a calculation and update > >the picture. i currently use the GDI SetPixel method on each pixel of > >the Pictureboxes image. This is proving far to slow, about 1.5 seconds > >on average. This app needs to display the update as fast as possible. > >Has anyone got any ideas as to how to speed this up? i was thinking > >about trying to access the picturebox's memory space directly, pseudo > >code: > > > >For Each pixel in <PictureBox.Image's bytearray> > > <PictureBox.Image's bytearray> (pixel) = <new pixel value from > >calculation> > >Next > > > >This way you're only updating some byte values in memory rather than > >calling GDI method's. > > > >Am i barking up the wrong tree? Has anyone got any better solutions? > >Any help would be much appreciated. > > > >Alex > > > It would be helpful to know exactly what you are changing (i.e. Contrast, Saturation)? > > Gene On 25 Jul 2006 02:38:58 -0700, keba***@gmail.com wrote:
Show quoteHide quote >Hi gene, You may want to investigate the ColorMatrix Class. If you are using VB2005, go to the help menu,> >The calculation is a bespoke alteration that matches the 3rd party >software we're integrating with. in a nutshell for each RGB of every >pixel i have to to a look up based on the starting byte value and the >correction value. this look up gives a new byte value. so there are >three lookups for each pixel that returns a new RGB value. what i need >to know is the fasted possible way of setting this new pixel value to >the picturebox. > >Hope that helps, >Alex > >gene kelley wrote: >> On 24 Jul 2006 10:08:16 -0700, keba***@gmail.com wrote: >> >> >Hi, >> > >> >I have an app (written in .NET 2.0) which updates a picturebox >> >according to some user input (a slider control). when the user makes a >> >change i loop through all of the pixels, do a calculation and update >> >the picture. i currently use the GDI SetPixel method on each pixel of >> >the Pictureboxes image. This is proving far to slow, about 1.5 seconds >> >on average. This app needs to display the update as fast as possible. >> >Has anyone got any ideas as to how to speed this up? i was thinking >> >about trying to access the picturebox's memory space directly, pseudo >> >code: >> > >> >For Each pixel in <PictureBox.Image's bytearray> >> > <PictureBox.Image's bytearray> (pixel) = <new pixel value from >> >calculation> >> >Next >> > >> >This way you're only updating some byte values in memory rather than >> >calling GDI method's. >> > >> >Am i barking up the wrong tree? Has anyone got any better solutions? >> >Any help would be much appreciated. >> > >> >Alex >> >> >> It would be helpful to know exactly what you are changing (i.e. Contrast, Saturation)? >> >> Gene search GDI+ Image. Download the example. The example shows a couple of uses of the ColorMatrix like convert to grayscale which would be fairly slow using SetPixel method. Back in VB6, would have used Get/Set DibBits routines in place of Get/Set Pixels, but I have not tried using any of those routines to day in .NET. Gene Hi
I haven't had to do any of this in .Net yet but you may want to look at using a Bit Blit technique (which is what you're really describing when you're talking about doing it in memory) - it's commonly referred to as BitBlt and involves an API call. Hope that helps Martin gene kelley wrote: Show quoteHide quote > On 25 Jul 2006 02:38:58 -0700, keba***@gmail.com wrote: > > >Hi gene, > > > >The calculation is a bespoke alteration that matches the 3rd party > >software we're integrating with. in a nutshell for each RGB of every > >pixel i have to to a look up based on the starting byte value and the > >correction value. this look up gives a new byte value. so there are > >three lookups for each pixel that returns a new RGB value. what i need > >to know is the fasted possible way of setting this new pixel value to > >the picturebox. > > > >Hope that helps, > >Alex > > > >gene kelley wrote: > >> On 24 Jul 2006 10:08:16 -0700, keba***@gmail.com wrote: > >> > >> >Hi, > >> > > >> >I have an app (written in .NET 2.0) which updates a picturebox > >> >according to some user input (a slider control). when the user makes a > >> >change i loop through all of the pixels, do a calculation and update > >> >the picture. i currently use the GDI SetPixel method on each pixel of > >> >the Pictureboxes image. This is proving far to slow, about 1.5 seconds > >> >on average. This app needs to display the update as fast as possible. > >> >Has anyone got any ideas as to how to speed this up? i was thinking > >> >about trying to access the picturebox's memory space directly, pseudo > >> >code: > >> > > >> >For Each pixel in <PictureBox.Image's bytearray> > >> > <PictureBox.Image's bytearray> (pixel) = <new pixel value from > >> >calculation> > >> >Next > >> > > >> >This way you're only updating some byte values in memory rather than > >> >calling GDI method's. > >> > > >> >Am i barking up the wrong tree? Has anyone got any better solutions? > >> >Any help would be much appreciated. > >> > > >> >Alex > >> > >> > >> It would be helpful to know exactly what you are changing (i.e. Contrast, Saturation)? > >> > >> Gene > > > You may want to investigate the ColorMatrix Class. If you are using VB2005, go to the help menu, > search GDI+ Image. Download the example. The example shows a couple of uses of the ColorMatrix > like convert to grayscale which would be fairly slow using SetPixel method. > > Back in VB6, would have used Get/Set DibBits routines in place of Get/Set Pixels, but I have not > tried using any of those routines to day in .NET. > > Gene On 26 Jul 2006 03:00:58 -0700, "Pritcham" <dontwanttogivemyn***@hotmail.com> wrote: BitBlt is simply a method of copying data form a source to a destination. It has no use with>Hi > >I haven't had to do any of this in .Net yet but you may want to look at >using a Bit Blit technique (which is what you're really describing when >you're talking about doing it in memory) - it's commonly referred to as >BitBlt and involves an API call. > >Hope that helps >Martin regards to "changing" the color data in the source bitmap. In .Net, the BitBlt API is wrapped in the Graphics.CopyFromScreen method. Gene Hi
I'm aware of that but the original post asked about whether it was possible to do the work in memory as opposed to changing each pixel 1 at a time - if you're doing something like that then I understand that it is (or can be) quicker to do in memory and then bitblt the results back to the picture box data. gene kelley wrote: Show quoteHide quote > On 26 Jul 2006 03:00:58 -0700, "Pritcham" <dontwanttogivemyn***@hotmail.com> wrote: > > >Hi > > > >I haven't had to do any of this in .Net yet but you may want to look at > >using a Bit Blit technique (which is what you're really describing when > >you're talking about doing it in memory) - it's commonly referred to as > >BitBlt and involves an API call. > > > >Hope that helps > >Martin > > > BitBlt is simply a method of copying data form a source to a destination. It has no use with > regards to "changing" the color data in the source bitmap. > > In .Net, the BitBlt API is wrapped in the Graphics.CopyFromScreen method. > > > Gene keba***@gmail.com wrote:
Show quoteHide quote > Hi, Elsethread what you have written suggests that the only way to do what > > I have an app (written in .NET 2.0) which updates a picturebox > according to some user input (a slider control). when the user makes a > change i loop through all of the pixels, do a calculation and update > the picture. i currently use the GDI SetPixel method on each pixel of > the Pictureboxes image. This is proving far to slow, about 1.5 seconds > on average. This app needs to display the update as fast as possible. > Has anyone got any ideas as to how to speed this up? i was thinking > about trying to access the picturebox's memory space directly, pseudo > code: > > For Each pixel in <PictureBox.Image's bytearray> > <PictureBox.Image's bytearray> (pixel) = <new pixel value from > calculation> > Next > > This way you're only updating some byte values in memory rather than > calling GDI method's. > > Am i barking up the wrong tree? Has anyone got any better solutions? > Any help would be much appreciated. you want to do is indeed to perform a calculation on each pixel's color value in turn. So given that, I present this: (from the docs for Bitmap.LockBits) Private Sub LockUnlockBitsExample(ByVal e As PaintEventArgs) ' Create a new bitmap. Dim bmp As New Bitmap("c:\fakePhoto.jpg") ' Lock the bitmap's bits. Dim rect As New Rectangle(0, 0, bmp.Width, bmp.Height) Dim bmpData As System.Drawing.Imaging.BitmapData = bmp.LockBits(rect, _ Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat) ' Get the address of the first line. Dim ptr As IntPtr = bmpData.Scan0 ' Declare an array to hold the bytes of the bitmap. ' This code is specific to a bitmap with 24 bits per pixels. Dim bytes As Integer = bmp.Width * bmp.Height * 3 Dim rgbValues(bytes - 1) As Byte ' Copy the RGB values into the array. System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes) ' Set every red value to 255. For counter As Integer = 0 To rgbValues.Length - 1 Step 3 rgbValues(counter) = 255 Next ' Copy the RGB values back to the bitmap System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes) ' Unlock the bits. bmp.UnlockBits(bmpData) ' Draw the modified image. e.Graphics.DrawImage(bmp, 0, 150) End Sub Things to note: - the PixelFormat of the bitmap must be one with a definite bits-per-pixel: you can't use indexed bitmaps like this - the number of bits needed for each pixel depends on the PixelFormat of the bitmap; as a consequence, the size of the Byte array needed also depends on that - the format of the data in the Byte array you get *also* depends on the BPP of the PixelFormat. eg if it is 32 bpp, then you will get <alpha byte> <red byte> <green byte> <blue byte> repeated; if it is 24bpp with no alpha, you will get <red byte> <green byte> <blue byte> repeated; and all the others. Finally I must point out that you shouldn't get too attached to this technique - it's only appropriate when you (as in this case) *have* to examine each and every pixel individually. Things other people have mentioned, like ColorMatrix, are more appropriate for general image manipulation. -- Larry Lard larryl***@googlemail.com The address is real, but unread - please reply to the group For VB and C# questions - tell us which version |
|||||||||||||||||||||||