Sh.Zakria Ответов: 3

Как получить изображение из базы данных access в visual studio?


Я пытаюсь извлечь изображение, хранящееся в базе данных Access, в Picturebox. Мне успешно удалось сохранить изображение в базе данных с помощью OLE-объекта, я не очень хорошо владею этим языком, но мой текущий код выглядит следующим образом:

Что я уже пробовал:

Private Sub lstUsers_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstUsers.SelectedIndexChanged

    Dim dt As New DataTable

    dt = runSQL("Select * from tblUser where UserName = '" & lstUsers.SelectedItem.ToString & "'")

    txtForename.Text = dt.Rows(0)(2)
    txtSurname.Text = dt.Rows(0)(3)
    txtCode.Text = dt.Rows(0)(6)
    txtFinish.Text = dt.Rows(0)(7)
    PictureBox1.Image = dt.Rows(0)(8)

End Sub



Когда я пытаюсь запустить эту программу и выбираю имя пользователя, я получаю следующее сообщение об ошибке:

Unable to cast object of type 'System.Byte[]' to type 'System.Drawing.Image'.


Любая помощь будет оценена по достоинству.

3 Ответов

Рейтинг:
2

Wendelius

Вы не можете поместить двоичные данные изображения непосредственно в picturebox, вам сначала нужно создать объект изображения из этих данных.

Об этом есть хорошая статья. Видеть: Сохранение и извлечение изображения из базы данных SQL Server с помощью VB.NET[^]

Не волнуйтесь, если база данных-это SQL Server, идея для изображения та же.


Рейтинг:
2

OriginalGriff

Здесь есть ряд проблем: во-первых, никогда не объединяйте строки для построения SQL-команды. Это оставляет вас широко открытыми для случайной или преднамеренной атаки SQL-инъекции, которая может уничтожить всю вашу базу данных. Вместо этого используйте параметризованные запросы.
Во-вторых, никогда не используйте SELECT * FROM - всегда указывайте, какие именно столбцы вы хотите получить и в каком порядке. Таким образом, вы не передаете данные, которые вам не нужны, что экономит пропускную способность, и ваш код становится более невосприимчивым к изменениям в базе данных, вызывающим ее сбой из - за другого порядка столбцов или, что еще хуже, поврежденных данных. Это особенно важно, если вы используете числовые индексы для извлечения содержимого столбцов вместо строковых имен столбцов.
В-третьих, не используйте DataTable для получения сведений об одном пользователе - вместо этого используйте DataReader, он намного эффективнее памяти - и проверьте возврат, чтобы убедиться, что есть данные, прежде чем пытаться получить к ним доступ! Если нет пользователя с таким именем, ваш код аварийно завершает работу и сгорает...
В-четвертых, не используйте код в решении 1: документация для Изображение.Метод FromStream (Поток) (System.Рисование)[^ очень специфично, что поток должен оставаться открытым в течение всей жизни изображения, что блок using не позволяет.

Dim ms As New MemoryStream(bytes)
Dim useThisImage As Image = Image.FromStream(ms)


Sh.Zakria

Большое вам спасибо за ваш ответ, теперь я его лучше понимаю. Каким будет окончательный код для отображения изображения из базы данных, если мое изображение хранится в (0) (8) в picturebox?
Я пытался:
Dim data As Byte () = DirectCast(dt. Rows(0)(8), Byte())
Использование ms в качестве нового потока памяти(данных)
Имя picturebox1.Образ = Образ.FromStream(МС)
Конец Использования
Но это дает мне ошибку-параметр недопустим.

OriginalGriff

Ах.
Это означает, что при сохранении изображений вы объединили строки для формирования SQL-команды. Это плохо , очень плохо. Это то, о чем я предупреждал вас в первую очередь - и это означает, что все изображения, которые вы сохранили в своей БД, являются полным мусором.
Видеть здесь:
https://www.codeproject.com/Tips/465950/Why-do-I-get-a-Parameter-is-not-valid-exception-wh
Код написан на C#, а не на VB, но его легко понять или использовать онлайн-конвертер.

Sh.Zakria

Это нормально, так как у меня есть только одно имя пользователя и фотография профиля в моей базе данных, потому что это тестовый проект.

OriginalGriff

Не имеет значения-всегда предполагайте, что он будет "жить" и кодировать соответствующим образом.
Таким образом, вы приобретаете привычку делать это правильно, а не плохо - и гораздо труднее избавиться от плохой привычки, чем от хорошей!
Кроме того, вам нужно проверить весь остальной код - одна конкатенация, и ваш лучший помощник может удалить вашу БД, просто набрав текстовое поле.

Рейтинг:
0

Sunasara Imdadhusen

Вы не можете напрямую назначить байтовый массив объекту изображения. Сначала вы должны преобразовать байтовый массив в объект изображения, а затем вы можете это сделать.
ниже приведено решение: C# vresion

byte[] data = (byte[]) dt.Rows(0)(8);
using (MemoryStream ms = new MemoryStream(data ))
{
pictureBox1.Image = Image.FromStream(ms);
}


Vb.Net версия:
Dim data As Byte() = DirectCast(dt.Rows(0)(8), Byte())
Using ms As New MemoryStream(data)
	pictureBox1.Image = Image.FromStream(ms)
End Using

С уважением,
Имдадхусен


Sh.Zakria

Когда я вставляю этот код в свою программу прямо под txtFinish.Text = DT. Rows (0) (7), слова byte и memoryStream подчеркнуты синим цветом. Должен ли я переводить ваш код в оператор visual basic?

Sunasara Imdadhusen

я добавил vb.net стиль кода, Вы можете использовать этот. если Ссылка недоступна в проекте, то необходимо добавить ссылку approvpriate из проекта.

Sh.Zakria

Имя picturebox1.Образ = Образ.FromStream (ms) - - - параметр недопустим.

Sunasara Imdadhusen

Проверьте эту ссылку для получения дополнительной информации http://net-informations.com/q/faq/imgtobyte.html