Search code examples
leadtools-sdk

WPF Cropping a portion of an image


I have created a WPF application where I need to allow a user to draw a rectangle on an existing loaded image(tif image) and have it save the coordinates/the portion of the rectangle as a separate image.

I am using the Leadtools.Windows.Controls reference and using the RasterImageViewer

Below is the code for the event handler when the user has completed drawing the rectangle.

private void ImageViewer_InteractiveUserRectangle(object sender, RectangleInteractiveEventArgs e)
    {
        if (e.Status == InteractiveModeStatus.End)
        {             

            var img = ImageViewer.Image;

            var top =Convert.ToInt32(e.Bounds.Top);
            var left = Convert.ToInt32(e.Bounds.Left);
            var width = Convert.ToInt32(e.Bounds.Width);
            var height = Convert.ToInt32(e.Bounds.Height);

            var rect = new Leadtools.LeadRect(left, top, width, height);
            var cmd = new Leadtools.ImageProcessing.CropCommand(rect);
            cmd.Run(img);

            _codecs.Save(img, @"c:\temp\test.tif",
                RasterImageFormat.CcittGroup4, 1, 1, 1, -1, CodecsSavePageMode.Append);
        }
    }

I am getting a separate cropped image, but it does not match the area drawn with the rectangle. I have tried various methods from the examples but they were all for Windows Forms applications and not WPF. Any help with what I am missing would be greatly appreciated.


Solution

  • The issue is that the ImageViewer UserRectangle bounds returns the coordinates in Control coordiates and you need to convert these to Image Coordinates which the Crop Command is looking for.

    According to the Documentation here: https://www.leadtools.com/help/leadtools/v19/dh/wl/rectangleinteractiveeventargs-bounds.html

    The coordinates are always in control (display) to image coordinates. You can use PointToImageCoordinates and BoundsToImageCoordinates to map a value in control or display coordinates (what is on screen) to image coordinates (actual x and y location in the image pixels). You can use PointFromImageCoordinates and BoundsFromImageCoordinates to map a value in image coordinates (actual x and y location in t he image pixels) to control or display coordinates (what is on screen).

    Here is the updated code to make it work for you project:

    if (e.Status == Leadtools.Windows.Controls.InteractiveModeStatus.End)
    {
      var img = imageViewer.Image;
    
      var imgRect = imageViewer.BoundsToImageCoordinates(e.Bounds);
    
      var top = Convert.ToInt32(imgRect.Top);
      var left = Convert.ToInt32(imgRect.Left);
      var width = Convert.ToInt32(imgRect.Width);
      var height = Convert.ToInt32(imgRect.Height);
    
      var rect = new Leadtools.LeadRect(left, top, width, height);
      var cmd = new Leadtools.ImageProcessing.CropCommand(rect);
      cmd.Run(img);
    
      _codecs.Save(img, @"c:\temp\test.tif",
        RasterImageFormat.CcittGroup4, 1, 1, 1, -1, CodecsSavePageMode.Append);
    }