Reputation: 41
I am wanting to take an existing Memory Stream image and pass it into ImageMagick execute command directly without saving the file physically to the machine. The code below gives an example what I want to achieve, but I am receiving the following error below.
I do not want to install the entire ImageMagick package and trying to keep the footprint of what is needed very small.
*I would also like the ability to save the output of the ImageMagick command back into the memory stream again. The goal is to pass and use the memory stream entirely without ever saving to the machine
Files being used:
ImageMagick Version:
Code Example:
# Set running location
$Desktop = [Environment]::GetFolderPath("Desktop")
Set-Location "$Desktop\TestImageStream\Core"
# Take existing screnshot and pass as a memory stream
$memoryStream = New-Object System.IO.MemoryStream
$imageBytes = [System.IO.File]::ReadAllBytes("$PWD\TestScreenshot.png")
$memoryStream.Write($imageBytes, 0, $imageBytes.Length)
$memoryStream.Seek(0, 'Begin')
# ImageMagick execute command
.\magick.exe $memoryStream -fill rgb(0,0,0) -opaque rgb(113,113,113) -fuzz 96% TestScreenshotOutput.jpg
# Cleanup
$memoryStream.Dispose()
Error:
magick.exe: UnableToOpenBlob 'System.IO.MemoryStream': No such file or directory @ error/blob.c/OpenBlob/3569
magick.exe: NoDecodeDelegateForThisImageFormat `MEMORYSTREAM' @ error/constitute.c/ReadImage/746.
Upvotes: 1
Views: 147
Reputation: 11210
I realize you're asking about IM, but libvips can do what you want (true streaming of images). For example:
cat k2.jpg | vips flip stdin .png horizontal | cat >x.png
That's linux, but it'll work on win too.
The command is using cat
to send a JPG file as a bytestream down a pipe to the stdin of the vips
executable. The vips
exe is running the flip
operation with the horizontal
flag, reading from stdin and writing to the PNG format on stdout (enabled by not using a filename before the extension). The final cat
command is sending the bytestream to a file on disk.
The file will never be fully loaded to memory. Instead, it will be streamed from source to destination in a set of small blocks of pixels. If you have more than one CPU core, the pixels blocks will be evaluated in parallel for a useful speedup. Memory use is low, even for very large images (eg. 500,000 x 500,000 pixels).
I think your difficulty would be in translating those magick command flags. The vips CLI is pretty basic and implementing your fuzz and fill would be painful. You'd be better off using the .net binding for libvips and coding the command up there. The .net binding has the same nice properties of streaming, speed (maybe 20x faster than magick.net) and low memory use.
Upvotes: 1