Multiple writes and pipes in a single command

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?".
dannygreer
Posts: 19
Joined: 2016-05-31T18:06:11-07:00
Authentication code: 1151

Multiple writes and pipes in a single command

Post by dannygreer »

I'm trying to write multiple size and watermarked versions from a single tif and have found the following to be the fastest way to do that:

Code: Select all

convert input.tif -depth 8 -flatten +matte -quality 82 \
	-write mpr:tmp -write fullsize.jpg +delete \
	mpr:tmp -intent relative -black-point-compensation -profile sRGB.icc +profile "!iptc,*" -resize 2000x2000 -write mpr:tmp -write xlarge.jpg +delete \
	mpr:tmp -resize 1100x800 -write mpr:tmp -write large.jpg +delete \
	mpr:tmp -tile watermark.png -draw "rectangle 0,0 1100,800" -write large_wm.jpg +delete \
	mpr:tmp -resize 450x450 -write mpr:tmp -write medium.jpg +delete  \
	mpr:tmp -tile watermark.png -draw "rectangle 0,0 450,450" -write medium_wm.jpg +delete \
	mpr:tmp -resize 150x150 -write mpr:tmp -write small.jpg +delete \
	mpr:tmp -tile watermark.png -draw "rectangle 0,0 150,150" -write small_wm.jpg +delete \
	mpr:tmp -resize 75x75 -write mpr:tmp -write xsmall.jpg +delete \
	mpr:tmp -tile watermark.png -draw "rectangle 0,0 75,75" xsmall_wm.jpg
I'm certain there are other improvements that can be made but my primary concern is that in testing, I have found the draw method of adding a tiled watermark to be far slower than using the composite command, so would like to update my command to something resembling:

Code: Select all

convert input.tif -depth 8 -flatten +matte -quality 82 \
	-write mpr:tmp -write fullsize.jpg +delete \
	mpr:tmp -intent relative -black-point-compensation -profile sRGB.icc +profile "!iptc,*" -resize 2000x2000 -write mpr:tmp -write xlarge.jpg +delete \
	mpr:tmp -resize 1100x800 -write mpr:tmp -write large.jpg +delete \
		mpr:tmp miff:- |\
        		composite -quality 82 -tile watermark.png - large_wm.jpg \
	mpr:tmp -resize 450x450 -write mpr:tmp -write medium.jpg +delete  \
		mpr:tmp miff:- |\
        		composite -quality 82 -tile watermark.png - medium_wm.jpg \
	mpr:tmp -resize 150x150 -write mpr:tmp -write small.jpg +delete \
		mpr:tmp miff:- |\
        		composite -quality 82 -tile watermark.png - small_wm.jpg \
	mpr:tmp -resize 75x75 -write mpr:tmp -write xsmall.jpg +delete \
		mpr:tmp miff:- |\
        		composite -quality 82 -tile watermark.png - xsmall_wm.jpg
The problem appears to be that once the first pipe happens, the convert stops.
--
Danny
Version: ImageMagick 6.9.4-3 Q16 x86_64
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Multiple writes and pipes in a single command

Post by fmw42 »

You should not need to pipe anything in either method. The reason you have to pipe is that you are using the very old composite. You should do everything with convert (... -composite). See http://www.imagemagick.org/Usage/layers/#composition

Then use parenthesis processing. See http://www.imagemagick.org/Usage/basics/#parenthesis and http://www.imagemagick.org/Usage/files/#write

You can use clones or mpr within parentheses.
dannygreer
Posts: 19
Joined: 2016-05-31T18:06:11-07:00
Authentication code: 1151

Re: Multiple writes and pipes in a single command

Post by dannygreer »

There is no documentation of a -tile option that can be used with -composite. I just ran a quick test and was unable to tile a watermark using -composite. This is my test that failed:

Code: Select all

convert input.tif -depth 8 -flatten +matte -quality 82 \
   -write mpr:tmp -write fullsize.jpg +delete \
   mpr:tmp -intent relative -black-point-compensation -profile sRGB.icc +profile -strip -resize 2000x2000 -write mpr:tmp -write xlarge.jpg +delete \
   mpr:tmp -resize 1100x800 -write mpr:tmp -write large.jpg  \
      \( -composite  -tile watermark.png large_wm.jpg \)
--
Danny
Version: ImageMagick 6.9.4-3 Q16 x86_64
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Multiple writes and pipes in a single command

Post by snibgo »

You first piped example has this:

Code: Select all

convert input.tif {blah} \
-write mpr:tmp -write fullsize.jpg +delete \
mpr:tmp {blah} -write mpr:tmp -write xlarge.jpg +delete \
mpr:tmp -resize 1100x800 -write mpr:tmp -write large.jpg +delete \
mpr:tmp miff:- |\
composite -quality 82 -tile watermark.png - large_wm.jpg \
mpr:tmp -resize 450x450 -write mpr:tmp -write medium.jpg +delete \
mpr:tmp miff:- |\ {blah...}
When an IM command tries to read an mpr: that hasn't been written, IM doesn't report this as an error. (I think it should.)

Your "composite" tries to read mpr:tmp. Then it writes mpr:tmp, and reads it again. I don't know what it would find in the first read, but it probably isn't what you want.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Multiple writes and pipes in a single command

Post by fmw42 »

dannygreer wrote:There is no documentation of a -tile option that can be used with -composite. I just ran a quick test and was unable to tile a watermark using -composite.
There are many ways to tile an image. See http://www.imagemagick.org/Usage/canvas/#tile especially the ones using convert syntax.

If you post your input and tile images so we can test your first command to see what it is doing, we might be able to give you a better method.
dannygreer
Posts: 19
Joined: 2016-05-31T18:06:11-07:00
Authentication code: 1151

Re: Multiple writes and pipes in a single command

Post by dannygreer »

snibgo wrote:Your "composite" tries to read mpr:tmp. Then it writes mpr:tmp, and reads it again. I don't know what it would find in the first read, but it probably isn't what you want.
I'm writing the mpr:tmp because I'm writing several versions of jpegs in a single command, between each resize, I rewrite the mpr for efficiency because it only gets smaller. I guess what you're saying is that the first time I write the mpr and then read it again is not necessary? I didn't want to write the actions performed after saving to mpr and before recalling the mpr to the next version.

Thanks for the tip, I will take a closer look at removing the first save and recall, it will probably speed up the command significantly.
--
Danny
Version: ImageMagick 6.9.4-3 Q16 x86_64
dannygreer
Posts: 19
Joined: 2016-05-31T18:06:11-07:00
Authentication code: 1151

Re: Multiple writes and pipes in a single command

Post by dannygreer »

fmw42 wrote:
dannygreer wrote:There is no documentation of a -tile option that can be used with -composite. I just ran a quick test and was unable to tile a watermark using -composite.
There are many ways to tile an image. See http://www.imagemagick.org/Usage/canvas/#tile especially the ones using convert syntax.

If you post your input and tile images so we can test your first command to see what it is doing, we might be able to give you a better method.
I'm looking to accomplish exactly what is at http://www.imagemagick.org/Usage/annota ... mark_image under the heading "Tiled" but for the reasons mentioned in this thread without the use of the, apparently outdated, 'composite' command.

Instead of:

Code: Select all

composite -dissolve 15 -tile \
            wmark_image.png   logo.jpg  wmark_tiled.jpg
It would be?:

Code: Select all

convert -composite -dissolve 15 -tile \
            wmark_image.png   logo.jpg  wmark_tiled.jpg
--
Danny
Version: ImageMagick 6.9.4-3 Q16 x86_64
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Multiple writes and pipes in a single command

Post by fmw42 »

try this with the images from that reference

Code: Select all

convert logo.jpg \( -size 180x180 tile:wmark_image.png \) \
-compose dissolve -define compose:args=15 -composite result.png
see the last section at http://www.imagemagick.org/script/compose.php for dissolve and the -define above it. Also http://www.imagemagick.org/script/comma ... php#define
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Multiple writes and pipes in a single command

Post by snibgo »

dannygreer wrote:I guess what you're saying is that the first time I write the mpr and then read it again is not necessary?
No, I'm saying that reading an mpr before you've written it won't work.

Perhaps you think that writing to an mpr in a convert, then reading that mpr in a composite, will work. It won't. Mpr is in memory, and private to that command. It sn't written to a disk file.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Multiple writes and pipes in a single command

Post by fmw42 »

I think what snigbo is getting at (and I overlooked before) is that mpr is local to a single Imagemagick (convert) command and will not be passed via a pipe. I do not think composite even supports writing or reading an mpr. I think mpr is restricted to convert (magick). Though I have not tested it. That is why I suggested you need to change your command to use one big convert command.
dannygreer
Posts: 19
Joined: 2016-05-31T18:06:11-07:00
Authentication code: 1151

Re: Multiple writes and pipes in a single command

Post by dannygreer »

snibgo wrote:No, I'm saying that reading an mpr before you've written it won't work.

Perhaps you think that writing to an mpr in a convert, then reading that mpr in a composite, will work. It won't. Mpr is in memory, and private to that command. It sn't written to a disk file.
Oh, I see now. Yes, I was trying to come back out of the composite and continue my convert. I'm going to attempt to proceed with the most recent of advice of fmw42 and integrate this into my first code block

Code: Select all

convert logo.jpg \( -size 180x180 tile:wmark_image.png \) \
-compose dissolve -define compose:args=15 -composite result.png
.

Many thanks for the help.
--
Danny
Version: ImageMagick 6.9.4-3 Q16 x86_64
dannygreer
Posts: 19
Joined: 2016-05-31T18:06:11-07:00
Authentication code: 1151

Re: Multiple writes and pipes in a single command

Post by dannygreer »

fmw42 wrote:try this with the images from that reference

Code: Select all

convert logo.jpg \( -size 180x180 tile:wmark_image.png \) \
-compose dissolve -define compose:args=15 -composite result.png
see the last section at http://www.imagemagick.org/script/compose.php for dissolve and the -define above it. Also http://www.imagemagick.org/script/comma ... php#define
In this example the -size is the area of the area that the watermark should cover specified in pixels. I tried 100% and that failed, I would like to apply this to many different image sizes would I first have to use identify to get the size or is there a way to specify that I would like the entire image covered? This raised another question. If I'm covering 100% of multiple sized images with the tiled watermark, I would want to specify either a size or the number of tiles that cover the image so that they're proportional to the image, I plan to use an svg for the watermark.
--
Danny
Version: ImageMagick 6.9.4-3 Q16 x86_64
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Multiple writes and pipes in a single command

Post by fmw42 »

In IM 6, you will need to compute the size from the input image and pass that as a variable. In IM 7, you can do that in the same command.

Code: Select all

magick logo.jpg -size "%wx%h" tile:wmark_image.png \
-compose dissolve -define compose:args=15 -composite result.png
If you need to compute number of tiles, etc, that may be best be done in separate fx calculations and then compute the tiled watermark image, etc and then composite it. But you can replace the %wx%h with a more complicated %[fx:...]x%[fx:...] where you can do math computations on w and h as desired. I do not fully understand what you want to do, so I cannot give you a definitive answer.
dannygreer
Posts: 19
Joined: 2016-05-31T18:06:11-07:00
Authentication code: 1151

Re: Multiple writes and pipes in a single command

Post by dannygreer »

fmw42 wrote:In IM 6, you will need to compute the size from the input image and pass that as a variable. In IM 7, you can do that in the same command.

Code: Select all

magick logo.jpg -size "%wx%h" tile:wmark_image.png \
-compose dissolve -define compose:args=15 -composite result.png
If you need to compute number of tiles, etc, that may be best be done in separate fx calculations and then compute the tiled watermark image, etc and then composite it. But you can replace the %wx%h with a more complicated %[fx:...]x%[fx:...] where you can do math computations on w and h as desired. I do not fully understand what you want to do, so I cannot give you a definitive answer.
Hey, I'm trying to apply watermarks to a number of different sized jpegs created from one original. The original could be any size, so I need the watermark to be proportional to the image. If my original image is 2000x2000px and the watermark is 100x100 it will look tiny compared to the same watermark applied to an image that is just 200x200px.

Here is how I'm currently doing it but end up with huge watermarks on the tiny images and tiny watermarks on the huge images:

Code: Select all

convert CMYKimage.tif -depth 8 -flatten -quality 100 -write mpr:776715 -write hpr.jpg \
        -tile watermark.png -draw "rectangle 0,0 ," -write hpr_wm.jpg +delete \
    mpr:776715 -quality 82 -resize 2000x2000">" -write lpr.jpg +delete \
    mpr:776715 -quality 82 -intent relative -black-point-compensation -profile sRGB.icc +profile "!iptc,*" -resize 1100x1100">" -write mpr:776715 -write scr.jpg \
        -tile watermark.png -draw "rectangle 0,0 1100,1100" -write scr_wm.jpg +delete mpr:776715 -quality 82 -resize 450x450">" -write mpr:776715 -write pre.jpg \
        -tile watermark.png -draw "rectangle 0,0 450,450" -write pre_wm.jpg +delete \
    mpr:776715 -quality 82 -resize 150x150">" -write mpr:776715 -write thm.jpg \
        -tile watermark.png -draw "rectangle 0,0 150,150" -write thm_wm.jpg +delete \
    mpr:776715 -quality 82 -resize 75x75">" -write mpr:776715 -write col.jpg \
        -tile watermark.png -draw "rectangle 0,0 75,75" col_wm.jpg
I'm thinking that the fastest method would be to compute the size of the original, create a tiled layer to apply to that image and write the jpeg of just the layer without the watermark, then write both layers, resize, write the image layer, then both layers and so on.
--
Danny
Version: ImageMagick 6.9.4-3 Q16 x86_64
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Multiple writes and pipes in a single command

Post by snibgo »

I notice that CMYKimage.tif is resized to 1100x1100, then that is resized to 450x450, then that is resized to 150x150, and finally that is resized to 150x150. So the final image has been subjected to four resizes.

You may get noticeably better quality if you resize CMYKimage.tif or an mpr of that image to each of the four sizes. However, this will be slower.

I don't understand what you want for the watermarks, so can't comment on that.
snibgo's IM pages: im.snibgo.com
Post Reply