powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Как заставить PictureBox отображать картинку полученую с SQL сервера
22 сообщений из 22, страница 1 из 1
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #32409210
Rafael
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В примерах SQL серевера нашел вот такой код:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
                    FileNumber = FreeFile
                    Open TempFile For Binary Access Write As FileNumber
                    Totalsize = FieldSize - HeaderSize
                    byteChunk() = fld.GetChunk(HeaderSize)      
                    NumOfChuncks = Totalsize \ ChunkSize
                    Remainder = Totalsize Mod ChunkSize
                    If Remainder >  0  Then
                        byteChunk() = fld.GetChunk(Remainder)
                        Put FileNumber, , byteChunk()
                    End If
                    Offset = Remainder
                    Do While Offset < Totalsize
                        byteChunk() = fld.GetChunk(ChunkSize)
                        Put FileNumber, , byteChunk()
                        Offset = Offset + ChunkSize
                    Loop
                    Close FileNumber
                    Image1.Picture = LoadPicture(TempFile)
                    Kill (TempFile)


Но что-то мне подсказывает, что должен быть короткий путь :), более элегантный...
И как в поле image записть картинку (например из файла), что-то как я не стараюсь, он мне пишет несоответствие типов.
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #32409537
Hibernate
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот тебе по-короче, но без сливания в файл :-)))
код не мой - выдрал где-то, не помню где, но работает стабильно во многих проектах. Забытому мною автору - отдельное спасибо.
в модуль добавляешь
Код: plaintext
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.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
Option Explicit

Private Declare Function GlobalAlloc Lib  "kernel32"  ( _
  ByVal wFlags As Long, _
  ByVal dwBytes As Long) As Long

Private Declare Function GlobalLock Lib  "kernel32"  ( _
  ByVal hMem As Long) As Long

Private Declare Function GlobalUnlock Lib  "kernel32"  ( _
  ByVal hMem As Long) As Long

Private Declare Function CreateStreamOnHGlobal Lib  "ole32"  ( _
   ByVal hGlobal As Long, _
   ByVal fDeleteOnRelease As Long, _
   ppstm As IStream) As Long

Private Declare Function GetHGlobalFromStream Lib  "ole32"  ( _
  ByVal pstm As IStream, _
  phglobal As Long) As Long

Private Declare Function GlobalSize Lib  "kernel32"  ( _
  ByVal hMem As Long) As Long

Const PictureID = &H746C&
Const S_OK =  0 

' Global Memory Flags
Const GMEM_MOVEABLE = &H2
Const GMEM_ZEROINIT = &H40

Const GHND = (GMEM_MOVEABLE Or GMEM_ZEROINIT)

Private Type PictureHeader
   Magic As Long
   Size As Long
End Type

Public Function Array2Picture(aBytes() As Byte) As StdPicture
Dim oIPS As IPersistStream
Dim oStream As IStream, hGlobal As Long, lPtr As Long
Dim lSize As Long, Hdr As PictureHeader
Dim lRes As Long

   ' Create a new empty
   ' picture object
   Set Array2Picture = New StdPicture
   
   ' Get the IPersistStream interface
   Set oIPS = Array2Picture
   
   ' Calculate the array size
   lSize = UBound(aBytes) - LBound(aBytes) + 1
   
   ' Allocate global memory
   hGlobal = GlobalAlloc(GHND, lSize + Len(Hdr))
   
   If hGlobal Then
   
      ' Get a pointer to the memory
      lPtr = GlobalLock(hGlobal)
      
      ' Initialize the header
      Hdr.Magic = PictureID
      Hdr.Size = lSize
      
      ' Write the header
      MoveMemory ByVal lPtr, Hdr, Len(Hdr)
      
      ' Copy the byte array to
      ' the global memory
      MoveMemory ByVal lPtr + Len(Hdr), aBytes(0), lSize
      
      ' Release the pointer
      GlobalUnlock hGlobal
      
      ' Create a IStream object
      ' with the global memory
      lRes = CreateStreamOnHGlobal(hGlobal, True, oStream)
   
      If lRes = S_OK Then
   
         ' Load the picture
         ' from the stream
         oIPS.Load oStream
               
      End If
      
      ' Release the IStream
      ' object
      Set oStream = Nothing
   
   End If

End Function

Public Sub Picture2Array(ByVal oObj As StdPicture, aBytes() As Byte)
Dim oIPS As IPersistStream
Dim oStream As IStream, hGlobal As Long, lPtr As Long
Dim lSize As Long, Hdr As PictureHeader
Dim lRes As Long

   ' Get the IPersistStream interface
   Set oIPS = oObj
   
   ' Create a IStream object
   ' on global memory
   lRes = CreateStreamOnHGlobal(0, True, oStream)
   
   If lRes = S_OK Then
   
      ' Save the picture in the stream
      oIPS.Save oStream, True
      
      ' Get the global memory handle
      ' from the stream
      If GetHGlobalFromStream(oStream, hGlobal) = S_OK Then
      
         ' Get the memory size
         lSize = GlobalSize(hGlobal)
         
         ' Get a pointer to the memory
         lPtr = GlobalLock(hGlobal)
         
         If lPtr Then
         
            lSize = lSize - Len(Hdr)
            
            ' Redim the array
            ReDim aBytes(0 To lSize - 1)
                                             
         
            ' Copy the data to the array
            MoveMemory aBytes( 0 ), ByVal lPtr + Len(Hdr), lSize
         
         End If
         
         ' Release the pointer
         GlobalUnlock hGlobal
         
      End If
      
      ' Release the IStream
      ' object
      Set oStream = Nothing
   
   End If

End Sub

в референсах ставишь ссылку на STG.tlb

запихиваем картинку в сервер:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Dim d() As Byte
Dim p As AdoDB.Parameter
Dim cm As AdoDB.Command

Picture2Array(imgUserPhoto.Picture, d())

Set p = cm.CreateParameter( "UserPhoto" , adVarBinary, adParamInput)
p.Size = UBound(d()) - LBound(d()) +  1 
p.AppendChunk (d())
cm.Parameters.Append p


Получаем картинку из сервера:
Код: plaintext
1.
2.
3.
4.
  With rs
    If Not IsNull(.Fields( "UserPhoto" )) Then
      Set imgUserPhoto.Picture = Array2Picture(.Fields( "UserPhoto" ).GetChunk(.Fields( "UserPhoto" ).ActualSize))
    End If
  End With
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36370764
Joni_5
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hibernateв референсах ставишь ссылку на STG.tlb

А это откуда брать у меня такого не то что в референсах, на компе в принципе нет!
или я что-то недопонял о_О
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36390034
Hibernate
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
оставь адрес - зашлю, если ты еще не нашел в нете.
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36390043
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hibernateоставь адрес - зашлю, если ты еще не нашел в нете.

и мне, и мне
мыло в профиле

спасибо
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36390489
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно обойтись без (вообще или нестандартных) библиотек типов. Здесь три подзадачки:
1) получение данных из источника и формирование на них COM-объекта, поддерживающего интерфейс IStream. Например, можно положить полученные (из файла или поля источника) данные в байтовый массив и применить функцию CreateStreamOnHGlobal(), как в данной теме, или воспользоваться тем, что ADODB.Stream реализует интерфейс IStream;
2) декодирование данных из IStream и получение раскодированного изображения. Например, можно использовать функцию OLE-библиотеки OleLoadPicture() или библиотеки GDI+ GdipLoadImageFromStream();
3) отображение раскодированного изображения на устройстве отображения. Здесь варианты зависят от формата и устройства, например, для отображения в PictureBox можно просто взять COM-объект, поддерживающий интерфейс IPicture, полученный от OleLoadPicture() и передать ссылку на него в PictureBox через Property Set Picture.

Пример.

Впрочем, существуют и другие варианты, например Intel JPEG Library может брать данные из памяти по указателю, IStream не надо создавать. Но для этого надо тащить с exe-шником библиотечную DLL.
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36390510
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БенедиктМожно обойтись без (вообще или нестандартных) библиотек типов. Здесь три подзадачки:

А можно, если вам не сложно, конкретизировать пример для варианта ADO. А то как-то совершенно не приходилось работать с потоками :(
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36473492
Pelican
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shocker.Pro,

Вот тебе пример
С англицким, надеюсь, проблем нету? :)
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36473501
Pelican
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот , кстати, ещё интересная инфа...
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36473589
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PelicanShocker.Pro,

Вот тебе пример
С англицким, надеюсь, проблем нету? :)

гм.
Если я правильно понял - этот пример использует сохранение в файл на диск и последующую загрузку. В принципе, это можно сделать и без стрима. Я же хотел бы перегружать картинку из базы прямо в ImageList или PictureBox МИНУЯ файловую систему, ибо при большом количестве маленьких картинок дисковая операция занимает заметное время (это я уже пробовал).
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36473961
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,

Возни с ADO-шным потоком больше, чем с массивом, а выгоды не просматриваются (если делать свою реализацию IStream, то можно получить хоть что-то, вроде индикатора прогресса загрузки и кнопки остановки).

Пусть есть форма, кнопка, PictureBox.

Для загрузки через массив:
Код: plaintext
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.
'В модуле формы
Private Function CheckShowPicParams(ByVal oField As ADODB.Field, _
                                    ByVal oPicBox As PictureBox) As Boolean
'необязательная функция проверки параметров
 If oField Is Nothing Then Exit Function
 If oPicBox Is Nothing Then Exit Function
 If oField.Type <> adLongVarBinary Then Exit Function
 If oField.ActualSize <=  0  Then Exit Function
 CheckShowPicParams = True
End Function

Private Sub ShowPic1(ByVal oField As ADODB.Field, ByVal oPicBox As PictureBox)
 If Not CheckShowPicParams(oField, oPicBox) Then Exit Sub
 
 Dim bBuf() As Byte
 bBuf = oField.Value 'длинный двоичный объект в байтовый массив
 
 Set oPicBox.Picture = LoadPictureUsingStream(bBuf) 'функция из примера по ссылке выше
End Sub

Private Sub Command1_Click()
 'тестовая процедура
 Dim rs As ADODB.Recordset
 Set rs = New ADODB.Recordset
 rs.Open <параметры>
 ShowPic1 rs(<имя или индекс поля>), Picture1
 rs.Close
End Sub
Для загрузки через ADODB.Stream (один из вариантов):
Код: plaintext
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.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
Private Type GUID
   Data1 As Long
   Data2 As Integer
   Data3 As Integer
   Data4( 0  To  7 ) As Byte
End Type

Private Declare Function OleLoadPicture Lib "olepro32" ( _
   ByVal pStream As IStream, ByVal lSize As Long, _
   ByVal fRunmode As Long, riid As GUID, ppvPic As IPictureDisp) As Long

Private Sub ShowPic2(ByVal oField As ADODB.Field, ByVal oPicBox As PictureBox)
 If Not CheckShowPicParams(oField, oPicBox) Then Exit Sub
 
 'Перевод значения поля в поток ADO
 Dim stmAdo As ADODB.Stream
 Dim stmI As IStream
 Set stmAdo = New ADODB.Stream
 stmAdo.Type = adTypeBinary
 stmAdo.Open
 stmAdo.Write oField.Value
 stmAdo.Position =  0 
 Set stmI = stmAdo 'основная сложность здесь
 
 Dim picDst As IPictureDisp
 Dim lResult As Long
 Dim IID_IDispatch As GUID
 With IID_IDispatch
    .Data1 = &H20400
    .Data4( 0 ) = &HC0
    .Data4( 7 ) = &H46
 End With
 lResult = OleLoadPicture(stmI, oField.ActualSize,  1 , IID_IDispatch, picDst)
 Set stmI = Nothing
 stmAdo.Close
 Set stmAdo = Nothing
 
 Set oPicBox.Picture = picDst
End Sub
Здесь используется тип IStream, описанный во внешней библиотеке типов. Её можно написать самому, или можно взять готовую ( здесь первая ссылка, её то ли часть, то ли предыдущая версия - STG.tlb, упоминающаяся в начале темы). Можно обойтись и без неё, но придётся написать (не самую тривиальную) функцию для получения ссылки на IStream из ссылки на ADODB.Stream (или применить грязный хак, сравнив ObjPtr(stmI) и ObjPtr(stmAdo) и сделав выводы).
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36474920
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БенедиктShocker.Pro,

Возни с ADO-шным потоком больше, чем с массивом, а выгоды не просматриваются

Для загрузки через массив:

Ага, вроде то, что я хотел, НО.
Решил попробовать и тут возник вопрос - а в каком виде картинка должна быть в базе? Ведь если я просто положу туда файл какого-то формата, он же будет снабжен какими-то заголовками и т.п. А тут же прямое присваивание свойства Picture, без всякого LoadFromFile....
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36475392
AndrF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProБенедиктShocker.Pro,
Для загрузки через массив:

Ага, вроде то, что я хотел, НО.
Решил попробовать и тут возник вопрос - а в каком виде картинка должна быть в базе? Ведь если я просто положу туда файл какого-то формата, он же будет снабжен какими-то заголовками и т.п. А тут же прямое присваивание свойства Picture, без всякого LoadFromFile....

Я тут приложил свой старенький тестовый примерчик...

В нем вас интересует функция LoadPictureFromBytes . Ну и остальные может пригодятся...
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36476252
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndrFЯ тут приложил свой старенький тестовый примерчик...

В нем вас интересует функция LoadPictureFromBytes . Ну и остальные может пригодятся...

Честно говоря, я не понял, что с ней сделать.
Там идет работа с файлами, а у меня как раз вопрос, как файлы миновать
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36476500
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProРешил попробовать и тут возник вопрос - а в каком виде картинка должна быть в базе? Ведь если я просто положу туда файл какого-то формата, он же будет снабжен какими-то заголовками и т.п. В общем случае - в том, что понимает функция декодирования. Стандартные функции берут стандартные форматы, например, OleLoadPicture() берёт BMP, GIF, JPEG, a GdipLoadImageFromStream() берёт BMP, GIF, JPEG (расширенная поддержка), TIFF, PNG. То есть в длинное двоичное поле в базе надо класть содержимое файла без "заголовков и т.п."Shocker.ProА тут же прямое присваивание свойства Picture, без всякого LoadFromFile....Ну, относительно прямое:
PictureBox <- IPicture(Disp) <- функция декодирования <- IStream <- массив <- поле.
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36476944
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БенедиктВ общем случае - в том, что понимает функция декодирования. Стандартные функции берут стандартные форматы, например, OleLoadPicture() берёт BMP, GIF, JPEG

То есть, если я правильно понял, формат будет определен по содержимому файла автоматически и никому рассказывать особым образом, что это BMP или JPG - не требуется... Ок, попробую.
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36477197
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,

да.
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36477797
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БенедиктShocker.Pro,

да.

Не, Бенедикт, что-то не едут у меня лыжи, выдернул пример:
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36478995
Фотография Бенедикт
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,

тут по ходу пара лыж едущих уже была, но пусть будет ещё одна
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
X = FreeFile
'FileLen FileName 'С первого взгляда бессмыслица. Служит для проверки существования файла
Open FileName For Binary Access Read Shared As #X

'Dim bFile() As Byte
'bFile = InputB(FileLen(FileName), #X)
ReDim bFile( 0  To LOF(X) -  1 ) As Byte
Get #X, , bFile
Close #X
'tm.Fields.Append "File", adBSTR
tm.Fields.Append "File", adLongVarBinary, - 1 
tm.Open
tm.AddNew
'tm("File") = Input(FileLen(FileName), #X)
tm("File") = bFile
tm.Update
'Close #X
Erase bFile
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36479139
AndrF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProAndrFЯ тут приложил свой старенький тестовый примерчик...

В нем вас интересует функция LoadPictureFromBytes . Ну и остальные может пригодятся...

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

Что тут непонятного - я даже название функции указал, которая возвращает Picture из байтового массива. А откуда ты возьмешь этот массив - из файла или поля базы данных твое дело...
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36480344
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гм.
Выяснилось, что проблема в том, как программер кривыми ручонками написал код для хранения файлов в БД (фрагмент этого кода я как раз привел в примере). А так как он криво написал и сохранение и извлечение, то "плюс криво" на "минус криво" давало на выходе нормальный файл.

Так что начну с переделки его кода и "переоприходования" файлов в БД а потом вернусь к функции, я думаю, что она заработает. AndrF, Бенедикт - спасибо за терпение, отчитаюсь позже.
...
Рейтинг: 0 / 0
Как заставить PictureBox отображать картинку полученую с SQL сервера
    #36487896
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблема была неправильном типе BLOB-поля на сервере и неявных преобразованиях VB, а именно - при прямом присвоении байтовому массиву текстового поля, оно испытывает преобразование (по всей видимости в юникод), длина массива становится в два раза больше, чем длина поля.

В общем, все работает, спасибо еще раз.
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Как заставить PictureBox отображать картинку полученую с SQL сервера
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]