Click here to Skip to main content
15,886,422 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hey guys,
I originally posted this on Stack Overflow but after a few minutes realized the whole community is pretty much toxic, unhelpful and unwelcoming. So I thought id try posting my question here instead :)

So here is the issue, I have found 2 different code snippets on the internet related to what I need to do but I cannot successfully merge the snippets in the way I need.

So essentially I have this as my base: Rotate a picture in C# - C# HelperC# Helper[^] this code works great for my rotation and even has zooming, however the zoom will only work from the top left corner which doesnt work for my situation.

What I want to be able to do is to keep the rotation function but to be able to zoom in and out of a specified point on the image. When it comes to matrix operations it just goes all over my head tbh.

What I have tried:

C#
  // Display the image at the current rotation and scale.
private void DisplayImage()
{
    if (OriginalImage == null) return;
    RotatedImage = null;
    picRotatedImage.Visible = false;

    float angle;
    if (!float.TryParse(txtAngle.Text, out angle)) return;

    // Find the size of the image's rotated bounding box.
    Matrix rotation = new Matrix();
    rotation.Rotate(angle);
    int old_wid = OriginalImage.Width;
    int old_hgt = OriginalImage.Height;
    PointF[] points =
    {
        new PointF(0, 0),
        new PointF(old_wid, 0),
        new PointF(0, old_hgt),
        new PointF(old_wid, old_hgt),
    };
    rotation.TransformPoints(points);
    float[] xs =
        { points[0].X, points[1].X, points[2].X, points[3].X };
    float[] ys =
        { points[0].Y, points[1].Y, points[2].Y, points[3].Y };
    int new_wid = (int)(xs.Max() - xs.Min());
    int new_hgt = (int)(ys.Max() - ys.Min());

    // Make the rotated image.
    RotatedImage = new Bitmap(new_wid, new_hgt);
    using (Graphics gr = Graphics.FromImage(RotatedImage))
    {
        gr.TranslateTransform(-old_wid / 2, -old_hgt / 2,
            MatrixOrder.Append);
        gr.RotateTransform(angle, MatrixOrder.Append);
        gr.TranslateTransform(new_wid / 2, new_hgt / 2,
            MatrixOrder.Append);
       // MY ATTEMPT AT SCALING
       float newScale = Math.Min(Math.Max(m_dZoomscale + (zoomIn ? s_dScrollValue : -s_dScrollValue), 0.1f), 10);
       float adjust = newScale / m_dZoomscale;
       m_dZoomscale = newScale;
    ///HERE
    gr.ScaleTransform(adjust, adjust, MatrixOrder.Append);
    ////

        RectangleF source_rect = new RectangleF(0, 0,
            OriginalImage.Width, OriginalImage.Height);
        PointF[] dest_points =
        {
            new PointF(0, 0),
            new PointF(OriginalImage.Width, 0),
            new PointF(0, OriginalImage.Height),
        };
        gr.DrawImage(OriginalImage, dest_points, source_rect,
            GraphicsUnit.Pixel);
    }

    // Scale the output PictureBox.
    SetPictureBoxSize();

    // Display the result.
    picRotatedImage.Image = RotatedImage;
    picRotatedImage.Visible = true;
}
Posted

1 solution

If you look at what the rotation is doing it moves the rotation point to the origin, performs the rotation and then moves it back again, so everything rotates around that point.

You need to do the same with the scaling.

For example:

///HERE
PointF scalePoint = new PointF(new_wid / 2, new_hgt / 2);
gr.TranslateTransform(-scalePoint.X, -scalePoint.Y, MatrixOrder.Append);
gr.ScaleTransform(adjust, adjust, MatrixOrder.Append);
gr.TranslateTransform(scalePoint.X, scalePoint.Y, MatrixOrder.Append);
////
 
Share this answer
 
Comments
jamesg3 20-Jun-21 21:58pm    
thanks mate! i managed to make it work, however how could I make it zoom to a specific point rather then the center? i have added a Point argument, I have tried to implement this however I cant seem to get the actual co-ordinates of the current part of the picture that is zoomed? any ideas?

PointF scalePoint = location;//new PointF(new_wid / 2, new_hgt / 2);
this.Text = scalePoint.ToString();
gr.TranslateTransform(-scalePoint.X * newScale, -scalePoint.Y * newScale, MatrixOrder.Append);
gr.ScaleTransform(newScale, newScale, MatrixOrder.Append);
gr.TranslateTransform(scalePoint.X * newScale, scalePoint.Y * newScale, MatrixOrder.Append);

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900