ASP.NET and thumbnail creation

Feb 26, 2015 at 8:31 PM
We have an ASP.NET / Web API site that accepts uploads and creates thumbnails from them. I have pieced-together various optimization ideas from here and in your Documentation. Some of those include things like...
settings.SetDefine(MagickFormat.Jpeg, "size", "1400x1400");
when reading the file and using "Strip()" on the image before creating thumbnails. Also, we use Parallel.ForEach since it creates more than one thumbnail for each image. Finally, it uses
MagickGeometry geo = new MagickGeometry(longsidesection[key] + "x" + longsidesection[key]);
tempimg.Resize(geo);
as part of the Parallel code.

The AppPool is set to use four processes; we receive many, many files so more threads, more memory, etc., seems necessary. This is in a virtualized server and "ImageMagick.MagickNET.UseOpenCL" reports "true", but I can't confirm or deny if OpenCL is being used or not. If so, it would only be on the processor level.

Anyway, is there anything else I should know about how Magick.NET instantiates itself in this setup? Is the object static? Does the Parallel call run effectively in .NET thread pools?

Some of this is subjective and/or hard to know, but any pointers you have would be great. Thanks!
Coordinator
Feb 26, 2015 at 9:56 PM
Edited Feb 26, 2015 at 9:56 PM
If it is reporting true it is most likely using OpenCL on your processor. But this is only used for a limited set of operations.

You might want to consider to use the Q8 version of Magick.NET to lower the memory usage. This will lower the quality of your images but you will have to test that for yourself if it is an issue in your situation. And I would suggest you to choose either the x86 version or the x64 version instead of the AnyCPU version. There is some extra overhead if you use the AnyCPU version.

Previous versions of Magick.NET did some things in static constructors but this has been removed because it was difficult to manage. There is one internal ImageMagick method that is called when the dll is loaded but that will not cause any issues in a multi-threaded environment. The most important thing is that you should create clones if you are performing multiple operations on one image at the same time. But that should be common sense :) Below is a good and a bad example
int[] sizes = new int[] { 200, 800, 1400 };

using (MagickImage image = new MagickImage())
{
  // Bad kitty
  Parallel.ForEach(sizes, (size) =>
  {
    image.Resize(size, size); // This operates on the same image
    image.Write(size + ".jpg");
  });

  // Good boy
  Parallel.ForEach(sizes, (size) =>
  {
    using (MagickImage clone = image.Clone())
    {
      clone.Resize(size, size);
      clone.Write(size + ".jpg");
    }
  });
}
p.s. You will get the JpegReadDefines class that you can use for 'jpeg:size' in the next release of Magick.NET. This will make the code more cleaner :)