О том как добавлять текстовую информацию, я писал в соответствующем посте. Но как добавить картинку? И какие в связи с этим могут возникнуть трудности? Частично добавление картинок было рассмотрено в посте про DataControls в разделе DBImage.
ДЛЯ БОЛЬШИНСТВА ФОРМАТОВ
Ссылку на класс TWICImage мне отправил пользователь под ником RIUS, эта информация добавлена чуть позже, чем я написал основной пост, но мне она показалась интересной, потому что позволяет работать с большинством форматов (единственное, пока не разобрался с PNG, с прозрачными слоями)…
Итак, знакомьтесь, класс TWICImage – позволяет обрабатывать BMP, JPEG, TIFF, PNG и др. популярные форматы…
Ещё полезная ссылка по данному классу.
Как добавить изображение в БД, используя класс TWICImage ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
procedure TMainForm.Button8Click(Sender: TObject); var bmp:tbitmap; W:TWICImage; begin bmp:=tbitmap.Create; W:=TWICImage.Create; MS:=TMemorystream.Create; OpenPictureDialog1.Execute; w.LoadFromFile(OpenPictureDialog1.FileName); bmp.Assign(w); simpledataset1.Insert; SimpleDataset1.FieldByName('Picture').Assign(bmp); simpledataset1.Post; simpledataset1.ApplyUpdates(-1); simpledataset1.Refresh; w.Free; MS.Free; end; |
Ниже Вы найдете информацию о “стандартных” способах добавления картинок в БД и чтения из БД. TWICImage я поставил наверх, потому что он, на мой взгляд, более универсальный.
ДОБАВЛЕНИЕ / ЧТЕНИЕ ЧЕРЕЗ TMemoryStream (Подходит для BMP,JPEG и др. НО НЕ PNG)
C BMP, JPEG такой трюк хорошо пройдет, только для JPEG надо подключить в uses модуль JPEG; C PNG трабл в том, что, при наличии прозрачного слоя – возникает черный фон. Как это победить, пока не придумал ((
Как сохранить изображение в БД?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
procedure TMainForm.Button4Click(Sender: TObject); var MS:TMemorystream; begin OpenPictureDialog1.Execute; MS:=TMemoryStream.Create; MS.LoadFromFile(OpenPictureDialog1.FileName); simpledataset1.Insert; TBlobfield(SimpleDataset1.FieldByName('Picture')).LoadFromStream(MS); simpledataset1.Post; simpledataset1.ApplyUpdates(-1); simpledataset1.Refresh; // Button 4click... end; |
Как прочитать изображение из БД?
Самое простое – в компонент DBImage, предварительно выставив свойства (например в FormCreate…)
1 2 3 4 5 |
with DBImage1 do begin Datasource:=Datasource1; Datafield:='Picture'; end; |
2 способ – загрузка изображения в компонент image из BLOB поля БД…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
procedure TMainForm.Button6Click(Sender: TObject); var MS:TMemorystream; begin if (simpledataset1.FieldByName('Picture') as tblobField).IsNull then exit; MS:=TMemorystream.Create; (simpledataset1.FieldByName('Picture') as tblobField).SaveToStream(MS); MS.Position:=0; image2.Picture:=nil; // Если не занулить будет ошибка image2.Picture.bitmap.LoadFromStream(MS); end; |
ДОБАВЛЕНИЕ / ЧТЕНИЕ ЧЕРЕЗ ASSIGN (Подходит для BMP,JPEG и др. НО НЕ PNG)
Как записать изображение в БД через Assign ?
(на примере записи в базу jpeg)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
procedure TMainForm.Button8Click(Sender: TObject); var bmp:tbitmap; jpeg:tjpegimage; begin bmp:=tbitmap.Create; jpeg:=tjpegimage.Create; OpenPictureDialog1.Execute; jpeg.LoadFromFile(OpenPictureDialog1.FileName); bmp.Assign(jpeg); simpledataset1.Insert; SimpleDataset1.FieldByName('Picture').Assign(bmp); simpledataset1.Post; simpledataset1.ApplyUpdates(-1); simpledataset1.Refresh; end; |
Как прочитать изображение в БД через Assign ?
1 2 3 4 5 6 7 8 9 10 11 |
procedure TMainForm.Button6Click(Sender: TObject); var bmp:TBitmap; begin bmp:=tbitmap.Create; bmp.Assign(simpledataset1.FieldByName('Picture')); image2.Picture.Assign(bmp); end; |
ТРАБЛ С PNG
Если применить эти методы к файлам формата PNG, то при наличии прозрачного слоя у меня возникал черный фон.
Как это победить – на настоящий момент – не знаю. Одинаковая картина – если отображать на DBImage и на Image. Причём, если PNG отображать на форме простой загрузкой файла (не через сохранение в БД и последующего чтения), то PNG отображается при этом нормально…
Возможно поможет функция Scanline, но за 1,5 дня безуспешных попыток – готового решения не получилось. Написал о проблеме на форуме, но пока тишина…
Думаю попробовать использовать 4 байт, который предназначен для Альфа канала. Довольно хорошая статья по сканлайн находится здесь.
И ещё одна статья по skyline на английском – достаточно подробная. В общем, надо разбираться в вопросе…
Но надо экспериментировать дальше…
Если у Вас есть готовое решение, пожалуйста, напишите мне на почту panteleevstas@gmail.com
Решение найдено!
Дело в том, что компонент DBImage – не поддерживает прозрачность. А Image – поддерживает.
Итак, чтобы отображать рисунки с прозрачностью, нужно загружать их в Image следующим образом…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
procedure TForm1.Button6Click(Sender: TObject); var bmp:tbitmap; begin bmp:=tbitmap.Create; // bmp.PixelFormat := pf32Bit; // bmp.HandleType := bmDIB; bmp.alphaformat := afDefined; //<<<<< Это критическая строчка для решения проблемы!!!! bmp.Assign(simpledataset1.FieldByName('Picture')); bmp.Transparent:=true; image1.Picture.Assign(bmp); end; |