AnonPowershellGuy1
AnonPowershellGuy1

Reputation: 41

Pass Memory Stream Image directly into ImageMagick command in PowerShell

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:

Used Files

ImageMagick Version:

IM7 Properties

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

Answers (1)

jcupitt
jcupitt

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

Related Questions