Consuming output from -print

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?".
Post Reply
Mihamix
Posts: 13
Joined: 2018-01-21T06:12:33-07:00
Authentication code: 1152

Consuming output from -print

Post by Mihamix » 2018-01-27T15:34:49-07:00

Hi All,

I'm trying to process folders containing jpg using mogrify to autocrop, resize, rotate if needed and apply watermark to them - on the server side in a client-server context.
However, as folders contain several thousands of high-res images it takes quite some time - therefore I need to provide progress feedback.
mogrify is started as a process on the server side, and my thought was to print a "." and a new line every time an image is processed. Tested it in command window and was working well...
Wrote the class library, but when trying to consume the output (standard output that is) from the process I don't receive anything...
Is the print printing to the standard error? Or is there any trick to capture it?
Also, in the manual it says that the print evaluates the expression and displays on the console; what expressions are available? Could it print the currently processed filename or the number of the file it has handled?

Any help would be appreciated...

Many thanks in advance,
Miham
ImageMagick 7.0.7 Q16 HDRI x64 DL on Win Srv 2008 R2

User avatar
fmw42
Posts: 23600
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Consuming output from -print

Post by fmw42 » 2018-01-27T16:39:14-07:00

-print or -format %... info: can list string formats or %[fx:...] expressions. See https://www.imagemagick.org/script/escape.php and https://www.imagemagick.org/Usage/transform/#fx. If you want to list filenames see %f. But to get a progress, I would recommend writing a script loop over each image in your directory and using convert rather than mogrify.

But if you use mogrify, you can do

Code: Select all

mogrify -format tif -print "%f\n" *.png
image.png
lena.png

As you see it returns the image filename to the terminal. Or you can redirect to a file. Since mogrify processes one image at a time, I do not see how you will get the progress number of images processed. But you can echo that from a script loop.

Please always profile your ImageMagick version and platform/OS when asking questions.

Mihamix
Posts: 13
Joined: 2018-01-21T06:12:33-07:00
Authentication code: 1152

Re: Consuming output from -print

Post by Mihamix » 2018-01-27T16:54:25-07:00

fmw42 wrote:
2018-01-27T16:39:14-07:00
-print or -format %... info: can list string formats or %[fx:...] expressions. See https://www.imagemagick.org/script/escape.php and https://www.imagemagick.org/Usage/transform/#fx. If you want to list filenames see %f. But to get a progress, I would recommend writing a script loop over each image in your directory and using convert rather than mogrify.

But if you use mogrify, you can do

Code: Select all

mogrify -format tif -print "%f\n" *.png
image.png
lena.png

As you see it returns the image filename to the terminal. Or you can redirect to a file. Since mogrify processes one image at a time, I do not see how you will get the progress number of images processed. But you can echo that from a script loop.

Please always profile your ImageMagick version and platform/OS when asking questions.
Cool, that's brilliant! Many thanks!
I don't really need the number of the file to be honest, as I have written my dll in a way so that I count the number of lines with the dot (my print command was -print ".\n"), but I reckon I can change it now to -print ".%f\n", and will be able to get the currently processed filename, too.
I'm rather executing mogrify to process batches than having to spawn tens of thousands of processes instead, to be honest. Do you see any reason why the individual execution is better than the batched? I'm particularly interested from performance perspective, tbh.

However, I've tested so many versions with different escaping, and whilst I have positively tested that my DLL _does_ capture the std output and counts them properly when it contains dots followed by newline, I am yet to have success with mogrify.
Might either overescape or underescape, but no luck so far...

my command line is:

Code: Select all

mogrify -print "." -trim -fuzz 10% -background white -resize 650x650 -rotate "90<" -gravity center -draw "image src-over 0,0 0,0 ‘Watermarks\C.png’" -path TestTmp\m "Source\Original\*.jpg"
fmw42 wrote:
2018-01-27T16:39:14-07:00
Please always profile your ImageMagick version and platform/OS when asking questions.
Where shall I add that to my profile?
I'm using ImageMagick-7.0.7-21-Q16-HDRI-x64 (dyn linked) on Windows Server 2008R2
ImageMagick 7.0.7 Q16 HDRI x64 DL on Win Srv 2008 R2

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

Re: Consuming output from -print

Post by snibgo » 2018-01-27T16:58:28-07:00

Mihamix wrote:Wrote the class library, ...
Perhaps that gives a clue. Is your library buffered output? If it is, try flushing the buffer.
snibgo's IM pages: im.snibgo.com

Mihamix
Posts: 13
Joined: 2018-01-21T06:12:33-07:00
Authentication code: 1152

Re: Consuming output from -print

Post by Mihamix » 2018-01-27T17:11:00-07:00

snibgo wrote:
2018-01-27T16:58:28-07:00
Mihamix wrote:Wrote the class library, ...
Perhaps that gives a clue. Is your library buffered output? If it is, try flushing the buffer.
I see what you say, but I'm not sure if I have missed something... Could be...

This is the code snippet starting up the process

Code: Select all

                imageProcess = new Process();
                imageProcess.StartInfo.UseShellExecute = false;
                imageProcess.StartInfo.RedirectStandardOutput = true;
                imageProcess.StartInfo.RedirectStandardError = true;
                imageProcess.StartInfo.FileName = command_filename;
                imageProcess.StartInfo.Arguments = arguments;
                imageProcess.StartInfo.WorkingDirectory = workingDir;
                imageProcess.OutputDataReceived += new DataReceivedEventHandler(imageProcess_outputDataReceived);
                imageProcess.ErrorDataReceived += new DataReceivedEventHandler(imageProcess_errorDataReceived);
                imageProcess.Exited += new EventHandler(imageProcess_Exited);
                imageProcess.Start();
                imageProcess.BeginOutputReadLine();
                imageProcess.BeginErrorReadLine();

The event handler method for std out is (assuming -print ".%f\n" in the command line):

Code: Select all

        private void imageProcess_outputDataReceived(object sendingProcess, DataReceivedEventArgs outLine)
        {
            if (!String.IsNullOrEmpty(outLine.Data))
            {
                if (outLine.Data[0] == '.')
                {
                    currentFileCount++;
                    currentImageFile = outLine.Data.Substring(1, outLine.Data.Length - 1);
                }
            }
        }
ImageMagick 7.0.7 Q16 HDRI x64 DL on Win Srv 2008 R2

User avatar
dlemstra
Posts: 1475
Joined: 2013-05-04T15:28:54-07:00
Authentication code: 6789
Contact:

Re: Consuming output from -print

Post by dlemstra » 2018-01-28T02:42:50-07:00

@Mihamix It looks like you are using C#, you might also want to take at the C# ImageMagick library that I created: https://github.com/dlemstra/Magick.NET
.NET + ImageMagick = Magick.NET https://github.com/dlemstra/Magick.NET, @MagickNET, Donate

Post Reply