Page 2 of 3

Re: Multiple writes and pipes in a single command

Posted: 2016-06-03T09:46:32-07:00
by fmw42
I suspect that you need to resize the watermark image to the appropriate size for each of your scaled down versions of your main image.

Re: Multiple writes and pipes in a single command

Posted: 2016-06-03T09:52:57-07:00
by snibgo
If that's the requirement, than adding the watermark once to the full-size image, then resizing that down to the various sizes, seems a better idea.

Re: Multiple writes and pipes in a single command

Posted: 2016-06-03T10:15:07-07:00
by fmw42
snibgo wrote:If that's the requirement, than adding the watermark once to the full-size image, then resizing that down to the various sizes, seems a better idea.
Good point, snibgo! But he may still need to resize the watermark to properly fit the full size image.

Re: Multiple writes and pipes in a single command

Posted: 2016-06-03T14:22:00-07:00
by dannygreer
snibgo wrote: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 did experiment with that and the speed cost wasn't worth the indistinguishable gain in quality. Speed is my primary concern as I have a million large images that I need to perform this action on. resize, write to mpr, write to jpeg, delete, load mpr was the fastest method I found, although as I type that I'm wondering why it is necessary to delete then load again. I'm not resizing the compressed jpeg (as far as I can tell) but the raw data.
snibgo wrote:I don't understand what you want for the watermarks, so can't comment on that.
With the watermarks, I'm trying to add a watermark that appears consistent proportional to the image. Take the example
Example 1. Image
Example 2. Image The same watermark applied to a smaller image appears proportionally much bigger.
Example 3. Image I would like the watermark to look like this on the resized images matching the original.

The difference in these small images is not significant, but if you we're to apply that watermark to an image 8000x8000 there would be hundreds of almost invisible tiles compared to the single tile that doesn't even fit on example 2.

Re: Multiple writes and pipes in a single command

Posted: 2016-06-03T14:39:39-07:00
by snibgo
So it seems you want to apply the watermark to the largest image, and then resize the result. Would that give you what you want? Then your command can be much simpler. Your input seems to be CMYK, but you want some output to be sRGB, and watermark.png is sRGB, so that would take some thought.

Re: Multiple writes and pipes in a single command

Posted: 2016-06-03T16:50:30-07:00
by fmw42
You are resizing the image too many times. That costs you in speed. Snibgo is correct, overlay the watermark on the big image one time and use -scale to resize to each size you want and write to jpg output. No need to write to mpr:. If you don't want to scale the large image each time, then scale each level to the next size smaller.

Try this adjust the various scale percents as desired:

Code: Select all

convert logo: \( wmark_image.png -scale 200% -write mpr:tile +delete \) \
\( -size 640x480 tile:mpr:tile \) \
-compose dissolve -define compose:args=15 -composite +write logo1.jpg \
-scale 50% +write logo2.jpg \
-scale 50% +write logo3.jpg \
-scale 50% logo4.jpg
As snibgo said if your input image and/or watermark are CMYK or unknown, then you may have to test for colorspace/type before hand and use profiles to convert to sRGB before doing the -compose dissolve. Thus you would have two commands or have variables that insert the appropriate profile conversion commands in one command line. The variables could be empty if no conversion is needed when both are already sRGB.

Re: Multiple writes and pipes in a single command

Posted: 2016-06-03T17:24:38-07:00
by dannygreer
snibgo wrote:So it seems you want to apply the watermark to the largest image, and then resize the result. Would that give you what you want? Then your command can be much simpler. Your input seems to be CMYK, but you want some output to be sRGB, and watermark.png is sRGB, so that would take some thought.
I want to write both unwatermarked and watermarked versions of the images so it is not as simple as just applying the watermark and scaling down. I'm wondering if there is a way that I can save both the tiled watermark and the image as a single mpr then tell convert to write only the image layer, both layers composited then resize, rewrite smaller mpr and go again.

Good point on the CMYK, my input images vary, most are RGB. I'm using a CMYK for testing because they are the most troublesome. I'm thinking that my watermark needs to be a vector such as svg to better scale and load quickly on large images. Now I'm wondering if it would be possible to save a vector alpha channel only that might not have an issue with the difference between RGB and CMYK.

Do you have any idea if ImageMagick converts the vector to raster as soon as it loads it into memory or only once written? An SVG that is immediately rasterized upon load is pointless an may as well be a raster image to start with, I'll just have to make it large enough for the biggest possible image size.

Re: Multiple writes and pipes in a single command

Posted: 2016-06-03T17:29:15-07:00
by dannygreer
fmw42 wrote:You are resizing the image too many times. That costs you in speed. Snibgo is correct, overlay the watermark on the big image one time and use -scale to resize to each size you want and write to jpg output. No need to write to mpr:. If you don't want to scale the large image each time, then scale each level to the next size smaller.

Try this adjust the various scale percents as desired:

Code: Select all

convert logo: \( wmark_image.png -scale 200% -write mpr:tile +delete \) \
\( -size 640x480 tile:mpr:tile \) \
-compose dissolve -define compose:args=15 -composite +write logo1.jpg \
-scale 50% +write logo2.jpg \
-scale 50% +write logo3.jpg \
-scale 50% logo4.jpg
As snibgo said if your input image and/or watermark are CMYK or unknown, then you may have to test for colorspace/type before hand and use profiles to convert to sRGB before doing the -compose dissolve. Thus you would have two commands or have variables that insert the appropriate profile conversion commands in one command line. The variables could be empty if no conversion is needed when both are already sRGB.
I did not realize that I could just keep scaling and saving jpegs without writing and reading the mpr's, this may be much faster, I'll test. The issue with this method is that it is only creating the watermarked versions, I need each version in both watermarked and unwatermarked in each size.

Re: Multiple writes and pipes in a single command

Posted: 2016-06-03T18:00:59-07:00
by snibgo
dannygreer wrote:... if ImageMagick converts the vector to raster as soon as it loads it into memory ...
Yes, that's how it works. Beware that some SVG files have lines "one pixel" thick, so these can disappear when resized down.
dannygreer wrote:... most are RGB. I'm using a CMYK for testing because they are the most troublesome.
That's wise. Assuming you want all outputs to be sRGB, I would do as Fred suggests: read the input, then have an environment variable. This would be set to blank when the input is sRGB, or the appropriate conversion if it isn't.

You can have as many mpr's as you want. (Well, I've never tried more than ten or so, but I think the only limit is your memory.)

Re: Multiple writes and pipes in a single command

Posted: 2016-06-03T18:20:41-07:00
by dannygreer
dannygreer wrote:... if ImageMagick converts the vector to raster as soon as it loads it into memory ...
Yes, that's how it works. Beware that some SVG files have lines "one pixel" thick, so these can disappear when resized down.[/quote]
Sounds like I may as well just save a large png if they're immediately rasterized. I thought I was saving myself loading time and memory with a svg. The load time is probably true, but the rasterization must take some extra time, then the memory used will be the same.
snibgo wrote:You can have as many mpr's as you want. (Well, I've never tried more than ten or so, but I think the only limit is your memory.)
I don't want many mpr's, I was hoping that I could save both the image and the tiled watermark in the same mpr so that I could resize them together, referencing them something like mpr:tmp[0] and mpr:tmp[1]?

Thanks again for all of the amazing help, I've been reading the docs for a week and not finding clear answers.

Re: Multiple writes and pipes in a single command

Posted: 2016-06-03T18:56:19-07:00
by snibgo
You can call them anything you want, but "[" and "]" have special meanings. "mpr:tmp[0]" would mean the zero'th image in the multi-image mpr named "tmp".

Personally, I try to use meaningful names, and I use capital letters, eg "mpr:WMARK" and "mpr:FULL_SIZE". When I come back to that code after six months, it gives me a fighting chance of understanding it.

Re: Multiple writes and pipes in a single command

Posted: 2016-06-03T19:11:04-07:00
by fmw42
Beware that some SVG files have lines "one pixel" thick, so these can disappear when resized down.
So you may need to rasterize the svg file for each resolution you need so you do not lose the thin lines. But of course that will slow things down some.

Re: Multiple writes and pipes in a single command

Posted: 2016-06-03T19:13:10-07:00
by dannygreer
snibgo wrote:You can call them anything you want, but "[" and "]" have special meanings. "mpr:tmp[0]" would mean the zero'th image in the multi-image mpr named "tmp".

Personally, I try to use meaningful names, and I use capital letters, eg "mpr:WMARK" and "mpr:FULL_SIZE". When I come back to that code after six months, it gives me a fighting chance of understanding it.
A multi-image mpr was what I was going for, that way I can resize it with a single -resize rather than having to resize the image and the watermarks separately. I'm working on putting all of this together with a more real world example and will post the results.

Re: Multiple writes and pipes in a single command

Posted: 2016-06-03T19:15:25-07:00
by fmw42
This will resize both input and watermarked images at the same time and write them out as a pair of jpgs marked -0 and -1.

Code: Select all

convert logo: \( wmark_image.png -scale 200% -write mpr:tile +delete \) \
\( -size 640x480 tile:mpr:tile \) \
\( -clone 0 -clone 1 -compose dissolve -define compose:args=15 -composite \) \
-delete 1 +write logo1.jpg \
-scale 50% +write logo2.jpg \
-scale 50% +write logo3.jpg \
-scale 50% logo4.jpg

Re: Multiple writes and pipes in a single command

Posted: 2016-06-06T12:29:01-07:00
by dannygreer
fmw42 wrote:This will resize both input and watermarked images at the same time and write them out as a pair of jpgs marked -0 and -1.
This is very efficient, but I lost control over the filenames and the ability to tweak the code to only output either just the watermarked, just the unwatermarked or both. I've been trying, unsuccessfully, all weekend to edit the code to give me what I want. I've added my (apparently incorrect) understanding of what each of these lines does as comments.

Code: Select all

convert image.jpg \( MyWatermark.png -write mpr:tile +delete \) \ #open image.jpg (open MyWatermark.png, write mpr named 'tile' and delete MyWatermark.png from memory) leaving image.jpg as layer 0 and mpr:tile in memory
\( -size 640x480 tile:mpr:tile \) \ # tile mpr:tile over an area of 640x480px leaving it in memory as layer 1
\( -clone 0 -clone 1 -compose dissolve -define compose:args=15 -composite \) \ # composite layer 1 onto layer 0
-delete 1 +write logo1.jpg \ # delete layer 1 and write the remaining two layers as jpegs
-scale 50% +write logo2.jpg \ # scale and save two more jpegs
-scale 50% +write logo3.jpg \ #...
-scale 50% logo4.jpg
My version of this using https://www.dropbox.com/s/morqff3ch35xt ... .jpg?raw=1 and https://www.dropbox.com/s/u4uqocbxfcd3x ... .png?raw=1 is:

Code: Select all

convert image.jpg \( MyWatermark.png -write mpr:comp +delete \) \ #open image.jpg (open MyWatermark.png, write mpr named 'comp' and delete MyWatermark.png from memory) leaving image.jpg as layer 0 and mpr:comp in memory
\( -size 4000x4000 tile:mpr:comp -write mpr:comp +delete \) \ # tile mpr:comp over an area of 4000x4000px rewrite mpr:comp with the tiled version and delete version in memory
\( -clone 0 -clone 1 -compose dissolve -define compose:args=15 -composite \) \ # composite layer 1 onto layer 0
-delete 1 -write mpr:comp \ #delete watermark layer leaving unwatermarked and comp as 0 and 1
mpr:comp[0] -write image1.jpg +delete \ #load unwatermarked layer 0 from mpr:comp and write as jpeg
mpr:comp[1] -write image1_wm.jpg +delete \ #load watermarked layer 1 from mpr:comp write jpeg and delete
mpr:comp -size 1100x1100 -write mpr:comp +delete \ #resize both layers to 1100x1100 and delete what is in memory ready to load a single layer
mpr:comp[0] -write image2.jpg +delete \ #load unwatermarked layer 0 from mpr:comp and write as jpeg
mpr:comp[1] image2_wm.jpg \ #load watermarked layer 1 from mpr:comp write jpeg
I'm getting no matches found for mpr:comp[0] or mpr:comp[1].

If I write the comp immediately after the -composite command, i do get a watermarked image, but the transparent background on the png appears white.