How to create a Bitmap greater than 9999 pixels

3

When trying to create a Bitmap I realized that I can not create with the size I wanted, I need an image with 16581375 x 1 .

>
Bitmap image = new Bitmap(16581375, 1);
image.Save("Path aqui");

As I try to run this code it returns me the error:

  

System.Runtime.InteropServices.ExternalException: 'Generic GDI + error.'

    
asked by anonymous 01.01.2018 / 18:19

1 answer

1

As this SOen response this is a GDI + limitation imposed by Windows.

"GDI" creates a view of the memory-mapped file for bitmap pixel data. This makes it very efficient, the bitmaps tend to be large, and the MMF helps keep the pixel data out of the paging file. The RAM pages can simply be discarded and re-read from the file.

Windows restricts the size of the view to an MMF, that is, the amount of data in the file that can be directed directly, As documented in this MSDN article :

  

The size of a file mapping object that is supported by a named file is limited by disk space. The size of a file view is limited to the largest contiguous block available from non-reserved virtual memory. This is at most 2GB or less of virtual memory already reserved by the process.

"The largest continuous block available" is the constraint on a 32-bit process, it tends to rotate around ~ 600MB, give or receive. The 2GB limit goes into a 64-bit process.

Technically, "GDI" can ignore this limit when rescaling the view. But no, the LockBits() method (also heavily used internally) would be inefficient and very strange to use.

To use larger bitmaps, you can use the GDI + successor that is the WIC ( Windows Imaging Component ).

Available in .NET through the System.Windows.Media.Imaging namespace.

Memory limit

The size limit is due to the limit of virtual memory, there is no amount of memory on your machine, remember other programs and even windows server (or your local windows) already use much of the memory, which may be limiting, see an example of how much memory is available:

using System;
using System.Diagnostics;

public class MemoryAvaliable
{
    static void Main(string[] args)
    {

        //Em Bytes
        using (PerformanceCounter perfCounter = new PerformanceCounter("Memory", "Available Bytes"))
        {
            long availableMemory = Convert.ToInt64(perfCounter.NextValue());
            Console.WriteLine(availableMemory);
        }

        //Em MB
        using (PerformanceCounter perfCounter = new PerformanceCounter("Memory", "Available MBytes"))
        {
            long availableMemory = Convert.ToInt64(perfCounter.NextValue());
            Console.WriteLine(availableMemory);
        }
    }
}
    
01.01.2018 / 19:53