Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
151 views
in Technique[技术] by (71.8m points)

c# - Reading image from Access - parameter not valid

I have simple database in Access .mdb file, but I don't know how to deal with: "parameter not valid" exception when Im creating Image from stream. I'v read that I need to strip 78 bytes offset (from here) but I still get a "parameter not valid" error when I call FromStream, even after stripping off the first 78 bytes.


This doesn't work for me:

byte[] abytPic = (byte[])dt.Rows[0]["Photo"]; byte arrary with image
if ((abytPic[0] == 21) && (abytPic[1] == 28)) //It's true
{
    byte[] abytStripped = new byte[abytPic.Length - 78];
    System.Buffer.BlockCopy(abytPic, 78, abytStripped, 0, abytPic.Length - 78); 
    msPic = new emoryStream(abytStripped);
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you are reading the data directly from MS Access, you do not need to strip any header information.

Assuming the image is stored as a BLOB, which is the most common, here is code to read in the array of bytes from the database and store as an image file (sorry, VB instead of C#):

  Dim varBytes() As Byte

  Using cn As New OleDbConnection(myConnectionString)
     cn.Open()

     sqlText = "SELECT [myColumn] " _
              & "FROM [myTable] " _
              & "WHERE ([mySearchCriteria] = '" & mySearchTerm & "')"

     Using cm As New OleDbCommand(sqlText, cn)
        Dim rdr As OleDbDataReader

        rdr = cm.ExecuteReader

        rdr.Read()

        varBytes = rdr.GetValue(0)
     End Using

  End Using

  My.Computer.FileSystem.WriteAllBytes(myPath & "myFile.emf", varBytes, True)

This example that I had laying around is one where I knew the files in the database were .emf images. If you know the extension, you can put it on the file name. If you don't, you can leave it blank and then open the resulting with an image viewer; it should start. If you need to find the extension or file type, once it is saved as a file, you can open it with any hex editor and the file type will be available from the header information.

Your question is a little bit unclear, so I'm not sure the above code is exactly what you want, but it should get you a lot closer.

EDIT:

This is the VB code that takes the array of bytes, loads it into a MemoryStream object, and then creates an Image object from the Stream. This bit of code worked just fine, and displayed the image in a picturebox on my form.

  Dim img As Image
  Dim str As New MemoryStream(varBytes)
  img = Image.FromStream(str)
  PictureBox1.Image = img

If the C# equivalent of this is not working for you, then the problem is likely in how the image is stored in the MS Access database.

EDIT:

If the image in your database is stored as a 'Package' and not a 'Long binary data', then you will need to strip the header information that MS Access adds. I've been playing with the 'Package' type of image storage with a simple .jpg file. The header in this case is much longer than 78 bytes. In this instance, it's actually 234 bytes, and MS Access also added some information to the end of the original file; about 292 bytes in this case.

It looks like your original approach was correct, you will just need to determine how many bytes to strip off the front and rear of the Byte array for your situation.

I determined it for my file by comparing the original image file, and the file exported from the database, (not to a Stream object, see my first code) in a hex editor. Once I figured out how much information (header and footer) was added by MS Access, I then knew how many bytes needed to be stripped.

EDIT:

The size of the header added by MS Access when the image is stored as 'Package' varies depending on the file type, and the original location (full path information) of the image when it was dumped into the MS Access database. So, even for the same file type, you may have a different number of bytes to strip from the header for each file. This makes it a lot more difficult, because then you will have to scan the byte array until you find the normal start-of-file information for that file type, and then strip everything before it.

All this headache is one of the reasons that it is better to store images as BLOBs 'Long binary data' in a database. Retrieval is much easier. I don't know if you have the option to do this, but if so, it would be a good idea.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...