StretchBlt

cs_epson1 Messages postés 89 Date d'inscription dimanche 12 novembre 2000 Statut Membre Dernière intervention 29 mars 2013 - 2 juin 2007 à 15:40
cs_epson1 Messages postés 89 Date d'inscription dimanche 12 novembre 2000 Statut Membre Dernière intervention 29 mars 2013 - 3 juin 2007 à 20:20
Bonjours à tous ,

J'ai un probleme que je n'arrive pas à résoudre .

Voici un code :

Private Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, _
ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal _
nSrcHeight As Long, ByVal dwRop As Long) As Long
Const SRCCOPY = &HCC0020

Private Sub Command1_Click()
Picture1.Circle (0, 0), 1
End Sub


Private Sub Command2_Click()
Dim Result As Long


Result = StretchBlt(Picture1.hdc, 0, 0, 1000, 1000, Picture2.hdc, 0, 0, Picture1.Width, Picture1.Height, SRCCOPY)
End Sub


Private Sub Form_Load()
Picture1.Scale (-30, 30)-(30, -30)
Picture1.FillColor = RGB(128, 128, 255)
End Sub

Lors d'un appui sur Command1 , le cercle est normalement tracé au centre du picture box (Picture1.Scale (-30, 30)-(30, -30) )

par contre quand je clique sur command2 , mon image est tracée en haut à gauche du picture box

alors que j'aimerais  que le coin haut/gauche de l'image soit au centre , comme le cercle.

J'ai tout essayé,pas moyen.

Quelqu'un aurait-il une idée ?

Je précise que le scalemode des picture box est en twip ,mais un autre mode ne change rien.

Merci de m'aider.

11 réponses

jmfmarques Messages postés 7668 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 28
2 juin 2007 à 15:57
Bonjour,

Pas compris ce que tu veux faire là !...

tu as 2 picturesBoxes et tu veux envoyer le dessin de laquelle vers laquelle, délà ?
Car, tel que tu t'y prends pour l'instant, tu dessines dans Picture1 ce qui s'y trouve déjà, à l'échelle de Picture2 !!!


On parlera ensuite de cette échelle.


1) Relis les paramètres de StretchBlt d'abord : les uns concernent la source et les autres la destination ...
2) oublie pour l'instant ton cercle et va droit au but (l'utilisation de StrecthBlt) en t'exerçant avec une simple image chargée depuis un fichier...


 
0
cs_epson1 Messages postés 89 Date d'inscription dimanche 12 novembre 2000 Statut Membre Dernière intervention 29 mars 2013
3 juin 2007 à 16:04
Salut jmfmarques et merci de ton interet pour mon petit soucis.
Je pensais avoir été clair mais aprés m'être relus PFFF... :(
Alors voila :
Dans Picture1 je dessine par code une forme géometrique (un carrés,Picture1.line ... pour les


4 cotés)qui se déplace et et que je voudrais remplir avec une images (ici contenue dans


Picture2).


J'ai essayé de faire déplacer picture2 dans picture1.Il se positionne et se déplace bien et au


bon endroit,nickel,mais l'image clignote pendant les déplacements.
Donc pour pallier à ça, je me suis dit :y'a qua faire un stretchBlt en redimensionnant l'image


!
J'ai donc fais ça en donnant comme coordonnées de destination le coin haut/gauche de de


picture2 pensant que le Blit positionnerait l'image à la place de picture2.
Mais au lieu de ça l'image est "posée" en haut à gauche de Picture1 et se deplace autour de ce


point.
La fonction stretchBlt ne semble pas comprendre que Picture1 à son point 0 au centre


(Picture1.Scale (-30,30)-(30,-30)).
L'image n'est même pas vraiment en haut à gauche à 0,0 , elle sort un peu du picture Box.
J'ai essyé pas mal de trucs : X * screen.twipsperpixelX, (ça améliore un peu),Display.ScaleWidth + X etc et ça ne donne rien.
Si je fais X + 400(nombre arbitraire) le bord gauche de l'image se positionn bien, mais si je déplace le point d'origine, l'image se déplace avec ce point mais se décale par rapport à ce point et donc se retrouve à coté.
On dirait que stretchBlt ne travaille pas avec le même ScaleMode.
Ce qui vaut pour X est aussi valable pour Y, mes coordonnées sont bonnes pour placer un picture Box, mais pas pour un stretchBlt.
Je ne trouve pas la relation entre mes coordonnées et celle de stretchBlt.
Voila, j'espére avoir été un peu + clair.
As tu une idée ?
Encore merci de prendre du temps pour moi.
@ +
0
jmfmarques Messages postés 7668 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 28
3 juin 2007 à 18:01
Il y a plusieurs choses que je ne comprends pas, dans tes explications :
"La fonction stretchBlt ne semble pas comprendre que Picture1 à son point 0 au centre "
Le point de départ d'une picturebox n'est pas en son centre, mais est le coin supérieur gauche (abscisse 0, ordonnée 0) de la pictureBox
Tu as quoi, au départ ? : une image dans Picture1 (que tu as déssinée) et une image dans la Picture2 ?


Tu veux faire quoi exactement en suite ?


- mettre la totalité de Picture2 dans picture1 et positionnée au centre de Picture1 ? Si oui : Picture2 est-elle plus petite que Picture1 ?


   - et, ce faisant, en gardant les dimensions de Picture2 ou en réduisant ces dimensions ?


- ne mettre dans Picture1 qu'une partie de Picture2 ?

Qu'entends-tu par "déplacer le point d'origine " ???

StrechtBlt travaille en Pixels.
Réponds avec précision à mes questions si tu veux une réponse précise.
0
jmfmarques Messages postés 7668 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 28
3 juin 2007 à 18:48
Bon,

J' ai peut-être trouvé le moyen, à travers un exemple "parlant" de te faire comprendre certains mécanismes.
Regarde tout, analyse, comprends... et adapte à ton cas


 


Sur une form :


- une picturebox Picture2 dans laquelle tu mets une image et sa propriété Autosize = True
 - une picturebox Picture1 de dimensions plus grandes que Picture1 (tant en hauteur qu'en largeur )

code :

Private Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal X _
As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, _
ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, _
ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long


Private Sub Form_Activate()
   Picture1.ScaleMode = vbPixels
   Picture2.ScaleMode = vbPixels
   Picture1.DrawWidth = 10
   Picture2.Picture = Picture2.Image
   Picture1.AutoRedraw = True
   Picture2.AutoRedraw = True
   x0 = (Picture1.ScaleWidth - Picture2.ScaleWidth) / 2
   y0 = (Picture1.ScaleHeight - Picture2.ScaleHeight) / 2
   X1 = x0 + Picture2.ScaleWidth
   Y1 = y0 + Picture2.ScaleHeight
   Picture1.Line (x0, y0)-(X1, Y1), , B
   StretchBlt Picture1.hdc, x0, y0, Picture2.ScaleWidth, Picture2.ScaleHeight, Picture2.hdc, _
 0, 0, Picture2.ScaleWidth, Picture2.ScaleHeight, &HCC0020
End Sub

Tu lances, bûches et en tires tes conclusions.
0

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

Posez votre question
jmfmarques Messages postés 7668 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 28
3 juin 2007 à 19:36
Quand tu auras fini avec le 1er exercice (et pas avant, hein...)

Tu remplacera la ligne disant :   

 StretchBlt Picture1.hdc, x0, y0, Picture2.ScaleWidth, Picture2.ScaleHeight, Picture2.hdc, _
 0, 0, Picture2.ScaleWidth, Picture2.ScaleHeight, &HCC0020

Par :

   k = 3
   StretchBlt Picture1.hdc, x0 + ((X1 - x0 - Picture2.ScaleWidth / k) / 2), y0 _
   + ((Y1 - y0 - Picture2.ScaleHeight / k) / 2), Picture2.ScaleWidth, Picture2.ScaleHeight, _
   Picture2.hdc, 0, 0, Picture2.ScaleWidth * k, Picture2.ScaleHeight * k, &HCC0020

Tu relances et regardes le résultat...
Si tu ne t'en sors pas avec StretchBlt après tout çà, ce n'est pas StretchBlt qu'il te faut bûcher, mais plutôt l'arithmétique
0
cs_epson1 Messages postés 89 Date d'inscription dimanche 12 novembre 2000 Statut Membre Dernière intervention 29 mars 2013
3 juin 2007 à 19:37
jmfmarques =>

En fait j'ai picture2 qui contient une image + grande que picture1.
picture1 et picture2 ont un scalemode en twip, autosize à thrue.
Je veux copier le contenu de picture2 une fois réduit en un point quelquonque de picture1.
Si je fais un stretchBlt directement, j'ai mon image en haut à gauche de picture1,ça marche .
Si je fais picture1.Circle (0, 0), 1 ,j'ai un cercle en haut à gauche de picture1.
Mais si je rajoute Picture1.Scale (-30,30)-(30,-30) dans form.resize,(necessaire à mon code) :
si je fais picture.circle (0,0),1 ,j'ai un cercle au centre de picture1 ,normal,
si je fais
Result = StretchBlt(picture1.hdc, 0, 0, 100, 100, Picture2.hdc, 0, 0, Picture2.Width, Picture2.Height, vbSrcCopy)
je devrais avoir une image de 100 X 100 (par example) avec son coin haut/gauche au centre de picture1,non ?
Tout mon probleme viens de "Picture1.Scale (-30,30)-(30,-30)"
Regarde le code que j'ai mis plus haut,tu vas comprendre.
Il est vrai que j'avais omis des détails qui ont leur importance :)
Voila
@+
0
jmfmarques Messages postés 7668 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 28
3 juin 2007 à 19:45
Et alors ?
Tu as maintenant tous les éléments qui te sont nécessaires (entre un exercice et l'autre)...
Tout le reste n'est que pure arithmétique.
Ne t'attends pas à ce que je te fasse un code qui correspond exactement à ce que tu fais.
Je t'ai montré comment utiliser StretchBlt, tant (1er exercice) en gardant les dimensions que (2ème exercice) en rapetissant.

Quant au cadre (le rectangle) : c'est rigoureusement le même principe : calcul arrithmétique élémentaire.
Tu peux d'ailleurs ne même pas utiliser de cadre..
Tu peux tout "conjuguer" comme tu l'entends, mais en conjugaisant toi...

Travaille bien.
0
cs_epson1 Messages postés 89 Date d'inscription dimanche 12 novembre 2000 Statut Membre Dernière intervention 29 mars 2013
3 juin 2007 à 19:54
Je crois que nos messages se sont croisés .

Je vais décortiquer tout ça et tâcher de comprendre .
Je maitrise pas mal StretchBlt ,mais avec les mêmes coordonnées,je trace un cercle et il est ou je veux,et je fais un Blit et il va n'importe ou.
Je pense que le probleme vient de changement de scale.
En tout cas merci de m'aider.
@+
0
cs_epson1 Messages postés 89 Date d'inscription dimanche 12 novembre 2000 Statut Membre Dernière intervention 29 mars 2013
3 juin 2007 à 20:01
d'ailleur pour comprendre reprends ton code et ajoute Picture1.Scale (-30, 30)-(30, -30) aprés picture2.scalemode=vbpixels et dis moi ce que tu en pense.
0
jmfmarques Messages postés 7668 Date d'inscription samedi 5 novembre 2005 Statut Membre Dernière intervention 22 août 2014 28
3 juin 2007 à 20:14
Mais Epson,
je n'en pense rien !
Je pense simplement qu'il ne te manque rien et que c'est maintenant à toi de "penser" à ce que tu fais avec.

Tiens,

Un petit cadeau pour te permettre de comprendre encore plus :

Un petit projet :

Une Form
- une pictureBox Picture1 avec une image dedans (propriété picture)
- dans
la picturebox Picture1 : un contrôle image image1 sans image dedans
- en dehors (en bas de ta Form, par exemple, de la PictureBox Picture1 : une picturebox Picture3 sans image

Tu lances et fais glisser le contrôle image1 avec le bouton gauche de ta souris.

Si, avec tout çà, tu ne comprends pas, oublie StrectBlt !!!

Option Explicit


Dim XX As Single
Dim YY As Single


Private Declare Function StretchBlt Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long


Private Sub Form_Load()
    Me.ScaleMode = vbPixels
    Picture1.ScaleMode = vbPixels
    Picture3.ScaleMode = vbPixels
End Sub


Private Sub Image1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  XX = Me.ScaleX(X, vbTwips, vbPixels)
  YY = Me.ScaleY(Y, vbTwips, vbPixels)
End Sub




Private Sub Image1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
 If Button = vbLeftButton Then
   Image1.Left = Image1.Left - XX + Me.ScaleX(X, vbTwips, vbPixels)
   Image1.Top = Image1.Top - YY + Me.ScaleY(Y, vbTwips, vbPixels)
   StretchBlt Picture3.hdc, 0, 0, Picture3.Width, Picture3.Height, Picture1.hdc, Image1.Left, Image1.Top, Image1.Width, Image1.Height, vbSrcCopy
 End If
End Sub

Le développement informatique n'est pas l'utilisation d'une baguette magique mais le fruit d'une étude et d'un travail.
Au boulot, donc

Moi, je vais maintenant au restaurant....
0
cs_epson1 Messages postés 89 Date d'inscription dimanche 12 novembre 2000 Statut Membre Dernière intervention 29 mars 2013
3 juin 2007 à 20:20
Ok.
Merci et bon appetit.
@+
0