4

I want to convert iPhone HEIC-images to Jpeg files. Since there are a lot of images, I handle this with Parallel.ForEach

string[] files = Directory.GetFiles(inputPath, "*.heic");
Parallel.ForEach(files, new ParallelOptions() { MaxDegreeOfParallelism = 16 }, file =>
{
    using (var image = new MagickImage(file))
    {
        Console.WriteLine(file);
        // Save frame as jpg
        image.Write(Path.Combine(output, Path.GetFileNameWithoutExtension(file) + ".jpg"));
        image.Dispose();
    }
});

BUT when I set the MaxDegreeOfParallelism = 16 there comes this error (8 or below seems to work)

ImageMagick.MagickCorruptImageErrorException: Insufficient memory (case 4) 

long:

enter image description here

Unbehandelte Ausnahme: System.AggregateException: Mindestens ein Fehler ist aufgetreten. ---> ImageMagick.MagickCorruptImageErrorException: Insufficient memory (case 4) `T:\Imageconversion\output\IMG_0934.jpg' @ error/jpeg.c/JPEGErrorHandler/343    bei ImageMagick.MagickExceptionHelper.Check(IntPtr exception)    bei ImageMagick.MagickImage.NativeMagickImage.WriteFile(MagickSettings settings)    bei ImageMagick.MagickImage.Write(String fileName)    bei HEIC_Conversion.Program.<>c__DisplayClass2.<Main>b__1(String file)    bei System.Threading.Tasks.Parallel.<>c__DisplayClass30_0`2.<ForEachWorker>b__0(Int32 i)    bei System.Threading.Tasks.Parallel.<>c__DisplayClass17_0`1.<ForWorker>b__1() bei System.Threading.Tasks.Task.InnerInvoke()    bei System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)    bei System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)    --- Ende der internen Ausnahmestapelüberwachung ---    bei System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)    bei System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)    bei System.Threading.Tasks.Task.Wait()    bei System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Func`4 bodyWithLocal, Func`1 localInit, Action`1 localFinally)    bei System.Threading.Tasks.Parallel.ForEachWorker[TSource,TLocal](TSource[] array, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Action`3 bodyWithStateAndIndex, Func`4 bodyWithStateAndLocal, Func`5 bodyWithEverything, Func`1 localInit, Action`1 localFinally)    bei System.Threading.Tasks.Parallel.ForEachWorker[TSource,TLocal](IEnumerable`1 source, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Action`3 bodyWithStateAndIndex, Func`4 bodyWithStateAndLocal, Func`5 bodyWithEverything, Func`1 localInit, Action`1 localFinally)    bei System.Threading.Tasks.Parallel.ForEach[TSource](IEnumerable`1 source, ParallelOptions parallelOptions, Action`1 body)

enter image description here

Anyway there is enough memory left: (marked the exception with red arrow)

Impostor
  • 2,080
  • 22
  • 43
  • 1
    is the process running as 32-bit (x86) or 64-bit? – Marc Gravell May 28 '21 at 08:40
  • 1
    Are you process 32 or 64-bit? Check "Prefer 32 bit" checkbox in the project settings. – Serg May 28 '21 at 08:41
  • it looks like most of the actual implementation here is P/Invoke to an `extern` with unmanaged code, and that's where the stack-trace leads; if this isn't as simple as "switch to 64-bit", this might be a case of "talk to the maintainers" – Marc Gravell May 28 '21 at 08:43
  • 2
    changed it to 64 bit and it seems to work - just testetd it with `MaxDegreeOfParallelism = 20` and 200 images – Impostor May 28 '21 at 08:46
  • @MarcGravell I just tried to find the reason why 64 bit works - the limitation of 32 bit is 4GB of RAM usage,but the application only took between 1 and 2GB. Why was this 64 bit setting so obvious to you? – Impostor May 28 '21 at 10:16
  • 3
    @Impostor anything approaching or over 2GB gets unstable on 32-bit; the reason 64-bit was obvious is that you were getting "insufficient memory" errors with lots of available memory. Keep in mind that image processing often requires big chunks of *contiguous* memory, and in a 32-bit space, that gets hard *really quickly* for large enough chunks. – Marc Gravell May 28 '21 at 10:33
  • @MarcGravell thanks for clarification didn't know that – Impostor May 28 '21 at 10:57

0 Answers0