Probleme avec GetBitmapBits

kikipounque Messages postés 12 Date d'inscription lundi 28 avril 2003 Statut Membre Dernière intervention 13 janvier 2007 - 8 sept. 2004 à 17:02
kikipounque Messages postés 12 Date d'inscription lundi 28 avril 2003 Statut Membre Dernière intervention 13 janvier 2007 - 13 sept. 2004 à 14:32
je souhaite recuperer le tableau de pixel, donc je fais appel a l'API suivante:

GetBitmapBits Picture1.Image.handle, (W * H * 4), PicBits(0, 0)

pour des images de tailles inferieures à 4500*2000 pixels, tout marche bien. pour des tailles superieures, ça ne plante pas mais le resultat sans aucun traitement sur les pixels ne renvoi rien : la picturebox de resultat est vide.

si qqn peut m'aider, ça serait cool.

merci

7 réponses

MoiOlivier Messages postés 172 Date d'inscription mardi 15 juillet 2003 Statut Membre Dernière intervention 4 août 2005
8 sept. 2004 à 18:41
Salut,

Déjà, ce sont de fameuses images, 4500*2000...

L'API GetBitmapBits est une api obsolète, elle n'existe encore que pour des raisons de compatibilité (dixit Microsoft).

Essaie plutot avec GetDIBits, elle fait la même chose en gros.

Bonne prog, @+.
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
8 sept. 2004 à 19:27
Va voir ma source nommée DKS_GESTION_IMAGE : il s'agit d'une classe qui encapsule la fonction GetDIBits pour obtenir un résultat très rapide, et qui permet d'accèder très aisément aux pixels à partir du tableau de bits.

DarK Sidious

[Responsable API/VB du site www.ProgOtoP.com]
Téléchargez ProgOtoP API Viewer
0
kikipounque Messages postés 12 Date d'inscription lundi 28 avril 2003 Statut Membre Dernière intervention 13 janvier 2007
9 sept. 2004 à 09:48
le probleme est identique avec la classe DKS_GESTION_IMAGE. le resultat est bon pour des petites tailles mais des qu'on depasse les 4500*2000, on attends le resultat qui ne vient jamais.
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
9 sept. 2004 à 10:20
Ca vient sûrement de la taille énorme de l'image !

Essaye de la découper en 2 ou en quatre...

DarK Sidious

[Responsable API/VB du site www.ProgOtoP.com]
Téléchargez ProgOtoP API Viewer
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
kikipounque Messages postés 12 Date d'inscription lundi 28 avril 2003 Statut Membre Dernière intervention 13 janvier 2007
13 sept. 2004 à 14:08
voila , je decoupe ma grosse image en plusieurs bitmaps de 2000*2000. et le temps n'est pas proportionnel.

exemple, pour une image 2000*2000, le prog met environ 6 secondes.

pour une image 3506*4581, il mets quasiment 2 minutes. ya comme un pb quelque part. alors qu'il devrait mettre 6 fois plus de temps que le premier cas, soit environ 36 secondes. que se passe-t-il?

voici le code avec la classe de Dark

Const WMAX = 2000
Const HMAX = 2000

Dim H As Long
Dim W As Long
Dim tab_startW() As Long 'stocke les positions de debut des images découpées
Dim tab_startH() As Long
Dim tab_W() As Long 'stocke les largeurs des images découpees
Dim tab_H() As Long
Dim tab_posW() As Long 'stocke les position reelles
Dim tab_posH() As Long
Dim tab_pb() As PictureBox

Private Sub Command1_Click()

Dim OBJ_Image As New CLS_GESTION_IMAGE 'stocke l'objet de gestion d'image
Dim LNG_for1 As Long 'stocke les valeurs de la boucle For->Next
Dim LNG_For2 As Long 'stocke les valeurs de la boucle For->Next
Dim LNG_Couleur As Long 'stocke la couleur récupèrée
Dim BYT_Red As Byte 'stocke la composante rouge de la couleur
Dim BYT_Green As Byte 'stocke la composante verte de la couleur
Dim BYT_Blue As Byte 'stocke la composante bleue de la couleur

Dim tps As Long
Dim str As String

Picture1.AutoRedraw = True

tps = GetTickCount
W = Picture1.ScaleWidth
H = Picture1.ScaleHeight

Dim coefx As Long
Dim coefy As Long
Dim i As Long
Dim j As Long

If W > WMAX Then
coefx = Int(W / WMAX)
ReDim tab_startW(coefx + 1) As Long
ReDim tab_posW(coefx + 1) As Long
ReDim tab_W(coefx + 1) As Long
tab_startW(0) = 0
tab_posW(0) = WMAX
tab_W(0) = WMAX
If coefx < 2 Then
tab_startW(1) = WMAX
tab_posW(1) = tab_startW(1) + W - WMAX
tab_W(1) = W - WMAX
Else
For i = 1 To coefx - 1
tab_startW(i) = tab_posW(i - 1)
tab_posW(i) = tab_startW(i) + WMAX
tab_W(i) = WMAX
Next i
tab_startW(coefx) = tab_posW(coefx - 1)
tab_posW(coefx) = tab_startW(coefx) + W - coefx * WMAX
tab_W(coefx) = W - WMAX
End If
Else
coefx = 0
ReDim tab_startW(1) As Long
ReDim tab_posW(1) As Long
ReDim tab_W(1) As Long
tab_startW(0) = 0
tab_posW(0) = W
tab_W(0) = W
End If

If H > HMAX Then
coefy = Int(H / HMAX)
ReDim tab_startH(coefy + 1) As Long
ReDim tab_posH(coefy + 1) As Long
ReDim tab_H(coefy + 1) As Long
tab_startH(0) = 0
tab_posH(0) = HMAX
tab_H(0) = HMAX
If coefy < 2 Then
tab_startH(1) = HMAX
tab_posH(1) = tab_startH(1) + H - HMAX
tab_H(1) = H - HMAX
Else
For i = 1 To coefy - 1
tab_startH(i) = tab_posH(i - 1)
tab_posH(i) = tab_startH(i) + HMAX
tab_H(i) = HMAX
Next i
tab_startH(coefy) = tab_posH(coefy - 1)
tab_posH(coefy) = tab_startH(coefy) + H - coefy * HMAX
tab_H(coefy) = H - HMAX
End If
Else
coefy = 0
ReDim tab_startH(1) As Long
ReDim tab_posH(1) As Long
ReDim tab_H(1) As Long
tab_startH(0) = 0
tab_posH(0) = H
tab_H(0) = H
End If

'decoupe le bitmap en (coefx * coefy) bitmaps séparés
ReDim tab_pb(coefx + 1, coefy + 1) As PictureBox
For i = 0 To coefx
For j = 0 To coefy

Set tab_pb(i, j) = Picture2
tab_pb(i, j).ScaleMode = 3
tab_pb(i, j).AutoRedraw = True
tab_pb(i, j).AutoSize = True
tab_pb(i, j).BorderStyle = 0
tab_pb(i, j).Height = tab_H(j) * Screen.TwipsPerPixelY
tab_pb(i, j).Width = tab_W(i) * Screen.TwipsPerPixelX

Call BitBlt(tab_pb(i, j).hdc, 0, 0, tab_W(i), tab_H(j), Picture1.hdc, tab_startW(i), tab_startH(j), SRCCOPY)
tab_pb(i, j).Refresh ' Montre l'image une fois la page rafraîchit

Set OBJ_Image.PictureBox = tab_pb(i, j)

For LNG_for1 = 0 To tab_pb(i, j).ScaleWidth - 1
For LNG_For2 = 0 To tab_pb(i, j).ScaleHeight - 1

Call OBJ_Image.GetPixelRGB(LNG_for1, LNG_For2, BYT_Red, BYT_Green, BYT_Blue)
If (BYT_Red < 128) Then
Call OBJ_Image.SetPixelRGB(LNG_for1, LNG_For2, 0, 0, 0)
Else
Call OBJ_Image.SetPixelRGB(LNG_for1, LNG_For2, 255, 255, 255)
End If

Next LNG_For2
Next LNG_for1

Call OBJ_Image.Refresh
Call BitBlt(Picture1.hdc, tab_startW(i), tab_startH(j), tab_W(i), tab_H(j), Picture2.hdc, 0, 0, SRCCOPY)
Set OBJ_Image = Nothing

Next j
Next i
Picture1.Refresh

'on calcule le temps écoulé et on l'affiche
MsgBox CStr(GetTickCount - tps) & " ms"

End Sub
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
13 sept. 2004 à 14:21
n'oublie pas de mettre des doevents dans tes boucles pour permettre au système de reprendre la main, car sinon, c'est normal qu'il soit plus lent !

De plus, évite de raffraichir souvent ton image avec un Call OBJ_Image.Refresh car cela demande un certain temps

DarK Sidious

[Responsable API/VB du site www.ProgOtoP.com]
Téléchargez ProgOtoP API Viewer
0
kikipounque Messages postés 12 Date d'inscription lundi 28 avril 2003 Statut Membre Dernière intervention 13 janvier 2007
13 sept. 2004 à 14:32
le OBJ_Image.Refresh permet de faire de le setdibits et non des raffraichissement d'images.

je gagne 2 secondes avec des doevents.

kikipounque
0
Rejoignez-nous