Pb de lenteur lors d'un chargement de StdPicture

Arnor2000 Messages postés 32 Date d'inscription mercredi 17 mars 2004 Statut Membre Dernière intervention 24 novembre 2004 - 5 juil. 2004 à 18:25
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 - 8 juil. 2004 à 08:14
Bonjour à tous !

Je fait un composant pour améliorer une picturebox avec plein de fonctionnalités (Je dépose la source dès que je l'ai terminée, promis !), mais j'ai un problème.
J'ai une image dans une stdPicture (imgImage as StdPicture) et je m'en sert pour mettre à jour UserControl.Picture, et je veux redimentionner mon imgImage pour qu'elle prenne la taille de mon controle. Donc en fait j'ai ma procédure Refresh (qui sert à rafraichir mon controle) qui appel une autre procédure qui adapte imgImage à la taille de mon controle avec la méthode PaintPicture (par l'intermédiaire d'une PictureBox temporaire imgTemp), jusque là, pas de problème.

Mais c'est dès que ma nouvelle image recalculée s'applique dans UserControl.MaskPicture (pour faire la transparence déjà géré par mon controle) que ca prend au moins une seconde à charger... ce qui est étrange c'est que juste avant j'applique ma nouvelle image recalculée dans UserControl.Picture et là le chargement est instantané !

Je met le code des mes deux procédures pour que vous voyez mieux ce que je veux dire :

Private Sub ImageControle()
    imgTemp.Height = UserControl.Height
    imgTemp.Width = UserControl.Width
    imgTemp.AutoRedraw = True
    imgTemp.Refresh
    imgTemp.PaintPicture imgImage, 0, 0, UserControl.Width, UserControl.Height
    imgTemp.Refresh
    Set imgImage = imgTemp.Image
End Sub

Private Sub Refresh()
    UserControl.Cls
    
    If numAdapter = Image_au_Controle And imgImage <> 0 Then Call ImageControle
    UserControl.Picture = imgImage
    UserControl.MaskColor = lngCouleurTransparence
    If bolTransparence Then
        UserControl.MaskPicture = imgImage
        UserControl.BackStyle = 0
    Else
        UserControl.BackStyle = 1
    End If
End Sub


J'ai aussi remarqué que si je ne redimentionne pas imgTemp (au début de ImageControle), tout s'affiche immédiatement... mais ce n'est pas une solution de mettre imgTemp très grand sans le redimentionner car à ce moment là quand j'enregistrement les propriétés dans le WriteProperty ca me fait une Form1.frx grosse de 3mo ! Et ca prend du temps à l'écriture et à la lecture !

Bon voila en gros mes problèmes ! Si quelqu'un a une explication, une autre méthode, ou une astuce pour palier à ce problème, merci beaucoup d'avance !!

Arnor

13 réponses

cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
6 juil. 2004 à 09:43
Utilise plutôt la fonction de l'API StretchBlt au lieu de PaintPicture. De Même, au lieu d'utiliser des stdPicture, utilise plutôt des contexte compatible avec ton usercontrol, que tu peux créer grâce à la fonction de l'API CreateCompatibleDC.

DarK Sidious

[Responsable API/VB du site www.ProgOtoP.com]
Téléchargez ProgOtoP API Viewer
0
Arnor2000 Messages postés 32 Date d'inscription mercredi 17 mars 2004 Statut Membre Dernière intervention 24 novembre 2004
6 juil. 2004 à 12:36
Merci beaucoup Darksidious !

Je vais explorer tes pistes ! C'est déjà un exploit d'avoir pris la peine de tout lire (j'avais pas vu que j'avais écrit un roman :-p )

Je reviendait te faire part de mes résultats !

Arnor
0
Arnor2000 Messages postés 32 Date d'inscription mercredi 17 mars 2004 Statut Membre Dernière intervention 24 novembre 2004
6 juil. 2004 à 16:02
Je ne sais pas comment utiliser CreateCompatibleDC, d'ailleur il ne vaudrait mieux pas utiliser CreateCompatibleBitmap ?

En fait une fois que j'ai créé un HDC compatible à mon UserControl(il faut qu'il soit compatible à quoi, en fait ?), il faut faire comment pour charger une image dedans ?

Je pense que c'est dans ce Property Set qu'il faut le charger, au départ il est comme ca :
Public Property Set Image(ByVal Value As StdPicture)
    Set imgImage = Value
    Call Refresh
    MsgBox HDCimage
    PropertyChanged "Image"
End Property

Il faut que je lui fasse quoi ?

Merci de vos réponse !
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
6 juil. 2004 à 16:49
Crée une variable privée qui stocke le handle de ton DC.

Ensuite, créer un DC compatible avec ton UserControl :
CreateCompatibleDC(UserControl.hdc)

Ensuite, il faut charger ton image dans ce DC avec la fonction LoadImage, mais ton value doit alors être de type String ! :
LoadImage(App.hInstance, Value, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)

Et ensuite, tu n'a plus qu'à afficher ton image dans le Paint de ton contrôle grâce à la fonction StretchBlt.

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
Arnor2000 Messages postés 32 Date d'inscription mercredi 17 mars 2004 Statut Membre Dernière intervention 24 novembre 2004
6 juil. 2004 à 17:56
Merci encore un fois !

Avec tes explications je suis sur d'y arriver maintenant !

J'espère que ca va arranger le problème de lenteur en tout cas !
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
6 juil. 2004 à 18:25
Ben à mon avis, ton problème de lenteur est due, d'une, que VB est très lent pour la manipulation d'umage, et de deux, que la transparence ralentit l'affichage !

Si le résultat est encore trop lent, tu peux toujours travailler avec des régions plutôt que de gérer la transparence avec VB !

DarK Sidious

[Responsable API/VB du site www.ProgOtoP.com]
Téléchargez ProgOtoP API Viewer
0
Arnor2000 Messages postés 32 Date d'inscription mercredi 17 mars 2004 Statut Membre Dernière intervention 24 novembre 2004
6 juil. 2004 à 23:35
désolé de faire encore appel à toi mais j'arrive pas à afficher l'image !

Je me suis servis de cette source pour essayer de completer tes informations : http://www.vbfrance.com/code.aspx?ID=6192

Et je suis arrivé à ce réultat :
Public Property Let Image(ByVal Value As String)
    HDCmemoire = CreateCompatibleDC(UserControl.hdc)
    HDCimage = LoadImage(App.hInstance, App.Path & "\Domino noir.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)
    SelectObject HDCmemoire, HDCimage
    GetObject HDCimage, Len(bmp), bmp
    Call Refresh
    PropertyChanged "Image"
End Property

Public Sub Refresh()
UserControl.Cls
HDCcontrole = GetDC(UserControl.hwnd)
If HDCmemoire <> 0 Then
StretchBlt(HDCcontrole, 0, 0, UserControl.Width, UserControl.Height, HDCmemoire, 0, 0, bmp.bmWidth, bmp.bmHeight, SrcCopy)
End If
    UserControl.MaskColor = lngCouleurTransparence
    If bolTransparence Then
        UserControl.MaskPicture = UserControl.Picture
        UserControl.BackStyle = 0
    Else
        UserControl.BackStyle = 1
    End If
End Sub

Le seul endroit où ca peut coincer c'est dans le StretchBlt car je suis sur qu'il y a la bonne image de chargée car bmp.bmWidth par exemple me donne les bonnes valeur...

Pour ce qui est de la rapidité du MaskPicture, justement tant que je ne redientionne pas l'image chargée il est quasi instantané (je l'ai testé qui prennait moins d'une seconde avec une image en 2048*2048 contre plus de 10 secondes avec la méthode des régions !) donc je ne tient pas à changer de méthode !

Arnor
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
7 juil. 2004 à 08:15
Quel est le problème rencontré ? Utilise-tu un ScaleMode en pixel pour ton usercontrol ?

10 secondes avec les régions ??? Ben dis donc, c'était loin d'être optimisé comme méthode alors ! Je parierais que c'était en utilisant la fonction de VB Point ? ou à la limite la fonction GetPixel ?

Non, pour les régions, pour obtenir un soupçon de rapidité, il faut manipuler directement les bits de l'image et non les pixels, tu y gagne énormément : voir ma source nommée Découpage rapide d'une feuille pour te donner un ordre d'idée ;-)

DarK Sidious

[Responsable API/VB du site www.ProgOtoP.com]
Téléchargez ProgOtoP API Viewer
0
Arnor2000 Messages postés 32 Date d'inscription mercredi 17 mars 2004 Statut Membre Dernière intervention 24 novembre 2004
7 juil. 2004 à 17:03
dsl d'avoir mis si longtemps, j'ai regardé tes sources pour essayer de comprendre ce qui m'arrive...

en fait je n'arrive pas à mettre l'image que j'ai dans HDCmemoire dans UserControl.Picture, en fait au mieux je peux faire UserControl.hdc mais ca marche pas...
Le mieux que j'ai obtenu c'est que ce soit tout blanc en passant par un PictureBox caché.

Ce qui me gène vraiment je pense que c'est que UserControl.Picture n'ait pas de hdc ce qui m'empèche d'utiliser Stretchbtl qui a besoin du hdc de la destination.

Pour ce qui est de la rapidité de maskPicture, tu devrait l'essayer toi-même, il suffit de créer un nouveau controle personnalisé, et de remplir MaskColor, MaskPicture et puis Picture en passant

Arnor
0
Arnor2000 Messages postés 32 Date d'inscription mercredi 17 mars 2004 Statut Membre Dernière intervention 24 novembre 2004
7 juil. 2004 à 17:06
Et backStyle à 0 aussi bien sur, j'allait oublier
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 130
7 juil. 2004 à 19:06
Le usercontrol possède bien un DC rattaché : pour récupèrer son hanlde, c'est bien UserControl.hDC ! Faut pas oublié de raffraichir l'affichage après l'appel de StretchBlt !

Pour le MaskPicture, je connais t'en fait pas, mais je le trouve très lent : j'ai fait une source (ou du moins j'ai commencé) de bouton personnalisable, et avec la transparence, dès que le bouton est assez grand, ca devient lent !

DarK Sidious

[Responsable API/VB du site www.ProgOtoP.com]
Téléchargez ProgOtoP API Viewer
0
Arnor2000 Messages postés 32 Date d'inscription mercredi 17 mars 2004 Statut Membre Dernière intervention 24 novembre 2004
7 juil. 2004 à 23:24
J'ai réussit à avoir mon image qui s'affiche une fraction de seconde quand je passe d'un fond opaque à un fond transparent ! Je n'arrive toujours pas à comprendre pourquoi à ce moment là et pas tout le temps, mais en tout cas ce dont je suis sur c'est que j'ai passé mon image dans le UserControl en faisant StretchBlt(UserControl.hdc, 0, ... et que mon UserControl.Picture est vide alors que c'est lui qu'il faut remplir non ?

En fait mon problèmec'est surtout que je n'y connais rien aux DC et à cette méthode pour afficher les images. Alors le mieux je pense, c'est que je commence par comprendre comment ca marche avant d'essayer de faire marcher mon controle... Je vais essayer de trouver un tutoriel qui m'explique tout a fond !

Merci beaucoup en tout cas de m'avoir montrer la piste à suivre pour arriver à un affichage rapide !

Arnor
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 juil. 2004 à 08:14
Ah oui forcément, si tu ne sais pas comment utiliser les API "classiques" pour l'affichage d'image, tu risque avoir du mal à les mettre en place.

Essaye déjà de manipuler les fonction BitBlt, puis StretchBlt dans des contrôles PictureBox standard, et ensuite, tu devrais mieux y arriver dans un UserControl.

Sache que la propriété Picture est directement liée à la propriété Image : La propriété Image stocke ce que tu dessine contrairement à la propriété Picture.

DarK Sidious

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