Process images to stdout immediately after they are read from stdin

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
barabanus
Posts: 10
Joined: 2018-11-21T07:58:29-07:00
Authentication code: 1152

Process images to stdout immediately after they are read from stdin

Post by barabanus »

Hello!

I've got a movie production pipeline which has a screenshots generator that produces a sequence of PPM to STDOUT. I pipe it to `convert` for postprocessing and then to `ffmpeg` to create the final movie without creation of intermediate files.

The command line looks like this:

Code: Select all

./generate-screenshots.py | convert ppm:- -distort resize 50% png:- | ffmpeg -f image2pipe -framerate 60 -i - movie.mp4
The problem is that ImageMagick accumulates input images until it runs out of memory (aka `No space left on device`).

Is it possible to make ImageMagick push images to STDOUT immediately after it had been read from STDIN and processed? I see no reason for ImageMagick to accumulate images.
Last edited by barabanus on 2020-03-16T12:09:23-07:00, edited 2 times in total.

snibgo
Posts: 13034
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Process images to stdout immediately after they are read from stdin

Post by snibgo »

barabanus wrote:Is it possible to make ImageMagick push images to STDOUT immediately after it had been read from STDIN and processed?
Yes. That's what "magick mogrify" does. Or simply "mogrify" if you use v6.
snibgo's IM pages: im.snibgo.com

barabanus
Posts: 10
Joined: 2018-11-21T07:58:29-07:00
Authentication code: 1152

Re: Process images to stdout immediately after they are read from stdin

Post by barabanus »

snibgo wrote:
2020-03-16T10:44:25-07:00
Yes. That's what "magick mogrify" does. Or simply "mogrify" if you use v6.
Well, I switched `convert` to `mogrify`, but there were no any difference.

snibgo
Posts: 13034
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Process images to stdout immediately after they are read from stdin

Post by snibgo »

"mogrify" has a different syntax to "convert". What was your exact command?

This works fine for me, on Windows 8.1:

Code: Select all

%IMG7%magick toes.png -duplicate 200 png:- | %IMG7%magick mogrify -resize 50% png:- | %IMG7%ffmpeg -f image2pipe -framerate 60 -i - movie.mp4
Looking at the console, and using "taskmgr" I can see that ffmeg starts immediately, and well before before magick ends.
snibgo's IM pages: im.snibgo.com

barabanus
Posts: 10
Joined: 2018-11-21T07:58:29-07:00
Authentication code: 1152

Re: Process images to stdout immediately after they are read from stdin

Post by barabanus »

snibgo wrote:
2020-03-16T12:34:44-07:00
"mogrify" has a different syntax to "convert". What was your exact command?
Let me simplify the command to demonstrate there's no actual difference which I guess is a bug.

At first, let me start with this command:

Code: Select all

{ for i in $(seq 10000); do convert logo: ppm:-; done } | convert ppm:- -resize 50% png:- >/dev/null
As expected, it generates error `No space left`

But when I use `mogrify` the result is the same:

Code: Select all

{ for i in $(seq 10000); do convert logo: ppm:-; done } | magick mogrify -resize 50% png:- >/dev/null
It generates the same `No space left` error.
Last edited by barabanus on 2020-03-16T13:28:08-07:00, edited 2 times in total.

snibgo
Posts: 13034
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Process images to stdout immediately after they are read from stdin

Post by snibgo »

barabanus wrote:{ for i in $(seq 10000); do convert logo: ppm:-; done } | magick mogrify -resize 50% png:- >/dev/null
Your command is bad. The "convert" writes (to the pipe) in ppm format. The "magick mogrify" tries to read png format from the pipe.
snibgo's IM pages: im.snibgo.com

barabanus
Posts: 10
Joined: 2018-11-21T07:58:29-07:00
Authentication code: 1152

Re: Process images to stdout immediately after they are read from stdin

Post by barabanus »

snibgo wrote:
2020-03-16T13:17:36-07:00
The "convert" writes (to the pipe) in ppm format. The "magick mogrify" tries to read png format from the pipe.
Is there a way to make it read PPM? Because when I write a sequence of PNGs it discards all PNGs except the first one.

barabanus
Posts: 10
Joined: 2018-11-21T07:58:29-07:00
Authentication code: 1152

Re: Process images to stdout immediately after they are read from stdin

Post by barabanus »

Let me report: using PPM format with mogrify evokes `no space left` error in infinite loop:

Code: Select all

$ { while :; do convert logo: ppm:-; done } | mogrify -resize 50% ppm:- >/dev/null
mogrify: unable to write blob '/tmp/magick-8762pDAKAfwG9XPc': No space left on device @ error/blob.c/ImageToFile/2339.
But using MIFF format does not:

Code: Select all

{ while :; do convert logo: miff:-; done } | mogrify -resize 50% miff:- >/dev/null
Ok, this feature does work with MIFF image format. But it's internal ImageMagick format I'm not able to generate. I'll try to find a format which would work.

snibgo
Posts: 13034
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Process images to stdout immediately after they are read from stdin

Post by snibgo »

I suppose you have checked that you have plenty of free space on "/tmp"?
snibgo's IM pages: im.snibgo.com

User avatar
magick
Site Admin
Posts: 11254
Joined: 2003-05-31T11:32:55-07:00

Re: Process images to stdout immediately after they are read from stdin

Post by magick »

Your command is flawed. The mogrify scripts reads the MIFF images indefinitely. It won't move to the -resize until it gets an EOF. As it continually reads the images pushed from the convert command, it continues to consume resources until your host throws an exception (such as out of space). As your command runs, notice the ever growing temporarily file in /tmp/magick-*.

snibgo
Posts: 13034
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Process images to stdout immediately after they are read from stdin

Post by snibgo »

Oops, yes, I didn't spot that. IM can cope with hundreds of thousands of images, but not an infinite number.
snibgo's IM pages: im.snibgo.com

barabanus
Posts: 10
Joined: 2018-11-21T07:58:29-07:00
Authentication code: 1152

Re: Process images to stdout immediately after they are read from stdin

Post by barabanus »

Thank you for your comments. Unfortunately, I haven't found any supported image format which provides immediate image processing from STDIN to STDOUT without waiting for EOF from STDIN.

PNG is not an option because if you feed `mogrify` a sequence of PNGs it will discard all but the first.
PPM is not sent by `mogrify` to STDOUT until EOF from STDIN.

Other formats from `mogrify -list format` haven't worked too.

Is it expected behavior of `mogrify`? Should I request this feature or report the bug?

I found this command to be useful to detect whether mogrify generates data to STDOUT:

Code: Select all

{ while :; do convert logo: ppm:-; done } | mogrify -resize 50% ppm:- | ffmpeg -i - -f gif -y /dev/null

User avatar
magick
Site Admin
Posts: 11254
Joined: 2003-05-31T11:32:55-07:00

Re: Process images to stdout immediately after they are read from stdin

Post by magick »

Try `convert ppm:- -resize 50% ppm:-`. Does that make a difference?

barabanus
Posts: 10
Joined: 2018-11-21T07:58:29-07:00
Authentication code: 1152

Re: Process images to stdout immediately after they are read from stdin

Post by barabanus »

magick wrote:
2020-03-17T13:55:57-07:00
Try `convert ppm:- -resize 50% ppm:-`. Does that make a difference?
No, there's no difference. I expected from `mogrify` to process images immediately, but `mogrify` instead accumulates input images the same way `convert` does. Is it a bug of `mogrify`? Or should I ask for this functionality from `mogrify`?

User avatar
magick
Site Admin
Posts: 11254
Joined: 2003-05-31T11:32:55-07:00

Re: Process images to stdout immediately after they are read from stdin

Post by magick »

Your use case cannot be supported. Many image types permit multiple frames per image file (e.g. MIFF). For these coders, stdin is read indefinitely until an EOF is detected or an exception is thrown. Other image types only permit one image. For these coders, one image is read and the command moves to write the output image, however, the command-line syntax does not provide for restarting. A work-around is to place a loop around the screenshot generator, push the screen shot to a file, convert the file while resizing, then repeat for the next screenshot.

Locked