



- Код: Выделить всё
SetDIBitsToDevice Me.hdc, 0, 0, bi24BitInfo.bmiHeader.biWidth, bi24BitInfo.bmiHeader.biHeight, 0, 0, 0, bi24BitInfo.bmiHeader.biHeight, bBytes(1), bi24BitInfo, DIB_RGB_COLORS


Demonx писал(а):А если я не знаю высоту и ширину картинки? Как быть? Есть байтовый массив и всё. Можно поконкретней пример?
Private Declare Function CLSIDFromString Lib "ole32" (ByVal lpsz As Any, pclsid As GUID) As Long
Private Declare Function IsEqualGUID Lib "ole32" (rguid1 As GUID, rguid2 As GUID) As Boolean
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal dwLength As Long)
Private Declare Function CreateStreamOnHGlobal Lib "ole32" (ByVal hGlobal As Long, ByVal fDeleteOnRelease As CBoolean, ppstm As Any) As Long
Private Const GMEM_MOVEABLE = &H2
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal uFlags 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 GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
Private Enum CBoolean   ' enum members are Long data types
    CFalse = 0
    CTrue = 1
End Enum
Private Type GUID       ' 16 bytes (128 bits)
    dwData1 As Long     ' 4 bytes
    wData2 As Integer   ' 2 bytes
    wData3 As Integer   ' 2 bytes
    abData4(7) As Byte  ' 8 bytes, zero based
End Type
Private Declare Function OleLoadPicture Lib "olepro32" (pStream As Any, ByVal lSize As Long, ByVal fRunmode As CBoolean, riid As GUID, ppvObj As Any) As Long
Public Function PictureFromBits(abPic() As Byte) As IPicture  ' not a StdPicture!!
    Const sIID_IPicture = "{7BF80980-BF32-101A-8BBB-00AA00300CAB}"
    Const S_OK = 0     ' indicates successful HRESULT
    
    Dim nLow As Long
    Dim cbMem  As Long
    Dim hMem  As Long
    Dim lpMem  As Long
    Dim IID_IPicture As GUID
    Dim istm As stdole.IUnknown '  IStream
    Dim ipic As IPicture
    
    ' Get the size of the picture's bits
    On Error GoTo Out
    nLow = LBound(abPic)
    On Error GoTo 0
    cbMem = (UBound(abPic) - nLow) + 1
  
    ' Allocate a global memory object
    hMem = GlobalAlloc(GMEM_MOVEABLE, cbMem)
    If hMem Then
        ' Lock the memory object and get a pointer to it.
        lpMem = GlobalLock(hMem)
        If lpMem Then
            ' Copy the picture bits to the memory pointer and unlock the handle.
            MoveMemory ByVal lpMem, abPic(nLow), cbMem
            GlobalUnlock hMem
            ' Create an ISteam from the pictures bits (we can explicitly free hMem
            ' below, but we'll have the call do it here...)
            If (CreateStreamOnHGlobal(hMem, CTrue, istm) = S_OK) Then
                If (CLSIDFromString(StrPtr(sIID_IPicture), IID_IPicture) = S_OK) Then
                    ' Create an IPicture from the IStream (the docs say the call does not
                    ' AddRef its last param, but it looks like the reference counts are correct..)
                    OleLoadPicture ByVal ObjPtr(istm), cbMem, CFalse, IID_IPicture, PictureFromBits
                End If   ' CLSIDFromString
            End If   ' CreateStreamOnHGlobal
        End If   ' lpMem
        GlobalFree hMem
    End If   ' hMem
    
Out:
End Function

Andrey Fedorov писал(а):Demonx писал(а):А если я не знаю высоту и ширину картинки? Как быть? Есть байтовый массив и всё. Можно поконкретней пример?
- Код: Выделить всё
Private Declare Function CLSIDFromString Lib "ole32" (ByVal lpsz As Any, pclsid As GUID) As Long
Private Declare Function IsEqualGUID Lib "ole32" (rguid1 As GUID, rguid2 As GUID) As Boolean
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal dwLength As Long)
Private Declare Function CreateStreamOnHGlobal Lib "ole32" (ByVal hGlobal As Long, ByVal fDeleteOnRelease As CBoolean, ppstm As Any) As Long
Private Const GMEM_MOVEABLE = &H2
...
End Function




Private Declare Function CLSIDFromString Lib "ole32" (ByVal lpsz As Any, pclsid As GUID) As Long
Private Declare Function IsEqualGUID Lib "ole32" (rguid1 As GUID, rguid2 As GUID) As Boolean
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal dwLength As Long)
Private Declare Function CreateStreamOnHGlobal Lib "ole32" (ByVal hGlobal As Long, ByVal fDeleteOnRelease As Long, ppstm As Any) As Long
'Private Const GMEM_FIXED = &H0
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal uFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
Private Type GUID       ' 16 bytes (128 bits)
    dwData1 As Long     ' 4 bytes
    wData2 As Integer   ' 2 bytes
    wData3 As Integer   ' 2 bytes
    abData4(7) As Byte  ' 8 bytes, zero based
End Type
Private Declare Function OleLoadPicture Lib "olepro32" (pStream As Any, ByVal lSize As Long, ByVal fRunmode As Long, riid As GUID, ppvObj As Any) As Long
Public Function PictureFromBits(abPic() As Byte) As IPicture  ' not a StdPicture!!
    Const sIID_IPicture = "{7BF80980-BF32-101A-8BBB-00AA00300CAB}"
    Const S_OK = 0     ' indicates successful HRESULT
    
    Dim nLow As Long
    Dim cbMem  As Long
    Dim lpMem  As Long
    Dim IID_IPicture As GUID
    Dim istm As stdole.IUnknown '  IStream
    Dim ipic As IPicture
    
    ' Get the size of the picture's bits
    On Error GoTo Out
    nLow = LBound(abPic)
    On Error GoTo 0
    cbMem = (UBound(abPic) - nLow) + 1
  
    ' Allocate a global memory object
    lpMem = GlobalAlloc(0, cbMem)
    If lpMem Then
            ' Copy the picture bits to the memory pointer
            MoveMemory ByVal lpMem, abPic(nLow), cbMem
            ' Create an ISteam from the pictures bits (we can explicitly free hMem
            ' below, but we'll have the call do it here...)
            If (CreateStreamOnHGlobal(lpMem, 1, istm) = S_OK) Then
                If (CLSIDFromString(StrPtr(sIID_IPicture), IID_IPicture) = S_OK) Then
                    ' Create an IPicture from the IStream (the docs say the call does not
                    ' AddRef its last param, but it looks like the reference counts are correct..)
                    OleLoadPicture ByVal ObjPtr(istm), cbMem, 0, IID_IPicture, PictureFromBits
                End If   ' CLSIDFromString
            End If   ' CreateStreamOnHGlobal
    End If   ' lpMem
    GlobalFree lpMem
    
Out:
End Function

 
  

kif писал(а):tyomitch
Если не сложно, можно пример как сделать наоборот, т.е. из picture в Array
 



kif писал(а):Мне нужны только эти 2 метода picture2Array и Array2picture. больше ничего. обертка у меня есть, но она весит....


kif писал(а)::-) Может быть.

Так что ты не правhGlobal
[in] Memory handle allocated by the GlobalAlloc function. The handle must be allocated as movable and nondiscardable.



GSerg писал(а):Хм...
Вот ты, ANDLL, сказал об этом... было уж хотел тебе сказать - а позырь, друг мой, внимательно на имя функции CreateStreamOnHGlobal, но таки полез в MSDN на всякий случай...
Так там, Тёмыч, таки написано, чтоТак что ты не правhGlobal
[in] Memory handle allocated by the GlobalAlloc function. The handle must be allocated as movable and nondiscardable.









Option Explicit
Private Const BlockSize = 32768
Function ReadBLOB(Source As String, T As Recordset, sField As String)
    Dim NumBlocks As Integer 'счётчик количества блоков
    Dim SourceFile As Integer
    Dim i As Integer
    Dim FileLength As Long
    Dim LeftOver As Long
    Dim byteData() As Byte
    On Error GoTo Err_ReadBLOB 'если ошибка, то надо перейти на обработчик ошибок
    SourceFile = FreeFile
    Open Source For Binary Access Read As SourceFile 'открытие файла
    'получение длинны файла
    FileLength = LOF(SourceFile)
    If FileLength = 0 Then
    ReadBLOB = 0
    Exit Function
    End If
    'вычисление кол-во блоков, которые будут записаны в базу
    NumBlocks = FileLength \ BlockSize
    LeftOver = FileLength Mod BlockSize 'вычисляем остаток
    If LeftOver > 0 Then 'если есть остаток, то запись из файла в базу
                         'данных с размером остатка
    ReDim byteData(0 To LeftOver - 1) 'изменение массива для считывания данных
    Get SourceFile, , byteData 'считывание данных из файла
    'T.Edit
    T(sField).AppendChunk (byteData) 'запись в базу
    'T.Update
    End If
    'записываем данные блоками, размером BlockSize
    ReDim byteData(0 To BlockSize - 1)
    For i = 1 To NumBlocks 'считывание и запись в базу
    Get SourceFile, , byteData 'считывание данных из файла
    T(sField).AppendChunk (byteData) 'запись в базовое поле
    Next i
    Close SourceFile
    ReadBLOB = FileLength 'возвращение функцией размер записанных данных
    Exit Function
    Err_ReadBLOB:
     ReadBLOB = -Err 'возвращение номера ошибки
    MsgBox Err.Description, , Err.Number 'если нужно - сообщение об ошибке
    Exit Function
    End Function
    Function WriteBLOB(T As Recordset, sField As String, Destination As String)
    Dim NumBlocks As Integer, DestFile As Integer, i As Integer
    Dim FileLength As Long, LeftOver As Long
    Dim byteData() As Byte
    
    On Error GoTo Err_WriteBLOB
    
    'размер записанных данных
    FileLength = T(sField).FieldSize()
    If FileLength = 0 Then
    WriteBLOB = 0
    Exit Function
    End If
    'вычисление количества блоков для записи
    NumBlocks = FileLength \ BlockSize
    LeftOver = FileLength Mod BlockSize
    
    'очистка содержимого файла
    DestFile = FreeFile
    Open Destination For Output As DestFile
    Close DestFile
    'открытие файла
    Open Destination For Binary As DestFile
    
    'если есть остаток, то запись в файл данных из базы с размером остатка
    If LeftOver > 0 Then
    byteData() = T(sField).GetChunk(0, LeftOver)
    Put DestFile, , byteData
    End If
    'запись в файл всех данных, которые остались блоками размером
    ' по BlockSize каждый
    For i = 1 To NumBlocks
    byteData() = T(sField).GetChunk((i - 1) * BlockSize + LeftOver, BlockSize)
    Put DestFile, , byteData
    Next i
    Close DestFile
    WriteBLOB = FileLength
    Exit Function
    Err_WriteBLOB:
    WriteBLOB = -Err
    MsgBox Err.Description, vbCritical, Err.Number
    Exit Function
    End Function
Private Sub Кнопка6_Click()
    ReadBLOB("e:\temp\pictures\table.gif", main, Pict)
End Sub

Функция ReadBlob возвращает количество байт, записанных в базе данных. Source - файл рисунка который, будет записан в базе, T - таблица, или запрос в поле которого будет добавлен файл рисунка, sField - имя Поля, таблицы (Т), для записи данных (в поле с этим именем будет cделана запись).


 
 
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 11