Clone a image to a larger one without resize using Magick.NET

1.9k Views Asked by At

I've searched a bit around the discussions\forums/StackOverflow/Official documentation, but i couldn't find much information about how to achieve what i'm trying. Most of the official documentation covers the command-line version of ImageMagick.

I'll describe what i'm trying to do: I have a image loaded that i would like to paste into a larger one. Ex: the image i loaded has 9920 width, 7085 height. I would like to place it in the middle of a larger one (10594 width, 7387 height). I do have all border calculation ready ([larger width - original width / 2] , same goes for height).

But i don't know how to do it using MagickImage. Here's the max i got:

private void drawInkzone(MagickImage loadedImage, List<string>inkzoneAreaInformation, string filePath)
    {
        unitConversion converter = new unitConversion();
        List<double> inkZoneInfo = inkZoneListFill(inkzoneAreaInformation);
        float DPI = getImageDPI(filePath);
        double zoneAreaWidth_Pixels = converter.mmToPixel(inkZoneInfo.ElementAt(4), DPI);
        double zoneAreaHeight_Pixels = converter.mmToPixel(inkZoneInfo.ElementAt(5), DPI);
        using (MagickImage image = new MagickImage(MagickColor.FromRgb(255, 255, 255), Convert.ToInt32(zoneAreaWidth_Pixels), Convert.ToInt32(zoneAreaHeight_Pixels)))
        {
            //first: defining the larger image, with a white background (must be transparent, but for now its okay)
            using (MagickImage original = loadedImage.Clone())
            {
                //Cloned the original image (already passed as parameter)

            }
        }

Here's the max i got. In order to achieve this, i used the following post:

How to process only one part of image by ImageMagick?

And i'm not using GDI+ because i'll be always working with larger TIFF files (big resolutions), and GDI+ tends to throw exceptions (Parameter not valid, out of memory) when it can't handle everything (i loaded three images with an resolution like that, and got out of memory).

Any help will be kindly appreciate, thanks. Pablo.

2

There are 2 best solutions below

0
On

I managed to accomplish what i needed. Cool that i didn't had to calculate borders.

Here's the code:

       private void drawInkzone(MagickImage loadedImage, List<string>inkzoneAreaInformation, string filePath)
    {
        unitConversion converter = new unitConversion();
        List<double> inkZoneInfo = inkZoneListFill(inkzoneAreaInformation); //Larger image information
        float DPI = getImageDPI(filePath);
        double zoneAreaWidth_Pixels = converter.mmToPixel(inkZoneInfo.ElementAt(4), DPI); //Width and height for the larger image are in mm , converted them to pixel
        double zoneAreaHeight_Pixels = converter.mmToPixel(inkZoneInfo.ElementAt(5), DPI);//Formula (is: mm * imageDPI) / 25.4
        using (MagickImage image = new MagickImage(MagickColor.FromRgb(0, 0, 0), Convert.ToInt32(zoneAreaWidth_Pixels), Convert.ToInt32(zoneAreaHeight_Pixels)))
        {
            //first: defining the larger image, with a white background (must be transparent, but for now its okay)
            using (MagickImage original = loadedImage.Clone())
            {
                //Cloned the original image (already passed as parameter)
                image.Composite(loadedImage, Gravity.Center);
                image.Write(@"C:\DI_PLOT\whatever.png");                  
            }
        }

Hope this helps someone :)

0
On

You could either Composite the image on top of a new image with the required background or you could Clone and Extent if with the required background. In the answer from @Pablo Costa there is an example for Compositing the image so here is an example on how you could extent the image:

private void drawInkzone(MagickImage loadedImage, List<string> inkzoneAreaInformation, string filePath)
{
  unitConversion converter = new unitConversion();
  List<double> inkZoneInfo = inkZoneListFill(inkzoneAreaInformation);
  float DPI = getImageDPI(filePath);
  double zoneAreaWidth_Pixels = converter.mmToPixel(inkZoneInfo.ElementAt(4), DPI);
  double zoneAreaHeight_Pixels = converter.mmToPixel(inkZoneInfo.ElementAt(5), DPI);
  using (MagickImage image = loadedImage.Clone())
  {
    MagickColor background = MagickColors.Black;
    int width = (int)zoneAreaWidth_Pixels;
    int height = (int)zoneAreaHeight_Pixels;
    image.Extent(width, height, Gravity.Center, background);
    image.Write(@"C:\DI_PLOT\whatever.png");
  }
}