У меня есть простая база данных в Доступе .mdb файл, но я не знаю, как иметь дело с: "параметр не допустимое" исключение, когда я создаю Image
от потока. I'v читают, что я должен разделить 78-байтовое смещение (отсюда), но я все еще получаю "параметр не допустимая" ошибка, когда я называю FromStream, даже после снятия изоляции с первых 78 байтов.
Это не работает на меня:
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);
}
Если вы считываете данные непосредственно из MS Access, вам не нужно снимать информацию о заголовке.
Предполагая, что образ хранится в виде BLOB, что является наиболее распространенным, вот код для чтения в массиве байт из базы данных и хранения в виде файла образа (к сожалению, VB вместо 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)
В этом примере, который я проложил, я знал, что файлы в базе данных - это .emf-образы. Если вы знаете это расширение, вы можете поместить его в имя файла. Если нет, вы можете оставить его пустым, а затем открыть результат с помощью программы просмотра изображений; он должен начаться. Если вам нужно найти расширение или тип файла, то после сохранения его в виде файла, вы можете открыть его в любом шестнадцатиричном редакторе, и тип файла будет доступен из информации заголовка.
Ваш вопрос немного неясен, поэтому я не уверен, что приведенный выше код именно то, что вам нужно, но он должен подойти вам намного ближе.
EDIT:
Это VB код, который берет массив байт, загружает его в объект MemoryStream, а затем создает объект Image из потока. Этот бит кода работал просто отлично, и отображал изображение в картинке на моей форме.
Dim img As Image
Dim str As New MemoryStream(varBytes)
img = Image.FromStream(str)
PictureBox1.Image = img
Если эквивалент C# не работает, то проблема, скорее всего, в том, как изображение хранится в базе данных MS Access.
EDIT:
Если изображение в вашей базе данных хранится как 'Package', а не как 'Long binary data', то вам нужно удалить информацию о заголовке, которую добавляет MS Access. Я проиграл тип хранения образа 'Package' с простым .jpg файлом. В данном случае заголовок намного длиннее 78 байт. В данном случае это на самом деле 234 байта, и MS Access также добавил некоторую информацию в конец оригинального файла; в данном случае около 292 байт.
Похоже, что ваш оригинальный подход был верным, вам просто нужно определить, сколько байт нужно снять с лицевой и задней стороны массива байтов для вашей ситуации.
Я определил его для своего файла, сравнив исходный файл изображения и файл, экспортированный из базы данных (а не в объект Stream, см. мой первый код) в шестнадцатиричном редакторе. Как только я выяснил, сколько информации (заголовок и нижний колонтитул) было добавлено MS Access, я понял, сколько байт нужно удалить.
EDIT:
Размер заголовка, добавленного MS Access, когда изображение хранится в виде 'Package', варьируется в зависимости от типа файла, а также от исходного местоположения (полная информация о пути) изображения, когда оно было выгружено в базу данных MS Access. Таким образом, даже для одного и того же типа файлов у вас может быть разное количество байт, которые вы можете удалить из заголовка для каждого файла. Это значительно усложняет ситуацию, потому что тогда вам придется сканировать массив байтов до тех пор, пока вы не найдете нормальную информацию для этого типа файлов, а затем зачищать все перед ним.
Вся эта головная боль является одной из причин того, что лучше хранить образы в базе данных в виде BLOB-файлов 'Длинные двоичные данные'. Поиск намного проще. Не знаю, есть ли у вас такая возможность, но если да, то было бы неплохо.
Я не верю, что ваша проблема связана с базой данных. Исключения «Параметр недействителен» при работе с изображениями могут быть настоящей головной болью, поскольку я уже имел дело с ними раньше. Они не очень понимают, в чем проблема.
Как именно изображение было помещено в базу данных? Может возникнуть проблема с записью изображения в базу данных, прежде чем вы даже попытаетесь его извлечь. Кроме того, какой тип файла представляет собой изображение?
РЕДАКТИРОВАТЬ Вот пример кода, который я использовал раньше для получения изображения из массива байтов.
//takes an array of bytes and converts them to an image.
private Image getImageFromBytes(byte[] myByteArray)
{
System.IO.MemoryStream newImageStream = new System.IO.MemoryStream(myByteArray, 0, myByteArray.Length);
return Image.FromStream(newImageStream, true);
}