Работа с изображениями в Microsoft Access (97, 2000, 2003)


Возникла задача хранения (загрузка, отображение) картинок (фотографий и т.п.) в базе данных Access.

На первый взгляд опытного программиста ;-) нет ничего проще - картинки храним в поле таблицы с типом Поле объекта OLE (OLE Object), а отображаем на формах при помощи элемента управления Присоединенная рамка объекта, ну или если потребуется Свободная рамка объекта (Bound Object Frame, Unbound Object Frame). Но не тут-то было!; Оказалось, что если данные записать напрямую (в коде Visual Basic), например, используя метод AppendChunk, в поле с типом Поле объекта OLE, то в элементе управления Присоединенная рамка объекта изображение вот так вот просто не отображается. Отображается же оно только в том случае, если загрузить данные в это поле при помощи контекстного меню самого поля или указанного элемента управления, выбрав правильный тип OLE объекта (что-нибудь типа Рисунок, Picture...). Такая гибкость и умность обработки данных не особо устраивала.

А элемент управления с манящим типом Рисунок (Image) предназначен для работы исключительно со статическими изображениями: на этапе дизайна (ну, в общем-то, и из кода Visual Basic) можно указать файл на диске, который будет отображаться на форме.

Изучив БД примеров - Northwind в английской версии, Борей в русской - и изрядно просканировав интернет, стало понятно, что отсутствие нормальной работы с изображениями в Access'е - общепризнанный факт. Вариантов предлагается два:

  1. Хранение картинок в виде файлов на диске, а пути к ним - в БД. Отображение на форме при помощи элемента управления Рисунок (Image), присваивая путь в качестве значения свойству Рисунок (Picture)

  2. Хранение картинок в БД в полях Поле объекта OLE (OLE Object). Аналогичное отображение на форме при помощи элемента управления Рисунок (Image). При этом для загрузки файла используется метод AppendChunk, а чтобы отобразить картинку данные выгружаются во временный файл методом GetChunk, путь к полученному файлу присваивается свойству Рисунок (Picture) элемента управления. Этот метод дан с примером здесь.

Минус первого метода в том, что при перемещении каталога хранения файлов должны быть в обязательном порядке корректно изменены пути к файлам, сохраненные в БД. Минусы второго метода - нужно придумать как добиться уникальности имени временного файла (так как теоретически с БД могут работать несколько пользователей "из одного и того же места"), и прямая работа с файлами на диске всё-таки замедляет работу. И оба этих метода не подходят для использования в Ленточной форме (Continuous Forms), а только в Одиночной форме (Single Form).

Уже склонившись ко 2-ому варианту, как более приемлемому, промелькнула мысль - а не попробовать ли использовать элемент управления Рисунок (Image) не только для отображения, но и для преобразования данных в нужный графический формат, использовав свойство PictureData объекта Image?! И это сработало! Не нужны никакие временные файлы (хотя, конечно для Ленточной формы это всё равно не подходит, но это и не критично).

Итак, идея в том, что загрузка файла осуществляется присвоением пути к нему свойству Picture элемента управления Рисунок (Image), и последующим считыванием данных из свойства PictureData - таким образом мы добиваемся, что данные буду сохранены в формате, который Access гарантированно отобразит. А отображение картинки выполняется считыванием данных из поля с типом Поле объекта OLE (OLE Object) и их присвоением свойству PictureData элемента управления.

  Пример.

Пусть у нас в таблице MyTable есть поле MyImage типа Поле объекта OLE (OLE Object). На форме MyForm нам нужен элемент управления Рисунок (Image) - MyPic. При этом, чтобы разместить этот элемент управления на форме, нужно обязательно выбрать рисунок, а потом в дизайнере в свойстве Рисунок (Picture) указать (отсутствует) ((none)) - со скобками. На вопрос об удалении рисунка - ответить утвердительно.

Загрузку можно выполнить примерно так:

'====================================================
Dim rs As Recordset
Dim dlgFile As FileDialog, strFilePath As String

Set dlgFile = Application.FileDialog(msoFileDialogOpen)

dlgFile.AllowMultiSelect = False
dlgFile.Filters.Clear
dlgFile.Filters.Add "Все файлы", "*.*"
dlgFile.Filters.Add "JPEG", "*.jpg"
dlgFile.Filters.Add "Рисунки", "*.bmp"
dlgFile.FilterIndex = 1
If dlgFile.Show = 0 Then
   Set dlgFile = Nothing
   Exit Sub
End If

strFilePath = Trim$(dlgFile.SelectedItems(1))
Set dlgFile = Nothing

MyPic.Picture = strFilePath

Set rs = CurrentDB.OpenRecordset("MyTable", dbOpenDynaset)

rs.AddNew
rs![MyImage] = MyPic.PictureData
rs.Update

MyPic.Picture = "" 'очистка картинки, если нужно
'====================================================

А отображение выполнять так (например, в обработчике события Текущая запись (On Current)):

'====================================================
If Me.NewRecord Then
   MyPic.Picture = ""
Else
   MyPic.PictureData = Me![MyImage]
End If
'====================================================


Нашёл что искал.спасибо автору.С уважением,spawnet

Нашёл что искал.
спасибо автору.С уважением,spawnet.

Нравится