This commit is contained in:
James Jackson-South 2022-02-06 17:00:17 +11:00
Родитель 5b4f379b81
Коммит 38a9444920
2 изменённых файлов: 8 добавлений и 8 удалений

Просмотреть файл

@ -2,11 +2,11 @@
Starting with ImageSharp 2.0, the library uses large (~4MB) discontigous chunks of unmanaged memory to represent multi-megapixel images. Internally, these buffers are heavily pooled to reduce OS allocation overhead. Unlike in ImageSharp 1.0, the pools are automatically trimmed after a certain amount of allocation inactivity, releasing the buffers to the OS, making the library more suitable for applications that do imaging operations in a periodic manner.
The buffer allocation and pooling behavior is implemented by @"SixLabors.ImageSharp.Memory.MemoryAllocator" which is being used through @"SixLabors.ImageSharp.Configuration"'s @"SixLabors.ImageSharp.Configuration.MemoryAllocator" property within the library, therefore it's configurable and replacable by the user.
The buffer allocation and pooling behavior is implemented by @"SixLabors.ImageSharp.Memory.MemoryAllocator" which is being used through @"SixLabors.ImageSharp.Configuration"'s @"SixLabors.ImageSharp.Configuration.MemoryAllocator" property within the library, therefore it's configurable and replaceable by the user.
### Configuring the pool size
By deault, the maximum pool size is platform-specific, defaulting to a portion of the available physical memory on 64 bit coreclr, and to a 128MB constant size on other platforms / runtimes.
By default, the maximum pool size is platform-specific, defaulting to a portion of the available physical memory on 64 bit coreclr, and to a 128MB constant size on other platforms / runtimes.
We highly recommend to go with these defaults, however in certain cases it might be desirable to override the pool limit. In such cases the most straightforward solution is to replace the memory allocator globally:
@ -19,7 +19,7 @@ Configuration.Default.MemoryAllocator = MemoryAllocator.Create(new MemoryAllocat
### Enforcing contiguous buffers
Certain interop use cases may require multi-megapixel images to be layed out contiguously in memory so a single buffer pointer can be passed to native API-s. This can be enforced by setting @"SixLabors.ImageSharp.Configuration"'s @"SixLabors.ImageSharp.Configuration.PreferContiguousImageBuffers" to `true`. Note that this will lead to significantly reduced pooling that may hurt overall processing throughput. We don't recommend to flip this option globabally. Instead, you can enable it locally for the image instances that are expected to be contigous:
Certain interop use cases may require multi-megapixel images to be layed out contiguously in memory so a single buffer pointer can be passed to native API-s. This can be enforced by setting @"SixLabors.ImageSharp.Configuration"'s @"SixLabors.ImageSharp.Configuration.PreferContiguousImageBuffers" to `true`. Note that this will lead to significantly reduced pooling that may hurt overall processing throughput. We don't recommend to flip this option globally. Instead, you can enable it locally for the image instances that are expected to be contiguous:
```C#
Configuration customConfig = Configuration.Default.Clone();

Просмотреть файл

@ -9,7 +9,7 @@ using (Image<Rgba32> image = new Image<Rgba32>(400, 400))
}
```
The indexer is an order of magnitude faster than the `.GetPixel(x, y)` and `.SetPixel(x, y)` methods of `System.Drawing`, but individual `[x, y]` indexing has inherent overhead compared to more sophisticated approaches demnonstrated below.
The indexer is an order of magnitude faster than the `.GetPixel(x, y)` and `.SetPixel(x, y)` methods of `System.Drawing`, but individual `[x, y]` indexing has inherent overhead compared to more sophisticated approaches demonstrated below.
### Efficient pixel manipulation
If you want to achieve killer speed in your pixel manipulation routines, you should utilize the per-row methods. These methods take advantage of the [`Span<T>`-based memory manipulation primitives](https://www.codemag.com/Article/1807051/Introducing-.NET-Core-2.1-Flagship-Types-Span-T-and-Memory-T) from [System.Memory](https://www.nuget.org/packages/System.Memory/), providing a fast, yet safe low-level solution to manipulate pixel data.
@ -42,7 +42,7 @@ image.ProcessPixelRows(accessor =>
ref Rgba32 pixel = ref pixelRow[x];
if (pixel.A == 0)
{
// overwrite the pixel referenced by 'ref Rgba32 pixel':
// Overwrite the pixel referenced by 'ref Rgba32 pixel':
pixel = transparent;
}
}
@ -66,10 +66,10 @@ foreach (ref Rgba32 pixel in pixelRow)
Need to process two images simultaneously? Sure!
```C#
// Extract sub-region of sourceImage as a new image
// Extract a sub-region of sourceImage as a new image
private static Image<Rgba32> Extract(Image<Rgba32> sourceImage, Rectangle sourceArea)
{
Image<Rgba32> targetImage = new (sourceArea.Width, sourceArea.Height);
Image<Rgba32> targetImage = new(sourceArea.Width, sourceArea.Height);
int height = sourceArea.Height;
sourceImage.ProcessPixelRows(targetImage, (sourceAccessor, targetAccessor) =>
{
@ -154,6 +154,6 @@ using (var image = Image.LoadPixelData<Rgba32>(rgbaBytes, width, height))
### OK nice, but how do I get a single pointer or span to the underlying pixel buffer?
That's the neat part, youd don't. 🙂 Well ... normally.
That's the neat part, you don't. 🙂 Well ... normally.
For custom image processing code written in C#, we highly recommend to use the methods introduced above, since ImageSharp buffers are discontiguous by default. However, certain interop use-cases may require to overcome this limitation, and we support that. Please read the [Memory Management](memorymanagement.md) section for more information.