Чтение изображения от Доступа - параметр, не допустимый

У меня есть простая база данных в Доступе .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);
}

7
задан George Stocker 29 June 2013 в 13:55
поделиться

2 ответа

Если вы считываете данные непосредственно из 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-файлов 'Длинные двоичные данные'. Поиск намного проще. Не знаю, есть ли у вас такая возможность, но если да, то было бы неплохо.

7
ответ дан 7 December 2019 в 05:22
поделиться

Я не верю, что ваша проблема связана с базой данных. Исключения «Параметр недействителен» при работе с изображениями могут быть настоящей головной болью, поскольку я уже имел дело с ними раньше. Они не очень понимают, в чем проблема.

Как именно изображение было помещено в базу данных? Может возникнуть проблема с записью изображения в базу данных, прежде чем вы даже попытаетесь его извлечь. Кроме того, какой тип файла представляет собой изображение?

РЕДАКТИРОВАТЬ Вот пример кода, который я использовал раньше для получения изображения из массива байтов.

        //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);
    }
1
ответ дан 7 December 2019 в 05:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: