.NET Forum / Languages / VB.NET / May 2008
Get RAW Bitmap Data from a file
|
|
Thread rating:  |
RB0135 - 18 May 2008 00:23 GMT Hi All,
I have some Windows BMP, 1BPP, monochrome files that I need to get the raw data from to load a graphics buffer on a Roll Printer (which I know can be done). Lets forget about the Roll Printer in this equation as I am not sure I am getting the correct "raw" image from the file.
However, when I print what I think is the raw data, I get the image size, but the information within the image looks nothing like it should be, and looks like it is an out of sync TV, or interlaced not progressive. But, the image itself is unreadable, nothing looking even remotely to the original.
What I need to verify (or am asking for help) is to get the raw data out of the bitmap file correctly. Here is some code that I use to get the raw data (I think).
Dim bmBitmap As Image = New Bitmap("test.bmp") (also tried Dim bmBitmap As bitmap= New Bitmap("test.bmp") )
Dim raw As System.Drawing.Imaging.BitmapData = Nothing 'used to get attributes of the image Dim rawImage() As Byte = Nothing 'the image as a byte[]
Try 'Freeze the image in memory raw = bmbitmap.LockBits(New Rectangle(0, 0, bmbitmap.Width, bmbitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, Imaging.PixelFormat.Format1bppIndexed)
Dim size As Integer = raw.Height * raw.Stride rawImage = New Byte(size - 1)
'Copy the image into the byte() System.Runtime.InteropServices.Marshal.Copy(raw.Scan0, rawImage, 0, size) Finally If Not raw Is Nothing Then 'Unfreeze the memory for the image bmbitmap.UnlockBits(raw) End If End Try
The rawimage is what I try to print.
Am I doing something wrong or am I missing some steps.
I have also tried to load the RAWIMAGE returned bytes in a PictureBox, with the following code
Dim ms As New IO.MemoryStream(rawimage) pbPicture.Image = Image.FromStream(ms) <-- errors here
but get the "PARAMETER IS INCORRECT" error message, and I know from other posts, this is usually because the BYTE data is invalid (or not raw), although the byte length returned is 2880 bytes, which does equate to the width*height*8 of the image.
So, to state again, I just need the raw bytes that makeup the image within the bmp files.. I am sure I am close, but I am also sure I might be missing out on one step.
Any help/links most appreciated.
Thanks, Robert
Armin Zingler - 18 May 2008 01:28 GMT > Dim rawImage() As Byte = Nothing 'the image as a byte[] You don't have to set it to Nothing because it is Nothing as you have not assigned anything yet.
> rawImage = New Byte(size - 1) Can't compile this. The syntax above does not work. ReDim has to be used.
> but get the "PARAMETER IS INCORRECT" error message, and I know from > other posts, this is usually because the BYTE data is invalid (or > not raw), although the byte length returned is 2880 bytes, which > does equate to the width*height*8 of the image. I'm not sure...: You try Image.FromStream but you only have the pixel data without header bytes. If you wanted to use Image.FromStream, you would have to use a BinaryReader and read the whole file because only the pixel data is insufficient. Or you have to open the Filestream and pass it to Image.Fromstream directly. However, why don't you then use Image.FromFile or New Bitmap("test.bmp") ? If you need pixel data, LockBits is the right way, but what do you do want to do with the byte array in variable rawImage? The pixel data is in it, but that's not sufficient to be used with Image.FromStream.
Armin
RB0135 - 18 May 2008 04:10 GMT Thanks for your reply..
The code I used and presented in the original post was from the MS Robotic Lib SDK and does compile OK..
I understand your point about the redim, but mine compiles fine without it...
The part of code using the MemoryStream and a picture box, was another Idea I was testing to get the bytes, but it is not relevant to the overall issue.
The various bits of code are tests I am trying to do to get PIXEL DATA in the right format and the right data from the BMP file.
The data is transferred to the Roll Printer in Bytes, where it interperets it. Each bit is on or off.
All this is explained in the original post.
Thats what I need the rawimage data to be.. A bit representation of the image from the BMP file.. I dont want the header information, just, I suppose, what the image looks like in Bytes.
Does this make sense?
From your reply, the lockbits is the right way to go, but I am not getting the representation needed from the file.
I have read that BMP's store the data from bottom to top, left to right (or similar).. Is this the case?
Do I need more processing of the rawimage data to get the representation of the image from it?
Thanks again, Robert
> > Dim rawImage() As Byte = Nothing 'the image as a byte[] > [quoted text clipped - 23 lines] > > Armin Armin Zingler - 18 May 2008 08:54 GMT > Thanks for your reply.. > [quoted text clipped - 3 lines] > I understand your point about the redim, but mine compiles fine > without it... Strange. I tried it in VB 2008 Express and, as I expected, the syntax is not valid because, in VB, in opposite to C#, there is no "[]" for arrays. Therefore, "New Byte(size -1)" is interpreted as a constructor, but a Byte does not have such a constructor.
Are you really using VB.Net? ;-)
> The part of code using the MemoryStream and a picture box, was > another Idea I was testing to get the bytes, but it is not relevant [quoted text clipped - 7 lines] > > All this is explained in the original post. Not this way, nevertheless I got it now.
> Thats what I need the rawimage data to be.. A bit representation of > the image from the BMP file.. I dont want the header information, > just, I suppose, what the image looks like in Bytes. > > Does this make sense? Yes, but you don't show how you pass it to the roll printer.
> From your reply, the lockbits is the right way to go, but I am not > getting the representation needed from the file. How do you check this? I don't see any code that prints anything.
> I have read that BMP's store the data from bottom to top, left to > right (or similar).. Is this the case? > > Do I need more processing of the rawimage data to get the > representation of the image from it? I can only guess that you expect one byte per pixel, but you specified Imaging.PixelFormat.Format1bppIndexed as the format which means one bit per pixel (1 byte = 8 pixel). I don't know how you process the data in rawImage. In addition, IIRC, there is no indexed bitmap support in a certain area that I unfortunatelly don't remember currently.
It's always good to have a look here: http://www.bobpowell.net/ In the GDI+ FAQs, there is an example of creating a 1bpp image. There is also something about directly accessing pixel data. Maybe this helps in any way, too.
And we have m.p.d.framework.drawing.
Though, I'm still interested in how you really process 'rawImage'.
Armin
RB0135 - 18 May 2008 13:18 GMT Armin,
Thanks again for your reply.
Ok.. here is some more information. There is too much code to paste here on the printing and I didnt think at the time that was all that relevant, when I am sure I was NOT pulling the correct data out:
I looked at my code again and realised after the line rawImage = New Byte(size - 1) , I had to braces {} after the code, which was left over from the C# conversion. However, this made my source compile. When I removed them, and used the Redim, I got the same result anyway.
The Roll Printer is an Epson TM-T88 and a Posiflex PP7000 (The Posiflex uses the Epson command set). Both are giving the same result, so that is why I am also presuming I have the wrong raw data of the Bitmap
I am using code from this MS Knowledgebase that allows printing RAW data to the printer, rather than a driver (there isnt a driver for these Roll printers and using the Generic/text driver does not allow all characters to be transmitted to it). Here is the link: http://support.microsoft.com/?id=322090
To get the information to the printer, I need to send it the Define Graphic Download command:
RawPrinterHelper.SendStringToPrinter(pDocket.PrinterSettings.PrinterName.ToString(), Chr(29) & "*" & Chr(bmBitmap.Width / 8) & Chr(bmBitmap.Height / 8)) (this routine is in the above KB article, and the Chr(29) command is the Epson command to turn on Define Graphic Download).
Here is a section of the manual for the Epson: GS * x y d1 ... d(x * y * 8) defines a downloaded bit image using x * 8 dots in the horizontal direction and y * 8 dots in the vertical direction. Once a downloaded bit image has been defined, it is available until another definition is made; ESC & or ESC @ is executed; the printer is reset; or the power is turned off. When this command is executed, the user-defined characters are cleared. The default setting is no downloaded bit image defined.
Back to my program.......
Once I have the rawimage Byte array, I am sending this through that Epson Command, via this command from the KB Article:
' Allocate some unmanaged memory for those bytes. pUnmanagedBytes = Marshal.AllocCoTaskMem(rawimage.Length) ' Copy the managed byte array into the unmanaged array. Marshal.Copy(byBytes, 0, pUnmanagedBytes, image.Length)
RawPrinterHelper.SendBytesToPrinter(pDocket.PrinterSettings.PrinterName.ToString(), pUnmanagedBytes, rawimage.Length)
Of course, I get the right sized image being printed on the printer, but looks NOTHING like it should. As I mentioned, it just seems like a lot of lines (within the size of the image) like an out of sync TV picture...
This is the example they give:
x=16: y=5 PRINT #1, CHR$(&H1D);"*";CHR$(x);CHR$(y); FOR i=1 TO x*y*8 READ a$: d=VAL("&H"+a$) PRINT #1, CHR$(d); NEXT i PRINT #1, CHR$(&H1D);"/";CHR$(0);CHR$(&HA);¬ Normal END
DATA FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,C0,00,00,00,03,C0 DATA 00,00,00,03,CF,FF,FF,FF,F3,CF,FF,FF,FF,F3,CF,FF DATA FF,FF,F3,CF,FF,FF,FF,F3,CF,FF,FF,FF,F3,CF,C0,FC DATA 03,F3,CF,C0,FC,03,F3,CF,C0,FC,03,F3,CF,C0,FC,03 DATA F3,CF,C0,FC,03,F3,CF,C0,FC,03,F3,CF,C0,FC,03,F3 DATA CF,C0,FC,03,F3,CF,C0,FC,03,F3,CF,C0,00,03,F3,C0 DATA 00,00,00,03,C0,FF,00,03,F3,C3,FF,C0,03,F3,C7,FF DATA E0,03,F3,C7,FF,F0,03,F3,CF,FF,F8,03,F3,CF,FF,FC DATA 03,F3,CF,E3,FE,03,F3,CF,C1,FF,03,F3,CF,C0,FF,83 DATA F3,CF,C0,7F,C7,F3,CF,C0,3F,FF,F3,CF,C0,1F,FF,F3 DATA CF,C0,0F,FF,E3,CF,C0,07,FF,E3,CF,C0,03,FF,C3,C0 DATA 00,00,FF,03,C0,00,00,00,03,C0,3F,FF,FC,03,C0,FF DATA FF,FF,03,C3,FF,FF,FF,C3,C7,FF,FF,FF,E3,C7,FF,FF DATA FF,E3,CF,FF,FF,FF,F3,CF,F0,00,0F,F3,CF,C0,00,03 DATA F3,CF,C0,00,03,F3,CF,C0,00,03,F3,CF,C0,00,03,F3 DATA CF,C0,00,03,F3,CF,C0,00,03,F3,CF,C0,00,03,F3,CF DATA C0,00,03,F3,CF,C0,00,03,F3,C0,00,00,00,03,C0,00 DATA 00,00,73,C0,00,00,03,C3,C0,00,00,1E,03,C0,00,00 DATA 70,03,C0,00,03,C0,03,C0,00,1E,00,03,C0,00,78,00 DATA 03,C0,03,C0,00,03,C0,0E,00,00,03,C0,78,00,00,03 DATA C3,C0,00,00,03,CE,00,00,00,03,C0,00,00,00,03,CF DATA FF,FF,FF,F3,CF,FF,FF,FF,F3,CF,FF,FF,FF,F3,CF,FF DATA FF,FF,F3,CF,FF,FF,FF,F3,CF,FF,FF,FF,F3,CF,C0,0F DATA C0,03,CF,C0,0F,C0,03,CF,C0,0F,C0,03,CF,C0,0F,C0 DATA 03,CF,C0,0F,C0,03,CF,E0,1F,C0,03,CF,FF,FF,C0,03 DATA CF,FF,FF,CO,03,C7,FF,FF,80,03,C7,FF,FF,80,03,C1 DATA FF,FE,00,03,C0,3F,F0,00,03,C0,00,00,00,03,C0,0F DATA FF,F0,03,C0,FF,FF,FF,03,C3,FF,FF,FF,C3,C7,FF,FF DATA FF,E3,C7,FF,FF,FF,E3,CF,FF,FF,FF,F3,CF,F0,00,0F DATA F3,CF,C0,00,03,F3,CF,C0,00,03,F3,CF,C0,00,03,F3 DATA CF,C0,00,03,F3,CF,C0,00,03,F3,CF,C0,00,03,F3,CF DATA C0,00,03,F3,CF,F0,00,0F,F3,CF,FF,FF,FF,F3,C7,FF DATA FF,FF,E3,C7,FF,FF,FF,E3,C3,FF,FF,FF,C3,C0,FF,FF DATA FF,03,C0,0F,FF,F0,03,C0,00,00,00,03,C0,FF,00,03 DATA F3,C3,FF,C0,03,F3,C7,FF,E0,03,F3,C7,FF,F0,03,F3 DATA CF,FF,F8,03,F3,CF,FF,FC,03,F3,CF,E3,FE,03,F3,CF DATA C1,FF,03,F3,CF,C0,FF,83,F3,CF,C0,7F,C7,F3,CF,C0 DATA 3F,FF,F3,CF,C0,1F,FF,F3,CF,C0,0F,FF,E3,CF,C0,07 DATA FF,E3,CF,C0,03,FF,C3,C0,00,00,FF,C3,C0,00,00,00 DATA 03,C0,00,00,00,03,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF
I cant show you the graphic it prints. I can certainly email you the whole manual in PDF..
The bitmap that I am using has come from POSIFLEX and is what they state to test for Printing to the printer.
Now, I understand the 1bpp, but it seems the printer takes one byte per 8 pixels, so I was presuming that the RAW data is in the correct format. Also, when running the LockBits, it only allows me to use the format1bpp parameter. Any other format, even DONTCARE fails with INVALID PARAMETER.
You mentioned you dont know what I do with the rawimage data. As I mention here, I send it to the printer, but I am wondering and asking, do I need to process it further before sending it to the printer
I will check the link you gave me.. much appreciated.
If you can offer anymore assistance, or need extra information, please let me know.
Thanks, Robert
> > Thanks for your reply.. > [quoted text clipped - 60 lines] > > Armin Armin Zingler - 18 May 2008 13:57 GMT I'll have a look. Can take some time.
Armin
Armin Zingler - 18 May 2008 15:13 GMT > I cant show you the graphic it prints. I can certainly email you the > whole manual in PDF.. Good idea. Couldn't download it because at the Epson site a login is required, and at the Posiflex site I wasn't able to find a complete manual.
> If you can offer anymore assistance, or need extra information, > please let me know. The manual would really be nice. I did printing escape sequences some years ago, so I think can handle it quickly. Please send to: az dot no_spam at freenet dot de (like the re-address, just insert an "_")
Armin
Armin Zingler - 21 May 2008 09:27 GMT FYI, the problem has been solved. The printer expected the pixel data column by column, not row by row, which was not documented. After finding this out, we had to write a function that changes the orientation of the retrieved bitmap's pixel data (which was not simple because of 1bpp format).
So, if anybody has the same printer and problem, this is the answer. :)
Armin
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|