2009-11-22 6 views
3

Je dessine une image à partir de MetaFile (emf), puis j'applique des transformations de rotation à tout cela dans OnPaint d'un UserControl. Après avoir appliqué ces transformations, comment puis-je calculer la boîte rectangulaire normale non transformée de cette coordonnée à l'écran? J'ai besoin de cela pour pouvoir redimensionner l'image pivotée à la taille de UserControl.Calcul de la boîte englobante d'un dessin GDI +

protected override void OnPaint(PaintEventArgs e) 
{ 
    // rotate around the center of this UserControl 
    e.Graphics.TranslateTransform(this.Width/2.0f, this.Height/2.0f); 
    e.Graphics.RotateTransform(this.Rotation); 
    e.Graphics.TranslateTransform(this.Width/-2.0f, this.Height/-2.0f); 

    // TODO: now scale so the image so it fits exactly into this UserControl 

    // draw the image at the center of this UserControl 
    float left = (this.Width - ResourceManager.MyDrawingMetaFile.Width)/2.0f; 
    float top = (this.Height - ResourceManager.MyDrawingMetaFile.Height)/2.0f; 
    e.Graphics.DrawImage(Resources.MyDrawingMetaFile, left, top); 
} 

L'idée derrière cela est que je veux afficher une rotation .emf fichier dans un UserControl et ont le dessin fem remplir AllWays l'espace disponible dans le UserControl. Peut-être qu'il y a une meilleure approche?

Le mode fillmode/stretchmode que je cherche après est Uniform et UniformToFill (comme dans la Viewbox de WPF). La fem ne doit pas être déformée et en mode Uniforme l'emf remplit complètement la commande usercontrol au moins dans une dimension, rien n'est recadré. Dans UniformToFill, l'emf enchante le UserControl dans les deux dimensions et si les aspectratios ne correspondent pas, l'emf est recadrée dans une dimension.

+0

Comment voulez-vous qu'il se "remplisse"? Est-ce que la force électromotrice devrait couvrir complètement l'usercontrol (une partie de la force électromotrice devrait-elle être coupée) ou devrait-elle être dimensionnée de façon à ce que toute la force électromotrice soit visible - en laissant les parties de l'usercontrol couvertes? Et l'emf devrait-elle garder son format d'origine ou non? –

+0

Le mode de remplissage/stretchmode que je suis après est Uniform et UniformToFill (comme dans la Viewbox de WPF). La fem ne doit pas être déformée et en mode Uniforme l'emf remplit complètement la commande usercontrol au moins dans une dimension, rien n'est recadré. Dans UniformToFill, l'emf enchante le UserControl dans les deux dimensions et si les aspectratios ne correspondent pas, l'emf est recadrée dans une dimension. – bitbonk

Répondre

1

Si je vous comprends bien - vous devez savoir comment la rotation affecte la zone de délimitation de votre image, de sorte que vous pouvez l'adapter en conséquence.

Ensuite, vous pouvez faire comme ceci:

  1. Farcir les quatre coordonnées de votre boîte de sélection dans un point [].
  2. Configurer une matrice avec votre rotation (.RotateAt)
  3. Laisser la matrice transformer les quatre points.
  4. Trier les quatre coordonnées X transformées et comparer la largeur de la nouvelle boîte englobante (pts [3] .X - pts [0] .X après tri).
  5. Maintenant, vous savez comment mettre à l'échelle la largeur pour un ajustement parfait.
  6. Répétez l'étape 4 pour la hauteur également.
+0

Mes dessins ne sont pas nécessairement rectangulaires.Par exemple, si le dessin est un cercle, la rotation elle-même n'affecterait pas le facteur d'échelle. – bitbonk

+0

Ensuite, vous devez faire ce qui précède pour chaque * coin * dans l'image. Un cercle devra bien entendu être approché et considéré comme constitué d'un certain nombre de segments de droite. –

+0

Je me demande, comment WPF (probablement dans la couche DWM quelque part) le fait. – bitbonk

0

La façon dont il serait fait avec GDI est:

BeginPath() 
// Draw stuff 
EndPath() 
PathToRegion() 
GetRgnBox() 

GDI + a des équivalents - La GraphicsPath et les classes de la région peut faire ce qui précède

+0

Mon dessin provient d'un métafichier, donc je pense que GraphicsPath ne s'appliquerait pas. – bitbonk

+0

Un métafichier est juste une sérialisation des appels GDI, il devrait donc fonctionner avec GraphicsPath. Quoi qu'il en soit la classe MetaFile a une méthode GetMetafileHeader, vous pouvez obtenir la boîte de délimitation de métafichier et utiliser triginometry pour obtenir la taille pivotée. –

+0

Well GraphicsPath n'a pas de méthode AddMetaFile ou AddDrawing ou similaire. – bitbonk

Questions connexes