IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB 6 et antérieur Discussion :

Comment passer une image présente en buffer mémoire vers PictureBox


Sujet :

VB 6 et antérieur

  1. #1
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut Comment passer une image présente en buffer mémoire vers PictureBox
    Bonjour,

    j'ai un fichier bitmap (.bmp) dans une variable buffer (string) nommé "sBufferImage". (c'est une "image mémoire" du "fichier disque .bmp" qui est présent dans la variable)

    la variable est déclaré de cette façon.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim sBufferImage as String
    Je souhaite faire passer cette bitmat de ma variable buffer dans un picturebox.

    Le seul moyen que j'ai trouvé pour l'instant est de faire une sauvegarde de fichier sur disque puis de relire avec loadpicture

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      iNumFichier = FreeFile
      Open App.Path & "\UneImage.bmp" For Binary Access Write As #iNumFichier
        Put #iNumFichier, 1, sBufferImage
      Close #iNumFichier
      picImageLu.Picture = LoadPicture(App.Path & "\UneImage.bmp")
    Cette solution ne me satisfait pas pour 2 raisons
    - manque de performance; l'écriture et la lecture sur disque sont plus lent qu'un travail direct en mémoire.
    - je trouve que écrire un fichier sur le disque pour le relire aussitôt est un procédé qui ne va pas.


    Je cherche donc un moyen pour effectuer cette opération directement en mémoire.


    J'ai essayé avec :
    1) copymemory (je n'y croyait pas trop)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CopyMemory ByVal ObjPtr(picImageLu.Picture), ByVal StrPtr(sBufferImage), LenB(sBufferImage)
    Et là, scrash vb.
    CopyMemory n'interpréte pas le type de données pour transtyper (c'est beau de réver)
    Donc j'écrase d'autres données et scrach.


    2) avec les api pour le clipboard (OpenClipboard, EmptyClipboard SetClipboardData, CloseClipboard) mais il y a une distinction entre texte (vbCFText=1) et image (vbCFBitmap=2)

    3) J'ai réfléchi avec l'api "OleCreatePictureIndirect" et d'autres qui lui sont associés, mais il faut des handles et ma variable buffer n'en a pas.



    Pour tester et vous mettre en situation vous pouvez utiliser ce code (un bouton, un picturebox)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Private Sub Command1_Click()
    CopieImageSpecial
    End Sub
     
    Sub CopieImageSpecial()
    Dim iNumFichier       As Long
    Dim sBufferImage      As String
    Dim sNomfichierLu     As String
    Dim sNomfichierEcrit  As String
     
    sNomfichierLu = App.Path & "\monimage.bmp" ' mettez un nom de fichier image à vous présent dans le rertoire de l'appli
    sNomfichierEcrit = App.Path & "\Copieimage.bmp"
    ' lecture image (bmp)
    iNumFichier = FreeFile
    Open sNomfichierLu For Binary Access Read As #iNumFichier
    sBufferImage = Input(LOF(1), #iNumFichier) ' contient une "image mémoire" du fichier .bmp
    Close #iNumFichier
     
    ' ici il faudrait la copie mémoire directe pou compléter le picturebox
     
    ' pour test
    ' écriture nouvelle image (bmp) sur disque
    iNumFichier = FreeFile
    Open sNomfichierEcrit For Binary Access Write As #iNumFichier
    Put #iNumFichier, 1, sBufferImage
    Close #iNumFichier
    ' vérif en chargeant le picturebox
    Picture1.Picture = LoadPicture(sNomfichierEcrit)
    ' fin test
     
    End Sub
    Merci à ceux qui ont suivi.
    Si vous avez quelques idées, ou pourquoi pas une solution, c'est avec joie que j'en prendrai connaissance. ()

    Hervé.

  2. #2
    Inactif  

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    4 555
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4 555
    Points : 5 537
    Points
    5 537
    Par défaut
    Bonjour,

    1) pourquoi ne pas travailler directement avec une StdPicture ?

    2) maintenant, si tu as mis cette image dans le clipboard, tu peux également la récupérer sous forme de StdPicture, ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dim monimstd As StdPicture
       Set monimstd = Clipboard.GetData
    ===>> et là ===>> voir ce que j'ai écrit en 1)

    EDIT :
    Preuve de ce dont je te parle en 2)

    2 pictureboxes picture1 et picture2, picture1 n'étant là que pour une mise en presse-papiers (démo) et rien d'autre
    une image dans la propriété picture de picture1
    un bouton de commande command1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Private Sub Command1_Click()
       'cette partie est juste pour mettre quelque chose dans le presse-papier
        Clipboard.SetData Picture1.Picture
     
       'et maintenant on va récupérer ce qui est dans le presse-papier, mais dans une stdpicture
       Dim monimstd As StdPicture
       Set monimstd = Clipboard.GetData
     
       ' voyons si on peut se servir de cette stdpicture, en l'envoyant pers picture2
     
       Picture2.Picture = monimstd
    End Sub
    et (bien entendu), tu peux travailler avec la stdPicture comme tu l'entends (transformations, etc...) avant de l'envoyer dans picture2.picture

    Il reste que je ne comprends pas pourquoi tu ne prends pas directement en StdPicture ton fichier bmp (pas besoin de passer par le presse-papiers !!!)

  3. #3
    Membre expert
    Avatar de Delbeke
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    2 675
    Détails du profil
    Informations personnelles :
    Âge : 70
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 2 675
    Points : 3 696
    Points
    3 696
    Par défaut
    Il y a quelques temps, j'ai rouvé ce code sur internet, je suis désolé de ne pouvoir indiquer ni l'auteur ni ou j'ai eu ce code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Option Explicit
    Public Enum CBoolean
      cFalse = 0            ' 0&
      cTrue                 ' 1&
    End Enum
    Private Const sIID_stdPicture = "{7BF80980-BF32-101A-8BBB-00AA00300CAB}"
    Private Const GMEM_MOVEABLE = &H2
    Private Const S_OK = &H0
    Private Const NOERROR = 0
    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 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 Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
            Destination As Any, _
            Source As Any, _
            ByVal Length As Long)
    Private Declare Function CreateStreamOnHGlobal Lib "ole32" _
            (ByVal hGlobal As Long, _
            ByVal fDeleteOnRelease As CBoolean, _
            ppstm As Any) As Long
    Private Declare Function CLSIDFromString Lib "ole32" ( _
            ByVal lpsz As Any, _
            pclsid As GUID) As Long
    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
     
    Private Function PicFromBitsB(bData() As Byte) As StdPicture
      On Error GoTo Errored
      Dim lReturn As Long               'long return value
      Dim lSize As Long                 'long size of byte array
      Dim hMem  As Long                 'handle to allocated memory
      Dim lpMem  As Long                'long pointer to allocated memory
      Dim CLSID_stdPicture As GUID        'Class Identifier for stdPicture
      Dim oIStream As stdole.IUnknown   'IStream Oject
      'get data size
      lSize = (UBound(bData) - LBound(bData)) + 1
      If lSize = 0 Then
        Set PicFromBitsB = Nothing
        Exit Function
      End If
      'allocate global memory object and return handle
      hMem = GlobalAlloc(GMEM_MOVEABLE, lSize)
      If hMem = 0 Then GoTo Errored
      'lock the memory by handle and return pointer to it
      lpMem = GlobalLock(hMem)
      If lpMem = 0 Then GoTo Errored
      'copy the picture data to the memory and unlock the handle
      CopyMemory ByVal lpMem, bData(LBound(bData)), lSize
      Call GlobalUnlock(hMem)
      'create an IStream object from the pic data
      lReturn = CreateStreamOnHGlobal(hMem, cTrue, oIStream)
      If lReturn <> S_OK Then GoTo Errored
      'convert our stdPicture string to GUID
      lReturn = CLSIDFromString(StrPtr(sIID_stdPicture), CLSID_stdPicture)
      If lReturn <> NOERROR Then GoTo Errored
      'create an stdPicture object from IStream and return PicFromBits as pointer
      lReturn = OleLoadPicture(ByVal ObjPtr(oIStream), lSize, cFalse, CLSID_stdPicture, PicFromBitsB)
      If lReturn <> S_OK Then GoTo Errored
    Errored:
        'clean up if needed
        If hMem <> 0 Then GlobalFree (hMem)
    End Function
    J'espère que ce code pourra t'aider
    Et je présente mes excuses au développeur qui créé ce code

  4. #4
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Merci pour vos réponses

    Désolé ucfoutu, j'ai du mal m'exprimer.
    Citation Envoyé par rv26t Voir le message
    une variable buffer (string) nommé "sBufferImage".
    A la base je n'ai pas une image mais une chaîne de caractère qui contient la copie mémoire du fichier bitmap (.bmp) sur disque.
    Dans l'exemple que je donne pour tester et se mettre en situation. la première partie ne sert qu'à remplir la variable d'une façon simple.

    si je place la variable "sBufferImage" dans le clipboard c'est du texte : (IsClipboardFormatAvailable=vbCFText) est vrai, donc la copie vers le picturebox plante.


    Merci Delbeke, je vais étudier ce bout de code.
    Je vous tient au courant.
    A+, Hervé

  5. #5
    Modérateur

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 722
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 722
    Points : 5 100
    Points
    5 100
    Par défaut
    Encore merci Delbeke, cette fonction correspond tout à fait à mes attentes.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 7
    Dernier message: 19/06/2013, 10h47
  2. Réponses: 0
    Dernier message: 19/07/2012, 09h30
  3. comment passer une image au code
    Par tyranosaure dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 10/02/2007, 16h50
  4. Comment passer une image à un état ?
    Par Cazaux-Moutou-Philippe dans le forum WinDev
    Réponses: 14
    Dernier message: 22/10/2006, 22h29
  5. [VB.NET] Comment passer une image à CR
    Par olbi dans le forum Windows Forms
    Réponses: 5
    Dernier message: 25/09/2006, 20h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo