Maison >développement back-end >C++ >Pourquoi mon image saute-t-elle lors d'un zoom à partir du curseur de la souris à l'aide de transformations C# ?

Pourquoi mon image saute-t-elle lors d'un zoom à partir du curseur de la souris à l'aide de transformations C# ?

Susan Sarandon
Susan Sarandonoriginal
2024-12-25 06:47:43331parcourir

Why Does My Image Jump When Zooming from the Mouse Cursor Using C# Transformations?

Zoom sur une image à partir du curseur de la souris à l'aide de transformations

Dans ce scénario, une tentative est effectuée pour zoomer (mettre à l'échelle) une image à partir du emplacement de la souris en utilisant des transformations dans l'événement Paint pour traduire l'origine du bitmap à l'emplacement de la souris, puis redimensionner l'image et traduire son origine retour.

Problème :

  • L'image saute et ne parvient pas à être mise à l'échelle à partir de l'origine déplacée lors de la traduction de l'emplacement de la souris.
  • Rotation, l'échelle et le panoramique fonctionnent correctement sans se traduire par la souris emplacement.

Plateforme :

  • .Net 4.7.2
  • Visual Studio sous Windows 10 1909 (18363.778)

Code pertinent Blocs :

private void trackBar1_Scroll(object sender, EventArgs e) {
    // Get rotation angle
    ang = trackBar1.Value;
    pnl1.Invalidate();
}

private void pnl1_MouseWheel(object sender, MouseEventArgs e) {
    // Get mouse location
    mouse = e.location;

    // Get new scale (zoom) factor
    zoom = (float)(e.Delta > 0 ? zoom * 1.05 : zoom / 1.05);
    pnl1.Invalidate();
}

private void pnl1_MouseDown(object sender, MouseEventArgs e) {
    if (e.Button != MouseButtons.Left) return;
    pan = true;
    mouX = e.X;
    mouY = e.Y;
    oldX = imgX;
    oldY = imgY;
}

private void pnl1_MouseMove(object sender, MouseEventArgs e) {
    if (e.Button != MouseButtons.Left || !pan) return;

    // Coordinates of panned image
    imgX = oldX + e.X - mouX;
    imgY = oldY + e.Y - mouY;
    pnl1.Invalidate();
}

private void pnl1_MouseUp(object sender, MouseEventArgs e) {
    pan = false;
}

private void pnl1_Paint(object sender, PaintEventArgs e) {
    // Apply rotation angle @ center of bitmap
    e.Graphics.TranslateTransform(img.Width / 2, img.Height / 2);
    e.Graphics.RotateTransform(ang);
    e.Graphics.TranslateTransform(-img.Width / 2, -img.Height / 2);

    // Apply scaling factor - focused @ mouse location
    e.Graphics.TranslateTransform(mouse.X, mouse.Y, MatrixOrder.Append);
    e.Graphics.ScaleTransform(zoom, zoom, MatrixOrder.Append);
    e.Graphics.TranslateTransform(-mouse.X, -mouse.Y, MatrixOrder.Append);

    // Apply drag (pan) location
    e.Graphics.TranslateTransform(imgX, imgY, MatrixOrder.Append);

    // Draw "bmp" @ location
    e.Graphics.DrawImage(img, 0, 0);
}

Solutions possibles :

Pour résoudre ce problème et obtenir un zoom fluide à partir de l'emplacement de la souris, tenez compte des suggestions et astuces suivantes :

1. Diviser pour conquérir : Décomposez les différents effets graphiques et transformations en méthodes distinctes et spécialisées qui effectuent des tâches spécifiques. Ensuite, concevez ces méthodes pour qu'elles fonctionnent ensemble de manière transparente en cas de besoin.

2. Restez simple :Lors de l'application de plusieurs transformations graphiques, l'ordre dans lequel les matrices sont empilées peut conduire à de la confusion et à des résultats inattendus. Il est plus simple de calculer certaines transformations (traduction et mise à l'échelle principalement) au préalable et de laisser GDI gérer le rendu des objets et des formes prétraités.

3. Utilisez les bons outils : Un panneau comme « toile » n'est pas recommandé pour des scénarios comme celui-ci. Il manque une double mise en mémoire tampon, bien qu'elle puisse être activée. Cependant, une PictureBox (ou une étiquette plate non système) offre une double mise en mémoire tampon prête à l'emploi et est conçue pour le dessin plutôt que pour contenir des contrôles enfants.

4. Implémentez les modes de zoom : Au lieu d'effectuer une mise à l'échelle aveuglément à partir de l'emplacement de la souris, proposez différentes méthodes pour contrôler le comportement du zoom. Implémentez des modes de zoom tels que ImageLocation, CenterCanvas, CenterMouse et MouseOffset pour offrir de la flexibilité et répondre à divers cas d'utilisation.

En suivant ces directives et en mettant en œuvre des modes de zoom personnalisés, vous pouvez obtenir un zoom fluide et efficace à partir de l'emplacement de la souris tout en en conservant la position de l'image et le facteur d'échelle souhaités.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn