Tein aikani kuluksi pienen ohjelman joka siirtää kuvia tietokantaan. Kun tietokannassa olevan kuvan haluaa tuoda PictureBoxiin, niin onko se pakko kierrättää jonkin väliaikaistiedoston kautta, vai voisiko sen hoitaa jotenkin muuten? Alla pätkä nykyisestä tavasta tuoda kuva PictureBoxiin.
Dim TempFilename As String Dim MyStrm As ADODB.Stream TempFilename = App.Path & "Temp.bmp" Set MyStrm = New ADODB.Stream With MyStrm .Open .Type = adTypeBinary .Write rs.Fields(1).Value 'RecordSet rs include Images .SaveToFile TempFilename, adSaveCreateOverWrite End With Form1.Picture1.Picture = LoadPicture(TempFilename) Kill TempFilename
Varmasti onnistuu. Mikä tietokanta ja mikä on tietotyyppi?
Kanta Access ja kuvat on jpeg tai gif. Kuvat on viety binary Stream:nä kantaan, jossa ne on tallennettu OLE object:in.
Taitaa olla niin että pitää ensin lukea tuo tavara vaikka byte taulukkoon ja pudottaa sitten ole-headeri pois. Sitten pitää pyöräyttää IPicture (muoto joka menee pictureboksiin) Tosin voi olla että tämä onnistuu näin suoraan vain bmp-llä, voit ehkä joutua konvertoimaan välissä nuo giffit ja jpegit bmp-ksi vaikka jollain kuvakirjastolla. Eri kirjastoja (eli dll:iä) on netti pullollaan, mulla on tiedossa http://www.codeproject.com/bitmap/graphicsuite.asp, mutta varmasti muitakin (ja ehkä parempia) löytyy. Eli tartteet vaan jonkun dll:n ja sen konverttifunktion. .NET-versiossa taitaa olla suora tuki jpeg:lli ja giffille. Tai sitten pitää tuo IPicture tehdä eri tavalla, mun pitää vielä vähän tutkia sitä...
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Private Declare Function CreateStreamOnHGlobal Lib "ole32.dll" ( _ ByVal hGlobal As Long, _ ByVal fDeleteOnRelease As Long, _ lpIStream As IUnknown) As Long Private Declare Function OleLoadPicture Lib "oleaut32.dll" ( _ ByVal lpStream As IUnknown, _ ByVal lSize As Long, _ ByVal fRunmode As Long, _ riid As Any, _ lpIPicture As IPicture) As Long 'tämä sitten sinne missä kaivat kuvaa tietokannasta Dim pituus As Long pituus = Rs.Fields(1).ActualSize Dim bKuva() As Byte ReDim bKuva(pituus) bKuva = Rs.Fields(1).Value 'tiputetaan ole-headeri pois (se taitaa olla 78 tavua?) Dim uusi() As Byte ReDim uusi(pituus - 78) Call CopyMemory(uusi(0), bKuva(77), pituus - 78) 'tässä välissä pitäisi varmaan tehdä konvertointi 'bittikartaksi (jos ei ole jo, vaan on jpeg tai gif) '(CLSID) IID_IPICTURE Dim IID_IPicture(3) As Long IID_IPicture(0) = &H7BF80980 IID_IPicture(1) = &H101ABF32 IID_IPicture(2) = &HAA00BB8B IID_IPicture(3) = &HAB0C3000 Dim oStream As IUnknown Dim oPicture As IPicture Call CreateStreamOnHGlobal(VarPtr(uusi(LBound(uusi))), 0, oStream) ' tehdään ole IPicture Dim nResult As Long nResult = OleLoadPicture(oStream, 0, 0, IID_IPicture(0), oPicture) If nResult = 0 Then Set Picture1.Picture = oPicture End If
Taitaa olla niin että sen kuvan pitää olla BMP (bittikartta), WMF (metafile), tai ICO (ikonitiedosto), muuten joudut tekemään tuon konversion välissä.
Jos innostusta riittää niin osoitteesta http://www.ijg.org/ saa C-koodin jpeggiä varten. Sieltä pystyt rakentamaan kirjaston vaikka vb:lle. Oiskohan se ollut just tuo mistä vääsin muistissa tapahtuvaa käsittelyä varten kirjaston yhdessä työpaikassa... Ei vanha enää muista...
Hyvä luoja. Jopas oli kattava vastaus. Kiitoksia. =)
Huomasin vielä tuossa että ehkä helpoimmalla pääsee jos pystyt laittamaan formilles perinteisen Data-kontrollin (siis ei adoa, vaan tuon vanhan Datan, adodc ei taida olla yhteensopiva OLE-kontrollin kanssa) niin jos otat yhteyden tietokantaas ton datan-kontrollin kautta ja laitat vielä ole-kontrollin niin saat tuon datan kautta bindattua kuvan tuohon ole-kontrolliin. Siitä voit sitten kopsata tuon kuvan. Ei mikään elegantti ratkaisu survoa esihistoriallista data-kontrollia, mutta voipi olla että helpoin.
Kaivetaan tämä vanha topicci vielä naftaliinista sen verran, että Data-kontrollin kautta binary-datan sai suoraan PictureBoxiin ilman, että kierrättää ole-objektin kautta. Normaalisti vain määrittelee Data-objektiin DatabaseName:n ja RecordSourcen, sekä PictureBoxiin DataSourcen ja DataFieldin. Muuta ei tarvittu ja kannassa olevat kuvat ovat täysin selattavissa sellaisinaan.
Näköjään vanhat temput on joskus parempia kuin pussillinen uusia. ;)
Aihe on jo aika vanha, joten et voi enää vastata siihen.