You load your bitmap as a memory stream. You then discard the BITMAPFILEHEADER. What you have left is a packed DIB. The packed DIB represents the BITMAPINFOHEADER, palette, if indexed, and the bitmap's image byte array. [quoted text, click to view] "Andreas" <dont.need@one.com> wrote in message news:uS3VgSURHHA.4404@TK2MSFTNGP03.phx.gbl... > Hi, > > I recently found a thread where Frank Hileman suggested using the Bitmap > overload that enables you to get direct access to the image byte-array, > opposed to using unsafe code along with lockbits. I've written a small > wrapper for this functionality and its working ok. My question is, how > would I load an image from a file into this byte array? Obviously using > the Bitmap.FromFile() it out of the question since I dont want an extra > bitmap object in memory and besides it would require me to transfer pixel > by pixel over to the byte array. > > So does anyone have any suggestions on how to do this, while (preferbly) > keep the ability to load various formats (I will settle for the onces that > Bitmap.FromFile can handle for now)? Speed is also a factor I would like > to increase as much as possible. It would require me to get the image > dimentions as well so I can initilize the correct byte array, get a known > stide size and so on.. you get the picture (no phun intended) =) > > > Thanks! > > Andreas >
Hi, I recently found a thread where Frank Hileman suggested using the Bitmap overload that enables you to get direct access to the image byte-array, opposed to using unsafe code along with lockbits. I've written a small wrapper for this functionality and its working ok. My question is, how would I load an image from a file into this byte array? Obviously using the Bitmap.FromFile() it out of the question since I dont want an extra bitmap object in memory and besides it would require me to transfer pixel by pixel over to the byte array. So does anyone have any suggestions on how to do this, while (preferbly) keep the ability to load various formats (I will settle for the onces that Bitmap.FromFile can handle for now)? Speed is also a factor I would like to increase as much as possible. It would require me to get the image dimentions as well so I can initilize the correct byte array, get a known stide size and so on.. you get the picture (no phun intended) =) Thanks! Andreas
Ahh, despite all the refinements of .NET we still find ourselves up to the elbows in header files eh? -- Bob Powell [MVP] Visual C#, System.Drawing Ramuseco Limited .NET consulting http://www.ramuseco.com Find great Windows Forms articles in Windows Forms Tips and Tricks http://www.bobpowell.net/tipstricks.htm Answer those GDI+ questions with the GDI+ FAQ http://www.bobpowell.net/faqmain.htm All new articles provide code in C# and VB.NET. Subscribe to the RSS feeds provided and never miss a new article. [quoted text, click to view] Michael Phillips, Jr. wrote: > You load your bitmap as a memory stream. You then discard the > BITMAPFILEHEADER. What you have left is a packed DIB. > > The packed DIB represents the BITMAPINFOHEADER, palette, if indexed, and the > bitmap's image byte array. > > > "Andreas" <dont.need@one.com> wrote in message > news:uS3VgSURHHA.4404@TK2MSFTNGP03.phx.gbl... >> Hi, >> >> I recently found a thread where Frank Hileman suggested using the Bitmap >> overload that enables you to get direct access to the image byte-array, >> opposed to using unsafe code along with lockbits. I've written a small >> wrapper for this functionality and its working ok. My question is, how >> would I load an image from a file into this byte array? Obviously using >> the Bitmap.FromFile() it out of the question since I dont want an extra >> bitmap object in memory and besides it would require me to transfer pixel >> by pixel over to the byte array. >> >> So does anyone have any suggestions on how to do this, while (preferbly) >> keep the ability to load various formats (I will settle for the onces that >> Bitmap.FromFile can handle for now)? Speed is also a factor I would like >> to increase as much as possible. It would require me to get the image >> dimentions as well so I can initilize the correct byte array, get a known >> stide size and so on.. you get the picture (no phun intended) =) >> >> >> Thanks! >> >> Andreas >> >
So there is a tradeoff between speed of rendering and ease of loading =( "Bob Powell [MVP]" <bob@_spamkiller_bobpowell.net> skrev i meddelandet news:%23eX$T1XRHHA.4404@TK2MSFTNGP03.phx.gbl... [quoted text, click to view] > Ahh, despite all the refinements of .NET we still find ourselves up to the > elbows in header files eh? > > -- > Bob Powell [MVP] > Visual C#, System.Drawing > > Ramuseco Limited .NET consulting > http://www.ramuseco.com > > Find great Windows Forms articles in Windows Forms Tips and Tricks > http://www.bobpowell.net/tipstricks.htm > > Answer those GDI+ questions with the GDI+ FAQ > http://www.bobpowell.net/faqmain.htm > > All new articles provide code in C# and VB.NET. > Subscribe to the RSS feeds provided and never miss a new article. > > > > > > Michael Phillips, Jr. wrote: >> You load your bitmap as a memory stream. You then discard the >> BITMAPFILEHEADER. What you have left is a packed DIB. >> >> The packed DIB represents the BITMAPINFOHEADER, palette, if indexed, and >> the bitmap's image byte array. >> >> >> "Andreas" <dont.need@one.com> wrote in message >> news:uS3VgSURHHA.4404@TK2MSFTNGP03.phx.gbl... >>> Hi, >>> >>> I recently found a thread where Frank Hileman suggested using the Bitmap >>> overload that enables you to get direct access to the image byte-array, >>> opposed to using unsafe code along with lockbits. I've written a small >>> wrapper for this functionality and its working ok. My question is, how >>> would I load an image from a file into this byte array? Obviously using >>> the Bitmap.FromFile() it out of the question since I dont want an extra >>> bitmap object in memory and besides it would require me to transfer >>> pixel by pixel over to the byte array. >>> >>> So does anyone have any suggestions on how to do this, while (preferbly) >>> keep the ability to load various formats (I will settle for the onces >>> that Bitmap.FromFile can handle for now)? Speed is also a factor I would >>> like to increase as much as possible. It would require me to get the >>> image dimentions as well so I can initilize the correct byte array, get >>> a known stide size and so on.. you get the picture (no phun intended) =) >>> >>> >>> Thanks! >>> >>> Andreas >>> >>
You must load and parse the headers yourself. Read them one at a time and use seek, if necessary, to move around the stream. The BITMAPFILEHEADER tells you that you have a valid bitmap and the actual location of the bitmap's byte array. The Bitmap's constructor needs the BITMAPINFO header and the byte array for the bits. Do interop the easy way by navigating your web browser to pinvoke.net. That site will help you set up the headers. [quoted text, click to view] "Andreas" <dont.need@one.com> wrote in message news:OLgt67gRHHA.3948@TK2MSFTNGP05.phx.gbl... > So if I want to use the fast bitmap access code I will have to implement > custom fileformat loaders? That's defintilty a bit over my head at this > moment, very new to graphics programming. I get this far then I come to a > screaming halt. The loading of the byte-array is very fast > > DialogResult results = this.openFileDialog1.ShowDialog(); > if (results == DialogResult.OK) > { > if (File.Exists(this.openFileDialog1.FileName)) > { > byte[] contents = null; > using (FileStream reader = > File.OpenRead(this.openFileDialog1.FileName)) > { > contents = new byte[reader.Length]; > reader.Read(contents, 0, (int)reader.Length); > reader.Close(); > } > } > } > > "Andreas" <dont.need@one.com> skrev i meddelandet > news:ObOyczcRHHA.3316@TK2MSFTNGP02.phx.gbl... >> So there is a tradeoff between speed of rendering and ease of loading =( >> >> "Bob Powell [MVP]" <bob@_spamkiller_bobpowell.net> skrev i meddelandet >> news:%23eX$T1XRHHA.4404@TK2MSFTNGP03.phx.gbl... >>> Ahh, despite all the refinements of .NET we still find ourselves up to >>> the elbows in header files eh? >>> >>> -- >>> Bob Powell [MVP] >>> Visual C#, System.Drawing >>> >>> Ramuseco Limited .NET consulting >>> http://www.ramuseco.com >>> >>> Find great Windows Forms articles in Windows Forms Tips and Tricks >>> http://www.bobpowell.net/tipstricks.htm >>> >>> Answer those GDI+ questions with the GDI+ FAQ >>> http://www.bobpowell.net/faqmain.htm >>> >>> All new articles provide code in C# and VB.NET. >>> Subscribe to the RSS feeds provided and never miss a new article. >>> >>> >>> >>> >>> >>> Michael Phillips, Jr. wrote: >>>> You load your bitmap as a memory stream. You then discard the >>>> BITMAPFILEHEADER. What you have left is a packed DIB. >>>> >>>> The packed DIB represents the BITMAPINFOHEADER, palette, if indexed, >>>> and the bitmap's image byte array. >>>> >>>> >>>> "Andreas" <dont.need@one.com> wrote in message >>>> news:uS3VgSURHHA.4404@TK2MSFTNGP03.phx.gbl... >>>>> Hi, >>>>> >>>>> I recently found a thread where Frank Hileman suggested using the >>>>> Bitmap overload that enables you to get direct access to the image >>>>> byte-array, opposed to using unsafe code along with lockbits. I've >>>>> written a small wrapper for this functionality and its working ok. My >>>>> question is, how would I load an image from a file into this byte >>>>> array? Obviously using the Bitmap.FromFile() it out of the question >>>>> since I dont want an extra bitmap object in memory and besides it >>>>> would require me to transfer pixel by pixel over to the byte array. >>>>> >>>>> So does anyone have any suggestions on how to do this, while >>>>> (preferbly) keep the ability to load various formats (I will settle >>>>> for the onces that Bitmap.FromFile can handle for now)? Speed is also >>>>> a factor I would like to increase as much as possible. It would >>>>> require me to get the image dimentions as well so I can initilize the >>>>> correct byte array, get a known stide size and so on.. you get the >>>>> picture (no phun intended) =) >>>>> >>>>> >>>>> Thanks! >>>>> >>>>> Andreas >>>>> >>>> >> > >
[quoted text, click to view] > Please have patience with me, hehe. So is this > http://pinvoke.net/default.aspx/Structures.BITMAPINFOHEADER the header > info I should use in my application? The pinvoke site doesnt declare the Yes [quoted text, click to view] > BITMAPFILEHEADER header. Also, Im probably completly wrong here, but are > you saying that the difference in the fileformats are the BITMAPFILEHEADER > and the rest is the same for all format, i.e a "DIB" section ?
The BITMAPFILEHEADER tells you that your image is in fact a bitmap and not a ..png, .gif, .jpeg, etc. It is important to look at the offset in the BITMAPFILEHEADER for the location of the bitmap's byte array, because it does not necessarily follow that this location is directly after the BITMAPINFOHEADER and the palette, if the bitmap is indexed. There are some applications that make use of file mapping. In that case, the bits must be DWORD aligned in the actual file so the location may differ by a few bytes. [quoted text, click to view] > The image fileformats roughly look something like this > > -- start of file -- > BITMAPFILEHEADER > BITMAPINFOHEADER
palette or color table if the bitmap is 256 colors or less DWORD masks, if necessary, for 16bpp or 32bpp bitmap images. If the bitmap uses the defaults, the masks are not necessary. [quoted text, click to view] > DIB, that is the bitmap's byte array > -- end of file --
Yes, if following the original Windows 3.1 bitmap specification. No, if the application is using file mapping. The DIB will be located on a DWORD aligned location in the file. You may use the Marshal class to fill in the headers for the following: [quoted text, click to view] > (1) I know the size of the BITMAPFILEHEADER in bytes, so I skip them in my > bye-array. This is the offset, in the byte-array, for the BITMAPINFOHEADER > (2) I know the offset and size for the BITMAPINFOHEADER in bytes, so I use > some kind of memory copy to fill a BITMAPINFOHEADER structure > (3) From the BITMAPINFOHEADER I can then dimension my new byte-array (to > be used with the Bitmap constructor which takes the pointer to the > byte-array). I now also know the offset, in bytes, to the DIB section of > the file. > (4) I use some kind of memory copy to copy the DIB section information > into the byte array I was able to create in (3) > (5) I create the bitmap object (Bitmap x = new Bitmap(width,height, > stride, pixelformat, intptr)
The above is one way to load a bitmap and use Frank Hileman's method to speed access using System.Drawing methods.
Load it first into a Bitmap as usual. You will know the width and height at that point Then create a Graphics using a fast-access second bitmap (we call it EffectBuffer), and render into that second bitmap using DrawImageUnscaled. Dispose the first Bitmap. Also I just posted some more information on the fast access technique in the original thread. Regards, Frank Hileman check out VG.net: http://www.vgdotnet.com Animated vector graphics system Integrated Visual Studio graphics editor [quoted text, click to view] "Andreas" <dont.need@one.com> wrote in message news:uS3VgSURHHA.4404@TK2MSFTNGP03.phx.gbl... > Hi, > > I recently found a thread where Frank Hileman suggested using the Bitmap > overload that enables you to get direct access to the image byte-array, > opposed to using unsafe code along with lockbits. I've written a small > wrapper for this functionality and its working ok. My question is, how > would I load an image from a file into this byte array? Obviously using > the Bitmap.FromFile() it out of the question since I dont want an extra > bitmap object in memory and besides it would require me to transfer pixel > by pixel over to the byte array. > > So does anyone have any suggestions on how to do this, while (preferbly) > keep the ability to load various formats (I will settle for the onces that > Bitmap.FromFile can handle for now)? Speed is also a factor I would like > to increase as much as possible. It would require me to get the image > dimentions as well so I can initilize the correct byte array, get a known > stide size and so on.. you get the picture (no phun intended) =) > > > Thanks! > > Andreas >
So if I want to use the fast bitmap access code I will have to implement custom fileformat loaders? That's defintilty a bit over my head at this moment, very new to graphics programming. I get this far then I come to a screaming halt. The loading of the byte-array is very fast DialogResult results = this.openFileDialog1.ShowDialog(); if (results == DialogResult.OK) { if (File.Exists(this.openFileDialog1.FileName)) { byte[] contents = null; using (FileStream reader = File.OpenRead(this.openFileDialog1.FileName)) { contents = new byte[reader.Length]; reader.Read(contents, 0, (int)reader.Length); reader.Close(); } } } "Andreas" <dont.need@one.com> skrev i meddelandet news:ObOyczcRHHA.3316@TK2MSFTNGP02.phx.gbl... [quoted text, click to view] > So there is a tradeoff between speed of rendering and ease of loading =( > > "Bob Powell [MVP]" <bob@_spamkiller_bobpowell.net> skrev i meddelandet > news:%23eX$T1XRHHA.4404@TK2MSFTNGP03.phx.gbl... >> Ahh, despite all the refinements of .NET we still find ourselves up to >> the elbows in header files eh? >> >> -- >> Bob Powell [MVP] >> Visual C#, System.Drawing >> >> Ramuseco Limited .NET consulting >> http://www.ramuseco.com >> >> Find great Windows Forms articles in Windows Forms Tips and Tricks >> http://www.bobpowell.net/tipstricks.htm >> >> Answer those GDI+ questions with the GDI+ FAQ >> http://www.bobpowell.net/faqmain.htm >> >> All new articles provide code in C# and VB.NET. >> Subscribe to the RSS feeds provided and never miss a new article. >> >> >> >> >> >> Michael Phillips, Jr. wrote: >>> You load your bitmap as a memory stream. You then discard the >>> BITMAPFILEHEADER. What you have left is a packed DIB. >>> >>> The packed DIB represents the BITMAPINFOHEADER, palette, if indexed, and >>> the bitmap's image byte array. >>> >>> >>> "Andreas" <dont.need@one.com> wrote in message >>> news:uS3VgSURHHA.4404@TK2MSFTNGP03.phx.gbl... >>>> Hi, >>>> >>>> I recently found a thread where Frank Hileman suggested using the >>>> Bitmap overload that enables you to get direct access to the image >>>> byte-array, opposed to using unsafe code along with lockbits. I've >>>> written a small wrapper for this functionality and its working ok. My >>>> question is, how would I load an image from a file into this byte >>>> array? Obviously using the Bitmap.FromFile() it out of the question >>>> since I dont want an extra bitmap object in memory and besides it would >>>> require me to transfer pixel by pixel over to the byte array. >>>> >>>> So does anyone have any suggestions on how to do this, while >>>> (preferbly) keep the ability to load various formats (I will settle for >>>> the onces that Bitmap.FromFile can handle for now)? Speed is also a >>>> factor I would like to increase as much as possible. It would require >>>> me to get the image dimentions as well so I can initilize the correct >>>> byte array, get a known stide size and so on.. you get the picture (no >>>> phun intended) =) >>>> >>>> >>>> Thanks! >>>> >>>> Andreas >>>> >>> >
Michael, Please have patience with me, hehe. So is this http://pinvoke.net/default.aspx/Structures.BITMAPINFOHEADER the header info I should use in my application? The pinvoke site doesnt declare the BITMAPFILEHEADER header. Also, Im probably completly wrong here, but are you saying that the difference in the fileformats are the BITMAPFILEHEADER and the rest is the same for all format, i.e a "DIB" section ? According to http://www.webopedia.com/TERM/D/DIB.html a DIB is something used with BMP fileformats. Then again maybe the Bitmap class in dotnet works with a DIB internally, to be format independant? Like I've said Im very new to graphics programming and I havent even started disecting fileformats to get the basic understandings from them. I see this as a challenge though! So I would like to get this to work to add to my knowledge! So once I have my complete byte-array and I have defined the BITMAPINFOHEADER structure in my application.. then what? Im guessing something like this The image fileformats roughly look something like this -- start of file -- BITMAPFILEHEADER BITMAPINFOHEADER DIB -- end of file -- (1) I know the size of the BITMAPFILEHEADER in bytes, so I skip them in my bye-array. This is the offset, in the byte-array, for the BITMAPINFOHEADER (2) I know the offset and size for the BITMAPINFOHEADER in bytes, so I use some kind of memory copy to fill a BITMAPINFOHEADER structure (3) From the BITMAPINFOHEADER I can then dimension my new byte-array (to be used with the Bitmap constructor which takes the pointer to the byte-array). I now also know the offset, in bytes, to the DIB section of the file. (4) I use some kind of memory copy to copy the DIB section information into the byte array I was able to create in (3) (5) I create the bitmap object (Bitmap x = new Bitmap(width,height, stride, pixelformat, intptr) Thanks Andreas "Michael Phillips, Jr." <mphillips53@nospam.jun0.c0m> skrev i meddelandet news:eTRNELhRHHA.2172@TK2MSFTNGP04.phx.gbl... [quoted text, click to view] > You must load and parse the headers yourself. Read them one at a time and > use seek, if necessary, to move around the stream. > > The BITMAPFILEHEADER tells you that you have a valid bitmap and the actual > location of the bitmap's byte array. > > The Bitmap's constructor needs the BITMAPINFO header and the byte array > for the bits. > > Do interop the easy way by navigating your web browser to pinvoke.net. > That site will help you set up the headers. > > > "Andreas" <dont.need@one.com> wrote in message > news:OLgt67gRHHA.3948@TK2MSFTNGP05.phx.gbl... >> So if I want to use the fast bitmap access code I will have to implement >> custom fileformat loaders? That's defintilty a bit over my head at this >> moment, very new to graphics programming. I get this far then I come to >> a screaming halt. The loading of the byte-array is very fast >> >> DialogResult results = this.openFileDialog1.ShowDialog(); >> if (results == DialogResult.OK) >> { >> if (File.Exists(this.openFileDialog1.FileName)) >> { >> byte[] contents = null; >> using (FileStream reader = >> File.OpenRead(this.openFileDialog1.FileName)) >> { >> contents = new byte[reader.Length]; >> reader.Read(contents, 0, (int)reader.Length); >> reader.Close(); >> } >> } >> } >> >> "Andreas" <dont.need@one.com> skrev i meddelandet >> news:ObOyczcRHHA.3316@TK2MSFTNGP02.phx.gbl... >>> So there is a tradeoff between speed of rendering and ease of loading =( >>> >>> "Bob Powell [MVP]" <bob@_spamkiller_bobpowell.net> skrev i meddelandet >>> news:%23eX$T1XRHHA.4404@TK2MSFTNGP03.phx.gbl... >>>> Ahh, despite all the refinements of .NET we still find ourselves up to >>>> the elbows in header files eh? >>>> >>>> -- >>>> Bob Powell [MVP] >>>> Visual C#, System.Drawing >>>> >>>> Ramuseco Limited .NET consulting >>>> http://www.ramuseco.com >>>> >>>> Find great Windows Forms articles in Windows Forms Tips and Tricks >>>> http://www.bobpowell.net/tipstricks.htm >>>> >>>> Answer those GDI+ questions with the GDI+ FAQ >>>> http://www.bobpowell.net/faqmain.htm >>>> >>>> All new articles provide code in C# and VB.NET. >>>> Subscribe to the RSS feeds provided and never miss a new article. >>>> >>>> >>>> >>>> >>>> >>>> Michael Phillips, Jr. wrote: >>>>> You load your bitmap as a memory stream. You then discard the >>>>> BITMAPFILEHEADER. What you have left is a packed DIB. >>>>> >>>>> The packed DIB represents the BITMAPINFOHEADER, palette, if indexed, >>>>> and the bitmap's image byte array. >>>>> >>>>> >>>>> "Andreas" <dont.need@one.com> wrote in message >>>>> news:uS3VgSURHHA.4404@TK2MSFTNGP03.phx.gbl... >>>>>> Hi, >>>>>> >>>>>> I recently found a thread where Frank Hileman suggested using the >>>>>> Bitmap overload that enables you to get direct access to the image >>>>>> byte-array, opposed to using unsafe code along with lockbits. I've >>>>>> written a small wrapper for this functionality and its working ok. My >>>>>> question is, how would I load an image from a file into this byte >>>>>> array? Obviously using the Bitmap.FromFile() it out of the question >>>>>> since I dont want an extra bitmap object in memory and besides it >>>>>> would require me to transfer pixel by pixel over to the byte array. >>>>>> >>>>>> So does anyone have any suggestions on how to do this, while >>>>>> (preferbly) keep the ability to load various formats (I will settle >>>>>> for the onces that Bitmap.FromFile can handle for now)? Speed is also >>>>>> a factor I would like to increase as much as possible. It would >>>>>> require me to get the image dimentions as well so I can initilize the >>>>>> correct byte array, get a known stide size and so on.. you get the >>>>>> picture (no phun intended) =) >>>>>> >>>>>> >>>>>> Thanks! >>>>>> >>>>>> Andreas >>>>>> >>>>> >>> >> >> > >
Hi Andreas, Yes, the double memory is the tradeoff with using the built-in bitmap file reader. We can hope that if the file format is compressed, the first bitmap will be smaller than the second (the second is fully uncompressed). Also, if you care about speed, I don't recommend PictureBox, but a Control-derived class and paint a portion of the bitmap directly on that. Regards, Frank Hileman [quoted text, click to view] "Andreas" <dont.need@one.com> wrote in message news:upiGMkqRHHA.1860@TK2MSFTNGP06.phx.gbl... > Thanks Frank, I actually got it working myself before I saw your code. I > load the my image like Michael Phillips suggested. Sure I'm currently > limited to BMP fileformat but that can be changed. Wouldnt your method > mean I would your method mean I would, for a moment, have two bitmaps at > the same time? If I use large images then this will eat memory for sure. > > The one advantage with your method is that I will be able to use various > fileformats "out of the box" and don't need to make my own file format > parsers (BMP was easy, but I fear PNG; JPG and GIF can be a bit tricker). > > > "Frank Hileman" <frankhil@no.spamming.prodigesoftware.com> skrev i > meddelandet news:%23RIeYmlRHHA.4632@TK2MSFTNGP04.phx.gbl... >> Load it first into a Bitmap as usual. You will know the width and height >> at that point Then create a Graphics using a fast-access second bitmap >> (we call it EffectBuffer), and render into that second bitmap using >> DrawImageUnscaled. Dispose the first Bitmap. >> >> Also I just posted some more information on the fast access technique in >> the original thread.
[quoted text, click to view] > (top left pixel is drawn at bottom left and so on). What am I missing > here?
It's the Windows 3.1 Bitmap specification(i.e.,top left pixel at the bottom) .. That is how it is stored in the file. You may flip it before creating or after creating the bitmap object.
[quoted text, click to view] > By the way Michael, do you know if other file formats like png, gif and > jpg (after decompression and such) all have a "DIB" section as well that I > can extract and send to the Bitmap contructor overload just like a bmp > image? Or will I have to parse, for example, a png file, retrieve its > image information and fill out my own DIB which is then used byt the > Bitmap constructor overload?
For compressed image formats like jpeg, png, gif, tiff, etc., you will not know what the image array looks like until it is fully decompressed. Loading, parsing headers and decompressing image bytes for the other image formats is best left for the gdiplus decoders. Frank Hileman's suggestion to let gdiplus load and decode the image is the easy way to get the job done. Just create a second bitmap object with his method and use DrawImage to transfer the image from the source to the optimized bitmap object and then delete the original bitmap object.
Hi, Thanks for your patience and help. I've managed to successfully load the DIB of the bitmap and use Frank Hileman's suggested method for creating the bitmap. It's lightning fast. I loaded a 3000x3000x24bit BMP into a picturebox and it took about ½ second to do it. However, I have come across something strange. My bitmap loads perfectly, but when its displayed in the picturebox its flipped on the vertical axis (top left pixel is drawn at bottom left and so on). What am I missing here? Thanks, Andreas "Michael Phillips, Jr." <mphillips53@nospam.jun0.c0m> skrev i meddelandet news:unLCPwhRHHA.4744@TK2MSFTNGP02.phx.gbl... [quoted text, click to view] >> Please have patience with me, hehe. So is this >> http://pinvoke.net/default.aspx/Structures.BITMAPINFOHEADER the header >> info I should use in my application? The pinvoke site doesnt declare the > > Yes > >> BITMAPFILEHEADER header. Also, Im probably completly wrong here, but are >> you saying that the difference in the fileformats are the >> BITMAPFILEHEADER and the rest is the same for all format, i.e a "DIB" >> section ? > > The BITMAPFILEHEADER tells you that your image is in fact a bitmap and not > a .png, .gif, .jpeg, etc. > > It is important to look at the offset in the BITMAPFILEHEADER for the > location of the bitmap's byte array, because it does not necessarily > follow that this location is directly after the BITMAPINFOHEADER and the > palette, if the bitmap is indexed. There are some applications that make > use of file mapping. In that case, the bits must be DWORD aligned in the > actual file so the location may differ by a few bytes. > >> The image fileformats roughly look something like this >> >> -- start of file -- >> BITMAPFILEHEADER >> BITMAPINFOHEADER > > palette or color table if the bitmap is 256 colors or less > > DWORD masks, if necessary, for 16bpp or 32bpp bitmap images. > If the bitmap uses the defaults, the masks are not necessary. > >> DIB, that is the bitmap's byte array >> -- end of file -- > > Yes, if following the original Windows 3.1 bitmap specification. No, if > the application is using file mapping. The DIB will be located on a DWORD > aligned location in the file. > > You may use the Marshal class to fill in the headers for the following: > >> (1) I know the size of the BITMAPFILEHEADER in bytes, so I skip them in >> my bye-array. This is the offset, in the byte-array, for the >> BITMAPINFOHEADER >> (2) I know the offset and size for the BITMAPINFOHEADER in bytes, so I >> use some kind of memory copy to fill a BITMAPINFOHEADER structure >> (3) From the BITMAPINFOHEADER I can then dimension my new byte-array (to >> be used with the Bitmap constructor which takes the pointer to the >> byte-array). I now also know the offset, in bytes, to the DIB section of >> the file. >> (4) I use some kind of memory copy to copy the DIB section information >> into the byte array I was able to create in (3) >> (5) I create the bitmap object (Bitmap x = new Bitmap(width,height, >> stride, pixelformat, intptr) > > The above is one way to load a bitmap and use Frank Hileman's method to > speed access using System.Drawing methods. > > >
Thanks Frank, I actually got it working myself before I saw your code. I load the my image like Michael Phillips suggested. Sure I'm currently limited to BMP fileformat but that can be changed. Wouldnt your method mean I would your method mean I would, for a moment, have two bitmaps at the same time? If I use large images then this will eat memory for sure. The one advantage with your method is that I will be able to use various fileformats "out of the box" and don't need to make my own file format parsers (BMP was easy, but I fear PNG; JPG and GIF can be a bit tricker). "Frank Hileman" <frankhil@no.spamming.prodigesoftware.com> skrev i meddelandet news:%23RIeYmlRHHA.4632@TK2MSFTNGP04.phx.gbl... [quoted text, click to view] > Load it first into a Bitmap as usual. You will know the width and height > at that point Then create a Graphics using a fast-access second bitmap (we > call it EffectBuffer), and render into that second bitmap using > DrawImageUnscaled. Dispose the first Bitmap. > > Also I just posted some more information on the fast access technique in > the original thread. > > Regards, > Frank Hileman > > check out VG.net: http://www.vgdotnet.com > Animated vector graphics system > Integrated Visual Studio graphics editor > > "Andreas" <dont.need@one.com> wrote in message > news:uS3VgSURHHA.4404@TK2MSFTNGP03.phx.gbl... >> Hi, >> >> I recently found a thread where Frank Hileman suggested using the Bitmap >> overload that enables you to get direct access to the image byte-array, >> opposed to using unsafe code along with lockbits. I've written a small >> wrapper for this functionality and its working ok. My question is, how >> would I load an image from a file into this byte array? Obviously using >> the Bitmap.FromFile() it out of the question since I dont want an extra >> bitmap object in memory and besides it would require me to transfer pixel >> by pixel over to the byte array. >> >> So does anyone have any suggestions on how to do this, while (preferbly) >> keep the ability to load various formats (I will settle for the onces >> that Bitmap.FromFile can handle for now)? Speed is also a factor I would >> like to increase as much as possible. It would require me to get the >> image dimentions as well so I can initilize the correct byte array, get a >> known stide size and so on.. you get the picture (no phun intended) =) >> >> >> Thanks! >> >> Andreas >> > >
By the way Michael, do you know if other file formats like png, gif and jpg (after decompression and such) all have a "DIB" section as well that I can extract and send to the Bitmap contructor overload just like a bmp image? Or will I have to parse, for example, a png file, retrieve its image information and fill out my own DIB which is then used byt the Bitmap constructor overload? Hope it was somewhat clear ;) "Michael Phillips, Jr." <mphillips53@nospam.jun0.c0m> skrev i meddelandet news:unLCPwhRHHA.4744@TK2MSFTNGP02.phx.gbl... [quoted text, click to view] >> Please have patience with me, hehe. So is this >> http://pinvoke.net/default.aspx/Structures.BITMAPINFOHEADER the header >> info I should use in my application? The pinvoke site doesnt declare the > > Yes > >> BITMAPFILEHEADER header. Also, Im probably completly wrong here, but are >> you saying that the difference in the fileformats are the >> BITMAPFILEHEADER and the rest is the same for all format, i.e a "DIB" >> section ? > > The BITMAPFILEHEADER tells you that your image is in fact a bitmap and not > a .png, .gif, .jpeg, etc. > > It is important to look at the offset in the BITMAPFILEHEADER for the > location of the bitmap's byte array, because it does not necessarily > follow that this location is directly after the BITMAPINFOHEADER and the > palette, if the bitmap is indexed. There are some applications that make > use of file mapping. In that case, the bits must be DWORD aligned in the > actual file so the location may differ by a few bytes. > >> The image fileformats roughly look something like this >> >> -- start of file -- >> BITMAPFILEHEADER >> BITMAPINFOHEADER > > palette or color table if the bitmap is 256 colors or less > > DWORD masks, if necessary, for 16bpp or 32bpp bitmap images. > If the bitmap uses the defaults, the masks are not necessary. > >> DIB, that is the bitmap's byte array >> -- end of file -- > > Yes, if following the original Windows 3.1 bitmap specification. No, if > the application is using file mapping. The DIB will be located on a DWORD > aligned location in the file. > > You may use the Marshal class to fill in the headers for the following: > >> (1) I know the size of the BITMAPFILEHEADER in bytes, so I skip them in >> my bye-array. This is the offset, in the byte-array, for the >> BITMAPINFOHEADER >> (2) I know the offset and size for the BITMAPINFOHEADER in bytes, so I >> use some kind of memory copy to fill a BITMAPINFOHEADER structure >> (3) From the BITMAPINFOHEADER I can then dimension my new byte-array (to >> be used with the Bitmap constructor which takes the pointer to the >> byte-array). I now also know the offset, in bytes, to the DIB section of >> the file. >> (4) I use some kind of memory copy to copy the DIB section information >> into the byte array I was able to create in (3) >> (5) I create the bitmap object (Bitmap x = new Bitmap(width,height, >> stride, pixelformat, intptr) > > The above is one way to load a bitmap and use Frank Hileman's method to > speed access using System.Drawing methods. > > >
Don't see what you're looking for? Try a search.
|