Search code examples
c#imagemagickimagemagick-convertmagick.net

ImageMagick .NET Round Image(s) overlap issue


Hey all I have the following C# code:

List<string> lFiles = new List<string>();

lFiles.Add(@"C:\Users\David\Pictures\1.jpg");
lFiles.Add(@"C:\Users\David\Pictures\2.jpg");
lFiles.Add(@"C:\Users\David\Pictures\3.jpg");
IFiles.Add(@"C:\Users\David\Pictures\4.jpg");
IFiles.Add(@"C:\Users\David\Pictures\5.jpg");

using (MagickImageCollection images = new MagickImageCollection())
{
    MagickImage magickinput = null;

    foreach (string tempFile in lFiles)
    {
       magickinput = new MagickImage(tempFile);

       magickinput.Alpha(AlphaOption.Set);
       magickinput.Quality = 100;
       magickinput.Resize(0, 100);
       magickinput.Distort(DistortMethod.DePolar, 0);
       magickinput.VirtualPixelMethod = VirtualPixelMethod.HorizontalTile;
       magickinput.BackgroundColor = MagickColors.None;
       magickinput.Distort(DistortMethod.Polar, 0);                        
       images.Add(magickinput);
   }

   var montageSettings = new MontageSettings()
   {
       BackgroundColor = MagickColors.None,
       TileGeometry = new MagickGeometry(lFiles.Count, 1),
       Shadow = true,
       Geometry = new MagickGeometry(-10, 5, 0, 0)
   };

   using (IMagickImage result = images.Montage(montageSettings))
   {
       result.Composite(magickinput, CompositeOperator.DstIn);
       result.Trim();
       result.RePage();

       result.Write(@"C:\Users\David\Pictures\combinedImgs.png");
   }
}

This produces an image like this:

enter image description here

Notice that the area around Maggie (the first image) has Lisa (the second image) within it and cuts out some of image 2???. It also cuts off Marge (last image). If I just set Geometry = new MagickGeometry(-10, 5, 0, 0) to Geometry = new MagickGeometry(5, 5, 0, 0) it then looks like this:

enter image description here

Which fixes Marge (last image) but Maggie (first image) still looks odd...

I've also noticed that all the images seem to be "fuzzy" with their outlines:

enter image description here enter image description here

First image is the original and the second is the Magick version.

Images used:

enter image description here enter image description here enter image description here enter image description here enter image description here

Maggie (first image) by herself looks like this:

enter image description here

What am I doing incorrectly? I'm using version ImageMagick-7.0.7-Q16.

And this is the overall look i am going for:

enter image description here

UPDATE

This is as far as i have gotten with translating the command line:

List<string> lFiles = new List<string>();

lFiles.Add(@"C:\Users\David\Pictures\1.jpg");
lFiles.Add(@"C:\Users\David\Pictures\2.jpg");
lFiles.Add(@"C:\Users\David\Pictures\3.jpg");
lFiles.Add(@"C:\Users\David\Pictures\4.jpg");
lFiles.Add(@"C:\Users\David\Pictures\5.jpg");

using (MagickImageCollection images = new MagickImageCollection())
{
       MagickImage magickinput = null;

       foreach (string tempFile in lFiles)
       {
            magickinput = new MagickImage(tempFile);
            IMagickImage _circle = new MagickImage();

            magickinput.Resize(100, 100);
            _circle = new MagickImage(MagickColor.FromRgb(255, 255, 255), magickinput.Width + 20, magickinput.Height);
            _circle.Draw(new DrawableCircle(50, 50, 50, 100));
            _circle.Alpha(AlphaOption.Off);
            //_circle.Compose....????

      }
}

I'm not sure how to do these following commands in C#:

xc:black

copy_opacity -layers

dstover -layers

xc:"graya(100%,0)"

+smush

UPDATE 2

enter image description here


Solution

  • Here is a different approach using Imagemagick 6 (unix syntax). I resize the images, then create a circle mask, then put that circle into the alpha channel of each image using -layers composite with the null: separator, then smush the images together.

    convert maggie.jpg lisa.jpg bart.jpg homer.jpg marge.jpg -resize 100x100 \
    null: \
    \( -size 100x100 xc:black -fill white -draw "circle 50,50 50,88" \) \
    -alpha off -compose copy_opacity -layers composite \
    null: \
    \( -size 100x100 xc:none -fill black -draw "circle 50,50 50,90" -blur 0x5 \) \
    -compose dstover -layers composite \
    -background none -gravity center +smush -25+0 \
    simpsons_circles2.png
    

    enter image description here

    See https://www.imagemagick.org/Usage/anim_mods/#composite_single https://www.imagemagick.org/script/command-line-options.php#layers https://www.imagemagick.org/script/command-line-options.php#smush

    And that would translate into the following C# code (provided by dlemstra):

    List<string> lFiles = new List<string>();
    
    lFiles.Add(@"C:\Users\David\Pictures\1.jpg");
    lFiles.Add(@"C:\Users\David\Pictures\2.jpg");
    lFiles.Add(@"C:\Users\David\Pictures\3.jpg");
    lFiles.Add(@"C:\Users\David\Pictures\4.jpg");
    lFiles.Add(@"C:\Users\David\Pictures\5.jpg");
    
    using (MagickImageCollection images = new MagickImageCollection())
    {
        foreach (string tempFile in lFiles)
        {
            images.Add(tempFile);
        }
    
        using (var mask = new MagickImage("xc:black", 100, 100))
        {
            mask.Settings.FillColor = MagickColors.White;
            mask.Draw(new DrawableCircle(50, 50, 50, 88));
            mask.HasAlpha = false;
    
            foreach (var image in images)
            {
                image.Resize(100, 100);
    
                image.Composite(mask, CompositeOperator.CopyAlpha);
            }
        }
    
        using (var shadow = new MagickImage("xc:none", 100, 100))
        {
            shadow.Settings.FillColor = MagickColors.Black;
            shadow.Draw(new DrawableCircle(50, 50, 50, 90));
            shadow.Blur(0, 5);
    
            foreach (var image in images)
            {
                image.Composite(shadow, CompositeOperator.DstOver);
            }
        }
    
        images.First().BackgroundColor = MagickColors.None;
    
        using (IMagickImage result = images.SmushHorizontal(-25))
        {
            result.Write(@"C:\Users\David\Pictures\combinedImgs.png");
        }
    }