vrijdag, april 28, 2006

Convert byte[] to an Image/bitmap: why the System.ArgumentException: Invalid parameter used arises.....

I need images saved by an old vb6 program and convert them to a new db of a new prog. The old programma saved the images data into a image field of a SQL2000 DB. First I justed copy the image from V1 (db of the old programma) to V2 (the db (also SQL2000) used in the new program).

Problem: the data in the image field is corrupt! When I try to convert that data into a bitmap or jpg it gives me a Invalid parameter Exception when I do this code:

MemoryStream ImageDataStream = new MemoryStream();
// byte[] ImageData, filled with the image field of db
ImageDataStream.Write(ImageData,0,ImageData.Length);
ImageDataStream.Position=0;
Image img = Image.FromStream(ImageDataStream); //Invalid parameter Exception thrown

This is because the byte data of ImageData is corrupt due a Unicode encoding done by the old VB6 programma before/while saving it to db. Below some byte code (hex style) so that you can see the the good data vs the corrupt/wrong data:



A bitmap header starts with BM, so there you see that the is a doubling of the data: from 42 4D to 42 00 4D 00 => convertion to Unicode. You can't simply remove the 00 because unicoding is not just a 00 extend. For example 75 87 95 59 (see above in picture) will be converted to 75 00 21 20 22 20 59 00 and not just 75 00 87 00 95 00 59 00 !!

So what you have to do is convert the data back to the current ANSI code page (Encoding.Default):
ImageData=System.Text.UnicodeEncoding.Convert(Encoding.Unicode,Encoding.Default,ImageData);

So the code below will do the good convertion......
MemoryStream ImageDataStream = new MemoryStream();
ImageDataStream.Write(ImageData,0,ImageData.Length);
ImageDataStream.Position=0;
ImageData=System.Text.UnicodeEncoding.Convert(Encoding.Unicode,Encoding.Default,ImageData);
Image img = Image.FromStream(ImageDataStream);

Not every "Invalid parameter used" exception will be fixed like that, sometimes you need an other Convertion with other Encoder parameters or the image can have a added header (like the 78 long ole-header,..... => the code will be like ImageDataStream.Write(ImageData,78,ImageData.Length-78); )

Good luck!

donderdag, april 27, 2006

Messed up bitmap data ? FIXED (SEE ABOVE!)

On http://www.lierse.be/VB6bitmap.zip is a dat file (from an image field in SQL2000), it is a bitmap file, in an old VB6 programma that image is used and visible. So it is valid data. Problem: no code of vb6 of that prog is available.

My question: What is wrong with the bitmap data? does vb6 add some rubbish to it? I can't load it into image object in C# because a invalid argument exception (because somethings is wrong in the header or ...). I tried every offset (some people say use 78 as offset, because there will be a OLE header), and every offset gives the same error. I get an invalid argument when i do this:
ImageDataStream.Write(ImageData,i,ImageData.Length-i); // ok, tried every value of i
Image img = Image.FromStream(ImageDataStream); // the invalid argument error rises here


I'm trying now to rip the pixeldata and put the pixeldata in a own created bitmapfile with correct header/colormap... But still something is wrong, the pixeldata contains good data and then a piece of FF 00 FF 00 of the same length and that a few times....

Anybody knows what vb6 does to the imagedata when saving it to SQL2000 ? any tips are welcome.......

Internal Compiler Error: stage 'COMPILE' or 'BEGIN' errors

It happens sometimes, stupid bug in VS 2003? Most of the times it is one function that has a type error that for some kind of reason is not seen by the compiler (like DataRow myDataRow = new DataRRow();). Simply restart VS and look through your code and fix the mistyped stuff in the function......