WrapMemory Pointer and Resizing #1576
-
I have really large image data (2 GB) in the form of span. I'm using the following code to do WrapMemory, but it seems the Resize mutate operation is incompatible. Is there any way to do the following without having to copy this massive image? I don't have access to the bytes so I'm stuck with var stream = ...;
Span<SixLabors.ImageSharp.PixelFormats.L16> pixels = ...; // cast our image's pixel span to ImageSharp pixel type
var width = ...;
var height = ...;
unsafe
{
fixed (void* pixPtr = pixels)
{
using var image=
SixLabors.ImageSharp.Image.WrapMemory<SixLabors.ImageSharp.PixelFormats.L16>(pixPtr,
width, height);
image.Mutate(img => img.Resize(width / 4, height / 4, KnownResamplers.Bicubic));
image.SaveAsJpeg(stream);
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Internally, ResizeProcessor works by creating a new buffer so it can work as destination, then in the end swapping that buffer with the original one. The reason to do this is that otherwise certain cases would be really hard to implement. For example imagine, you are resizing the image into the bottom right corner of the same image as destination. Without copying you would overwrite the bottom right part of the source image while resizing the top rows. What we could consider is to relax the following requirement to be ImageSharp/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroup{T}.cs Lines 189 to 193 in 08b0320 But note, that What I recommend instead, is to use Clone(...): using var image= Image.WrapMemory<SixLabors.ImageSharp.PixelFormats.L16>(pixPtr, width, height);
// Only 2GB / (4*4) = 125 MB extra space is allocated, no unnecessary copies are done:
using Image resized = image.Clone(img => img.Resize(width / 4, height / 4, KnownResamplers.Bicubic));
resized.SaveAsJpeg(stream); I think it's a pretty straightforward solution, and one of the main reasons for the |
Beta Was this translation helpful? Give feedback.
Internally, ResizeProcessor works by creating a new buffer so it can work as destination, then in the end swapping that buffer with the original one. The reason to do this is that otherwise certain cases would be really hard to implement. For example imagine, you are resizing the image into the bottom right corner of the same image as destination. Without copying you would overwrite the bottom right part of the source image while resizing the top rows.
What we could consider is to relax the following requirement to be
>=
instead of expecting strict equality, so a smaller buffer can be copied into a larger one when swapping is not possible:ImageSharp/src/ImageSharp/Memory/Discontiguous…