With convert, when using -draw "image operator x0,y0 w,h filename", if x0 is negative then the content of filename is drawn as if x0 were x0 + 1. The same thing happens to y0.
I was busy quietly tiling a canvas when this bug decided to eat the edges of my topward and leftward tiles. A canvas being rectangular, my tiles being diamond-shaped, and me not wanting to let any area of the said canvas uncovered, I was led to draw some tiles at negative offsets. This particular case being encumbered with irrelevant details, here is a straight-to-the-point test, executed in IM 6.6.0-6 2010-03-16 Q16 OpenMP on both Ubuntu 9.10 and Windows XPSP3 :
A black square was drawn multiple times at regular intervals on a white background so as to obtain a checkerboard pattern, the success of this operation was a priori guaranteed by the regularity of the intervals used.
Code: Select all
convert \
-size 4x4 xc:black \
-write mpr:tile +delete \
-size 10x10 xc:white \
-draw "image SrcIn 6,6 4,4 'mpr:tile'" \
-draw "image SrcIn 2,2 4,4 'mpr:tile'" \
-draw "image SrcIn -2,-2 4,4 'mpr:tile'" \
-draw "image SrcIn -2,6 4,4 'mpr:tile'" \
-draw "image SrcIn 6,-2 4,4 'mpr:tile'" \
-filter Point -resize 100x100 \
no_tile_should_overlap.png
no_tile_should_overlap.png should have been :
http://pixfarm.net/upload/2/originals/e7/e7c3a5c45acdd05f717b9b7f8d371495.png
.. instead, it was :
http://pixfarm.net/upload/2/originals/91/912404768c3719fc79868589a8be070a.png
.. unfortunately not true to its name ; any tile drawn at a negative offset was off by 1 pixel before resizing.
The first idea that came to mind was that the formula I used to compute the intervals was wrong, but such was not the case.
Now focusing on -draw, I twiddled with it and found that drawing an image at -1,-1 is the same as drawing it at 0,0 on IM 6.6.0-6 as shown by :
Code: Select all
convert \
-size 100x100 \
\( xc:blue -draw "image SrcIn 0,0 70,46 'rose:'" \) \
\( xc:blue -draw "image SrcIn -1,-1 70,46 'rose:'" \) \
-compose Difference -composite -unique-colors \
-format " - expected result : not 0,\n - actual result : %[mean]." \
info:
- expected result : not 0,
- actual result : 0.
That is, no difference found.
Now, an unexpected behavior does not always a bug make.
I was then wondering if the behavior of -draw could be explained by a convention - then unknown to me - whereby the offset 0 would be considered equal to the offset -1. This would be in a way analogous to what happens to the numbering of years in the gregorian calendar (no year 'zero'). So I've tested it :
Code: Select all
convert \
-size 2x2 -virtual-pixel Tile \
xc:white \
-fill red -draw "point 0,0" -fill green -draw "point 1,0" \
-fill blue -draw "point 0,1" -fill yellow -draw "point 1,1" \
-format " - expected result : yellow,\n - actual result : %[pixel:p{-1,-1}]." \
info:
- expected result : yellow,
- actual result : yellow.
In other words, the offset -1 does differ from the offset 0 which is rather good news intuition-wise but not consistent with how the operator -draw behaves.
At this point, I was curious to see how another geometry-dependent operator reacts when fed some negative offset, so I tested -crop :
Code: Select all
convert \
-size 4x4 \
xc: \
-crop "4x4-3-3" \
-format " - expected result : 1x1,\n - actual result : %wx%h." \
info:
- expected result : 1x1,
- actual result : 1x1.
If -crop was behaving like -draw geometry-wise, the actual result would have been a faulty 2x2.
All this leads me to think that there is indeed a bug in how -draw "image ... interprets a negative offset.
Once one knows of this bug, an immediate workaround consists in subtracting 1 to any negative offset fed to -draw "image ....
This does the job for throwaway commands, but it's good to be aware that the day when this bug will be fixed, the scripts with this workaround will then overcompensate.
Thanks for your attention !