Search code examples
c#imagemagickcrop

Using ImageMagick.NET to extract a polygon


I'm using ImageMagick.NET to crop a polygon from an image using coordinates.

Most image cropping questions rely on cropping an image using a rectangle using 4 points, however I need to crop a polygon using between four to eight points instead.

I'm using the following code to create a mask and a drawable polygon to apply to the source image, however the result is that I'm getting is the inverse of what I would expect.

According to http://www.imagemagick.org/Usage/compose/tables/ the In operator should get me my result but instead its getting the remainder of the image

        MagickImage image = new MagickImage(imagePath);
        MagickImage dest = new MagickImage(new MagickColor(Color.White), 1120, 450);
        MagickImage mask = new MagickImage(new MagickColor(Color.White), 1120, 450);

        mask.FillColor = new MagickColor(Color.Black);

        List<Coordinate> coordinates = new List<Coordinate>();
        coordinates.Add(new Coordinate(0, 0));
        coordinates.Add(new Coordinate(0, 300));
        coordinates.Add(new Coordinate(100, 300));
        coordinates.Add(new Coordinate(100, 450));
        coordinates.Add(new Coordinate(1120, 450));
        coordinates.Add(new Coordinate(1120, 150));
        coordinates.Add(new Coordinate(850, 150));
        coordinates.Add(new Coordinate(850, 0));

        mask.Draw(new DrawablePolygon(coordinates));


        MagickGeometry offset = new MagickGeometry(0,0,0,0);
        dest.Alpha(AlphaOption.Transparent);
        dest.ClipMask = mask;

        dest.Composite(image, offset, CompositeOperator.Out);

        dest.Write(@"C:\temp\test.png");

Any help would be greatly appreciated


Solution

  • It looks like you are creating the mask incorrectly for the solution that you want. You should switch the black and white colors:

    List<Coordinate> coordinates = new List<Coordinate>();
    coordinates.Add(new Coordinate(0, 0));
    coordinates.Add(new Coordinate(0, 300));
    coordinates.Add(new Coordinate(100, 300));
    coordinates.Add(new Coordinate(100, 450));
    coordinates.Add(new Coordinate(1120, 450));
    coordinates.Add(new Coordinate(1120, 150));
    coordinates.Add(new Coordinate(850, 150));
    coordinates.Add(new Coordinate(850, 0));
    
    using (MagickImage image = new MagickImage(imagePath))
    {
      using (MagickImage mask = new MagickImage(Color.Black, 1120, 450))
      {
        mask.FillColor = new MagickColor(Color.White);
    
        mask.Draw(new DrawablePolygon(coordinates));
    
        using (MagickImage dest = new MagickImage(Color.White, 1120, 450))
        {
          dest.Alpha(AlphaOption.Transparent);
          dest.Mask = mask;
    
          MagickGeometry offset = new MagickGeometry(0, 0, 0, 0);
          dest.Composite(image, offset, CompositeOperator.Out);
    
          dest.Write(@"D:\test.png");
        }
      }