fast code to add rounded corners

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?".
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: fast IM code to add rounded corners to image with known

Post by fmw42 »

Clearly I can store the four corner masks in .mpc to save on recomputation.
It would seem to me better to store the whole mask than just the corner images. But I have not tested that for speed.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: fast IM code to add rounded corners to image with known

Post by NicolasRobidoux »

@Fred: Isn't the fact that it is immediately reloaded canceling the added safety? If I understand correctly, the +deleted image and the mpr:corner images are identical.

P.S.: Maybe I understand: Sure, but one is in the "stack", and the other one is in "memory". Things don't jump out of memory, but stack clutter may bite you later.

P.S.2: Given that the rest of the operation is so short, I think I'll live dangerously!

P.S.3: Thank you Fred!
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: fast IM code to add rounded corners to image with known

Post by fmw42 »

P.S.: Maybe I understand: Sure, but one is in the "stack", and the other one is in "memory". Things don't jump out of memory, but stack clutter may bite you later.
I believe that is correct.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: fast IM code to add rounded corners to image with known

Post by NicolasRobidoux »

I don't really understand what's going on internally (no time for careful RTFM/RTSC) but I still maintain that the +delete is unnecessary, because what's deleted is immediately put back on the stack: May as well leave it there, and skip the "load it back" step.
Last edited by NicolasRobidoux on 2012-03-15T05:21:26-07:00, edited 2 times in total.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: fast IM code to add rounded corners to image with known

Post by NicolasRobidoux »

I'm happy with my earlier solution, so I'll quit while I'm ahead.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: fast IM code to add rounded corners to image with known

Post by fmw42 »

NicolasRobidoux wrote:I don't really understand what's going on internally (no time for careful RTFM/RTSC) but I still maintain that the +delete is unnecessary, because what's deleted is immediately put back on the stack.
Well that was what Anthony explained to me. But I will leave that for him to clarify further. Perhaps I will learn a thing or two more.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: fast IM code to add rounded corners to image with known

Post by anthony »

NicolasRobidoux wrote:RE: the flip/flop way of generating the mask:

Wouldn't it go faster to first create an intermediate mask which has two rounded corners, and then flipping the result once to get the other two?

That is: one corner -> two corners -> four corners instead of adding one corner at a time, which adds one more step?
For a technqiue where you generate one mask for the whole image. Yes that is the faster way (in operational steps) See First example in Rounding Corners
http://localhost/anthony/im/thumbnails/#rounded

But for very LARGE images, generating a large mask has a very large memory cost (for the mask image) and also a large processing cost (most of the mask image does nothing). In that case overlaying a small image to each corner separateally becomes the faster and more memory efficent technique.
See Second example in Rounding Corners.

Don't forget to also look at the advanced techniques
Border with Rounded Corners (whole image mask)
http://www.imagemagick.org/Usage/thumbn ... ded_border
and Fancy Corner Overlays (added borders + seperate corner overlays)
http://www.imagemagick.org/Usage/thumbnails/#fancy
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: fast IM code to add rounded corners to image with known

Post by fmw42 »

Anthony,

Note he is creating the mask once for use with many many images and saving it in .mpc format. So I would expect that would be faster than creating the corners each time. However, he raised a question about just saving the corner images as .mpc and then using them.

Note he also raised the question about the +delete when using mpr: images.

Fred
Last edited by fmw42 on 2012-03-14T19:39:27-07:00, edited 1 time in total.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: fast IM code to add rounded corners to image with known

Post by anthony »

NicolasRobidoux wrote:I'm trying to learn more IM syntax so I can try a few other things. Only operating on the corner pixels does appear to be something that could run faster (at least on large images).

Question: Isn't the +delete a waste in the following code?
What it seems to be doing is creating a triangle corner, storing it in mpr:triangle, deleting it (P.S. actually deleting the already loaded copy) and then immediately reloading it.

Why not (code not deleting first corner) gives exactly the same result and it appears to be a smidgeon faster.
Yes it is faster (though not by much).
The reason I save to MPR then delete it, the re-load the MPR image again, is that the basically the same code is then used for each of the four corners. Basically I divided the operations into 'setup' or 'initialization' operations set, and then a 'apply to image' operations set.

This may not be important for a single image, but what if you are using convert to add corners to multiple images. For example... in psuedo-code operation blocks (generated by a script)

Code: Select all

   convert
          initialise options
          read image, add corners, write image, delete 
          read image, add corners, write image, delete
          read image, add corners, write image, delete
          ...
          null:
This is posible in IMv6, by havign a shell generate the "convert" command in a loop
For examples of this see Warping Image Animation Example scripts in...
http://www.imagemagick.org/Usage/warping/#animations

In IMv7 the above could generated and feed directly to a IM command via a pipeline, instead of using one very long "convert" command line.

Also in IMv7 "mogrify" will have new (optional) 'styles', whcih will let you seperate the single IMv6 mogrify operations list into three seperate sections, for more efficent handling.
  • initialization options (to setup IM before reading first image)
    IM will reset back to this state before reading each image.
  • the per-image options to be applied. That is the 'loop' part of mogrify with an implied read, write
  • the list of images to be operated on (usally "in-place" on disk but does not have to be)
Note that mogrify will still handle IMv6 style, but the new style will be much more versitile and will even allow you to handle multiple images and composition. For example: IMv7 "mogrify will allow you overlay logos, watermarks, or even corner masks and framing images.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: fast IM code to add rounded corners to image with known

Post by anthony »

NicolasRobidoux wrote:Clearly I can store the four corner masks in .mpc to save on recomputation.

Still struggling with adapting the flip/flop code to jpg output (my input and output images never have transparency) and rounded corners. I'm that ignorant w.r.t. complex IM commands. :(
It can be done. But the overlay masking image should overlay the 'background color', and use transparency for the part of the image you want preserved. The thrid "rounded corners" example is one such method, and draws a greyscale mask, whcih is then converted to a alpha 'shaped mask' for the overlaying.
http://www.imagemagick.org/Usage/thumbnails/#rounded

Of course you can also do this with individual composited corners too.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: fast IM code to add rounded corners to image with known

Post by NicolasRobidoux »

Thank you very much Anthony. (Struck with the flu, so I move and think like a slug :?)
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: fast IM code to add rounded corners to image with known

Post by NicolasRobidoux »

Another way.

First create four "masks":

Code: Select all

convert -size 16x16 xc:none -draw "fill white rectangle 0,0 15,15 fill black circle 15,15 15,0" -background white -alpha shape RoundCorner8NW.mpc
convert RoundCorner8NW.mpc -flop RoundCorner8NE.mpc
convert RoundCorner8NW.mpc -flip RoundCorner8SW.mpc
convert RoundCorner8NE.mpc -flip RoundCorner8SE.mpc
Store these were convenient (ramdisk ;-)), and use to create the frame:

Code: Select all

convert RogerRabbit.mpc \
RoundCorner8NW.mpc -gravity northwest -composite \
RoundCorner8NE.mpc -gravity northeast -composite \
RoundCorner8SW.mpc -gravity southwest -composite \
RoundCorner8SE.mpc -gravity southeast -composite \
-quality 70 FramedRogerRabbit.jpg
Last edited by NicolasRobidoux on 2012-03-15T12:39:53-07:00, edited 5 times in total.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: fast IM code to add rounded corners to image with known

Post by NicolasRobidoux »

Now, let's rebenchmark (I've svn up and recompiled IM since my first benchmarks).

Code: Select all

convert -size 400x320 xc:white RogerRabbit.mpc \( -size 400x320 xc:black -fill white -draw "roundRectangle 0,0 399,319 8,8" \) -composite -flatten -quality 70 FramedRogerRabbit.jpg
0.042s

Code: Select all

convert -size 400x320 xc:black -fill white -draw "roundRectangle 0,0 399,319 8,8" RoundFrame400x320.mpc
convert -size 400x320 xc:white RogerRabbit.mpc  RoundFrame400x320.mpc -composite -flatten -quality 70 FramedRogerRabbit.jpg
0.028s

Code: Select all

convert -size 16x16 xc:none -draw "fill white rectangle 0,0 15,15 fill black circle 15,15 15,0" -background white -alpha shape -strip RoundCorner8NW.mpc
convert RoundCorner8NW.mpc -flop -strip RoundCorner8NE.mpc
convert RoundCorner8NW.mpc -flip -strip RoundCorner8SW.mpc
convert RoundCorner8NE.mpc -flip -strip RoundCorner8SE.mpc
convert RogerRabbit.mpc \
RoundCorner8NW.mpc -gravity northwest -composite \
RoundCorner8NE.mpc -gravity northeast -composite \
RoundCorner8SW.mpc -gravity southwest -composite \
RoundCorner8SE.mpc -gravity southeast -composite \
-quality 70 FramedRogerRabbit.jpg
0.016s and this one does not require any knowledge of the image to be framed (exept of course that the image should be big enough for the rounded corners, which means, I suppose, that it's at least 32x32 or so) and the same exact code and masks work with all images to be framed, independently of their dimensions. :-) The rounded corners look better too.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: fast IM code to add rounded corners to image with known

Post by NicolasRobidoux »

Here is something rather intriguing: Using flip and flop to produce the four corner masks leads to slightly larger .mpc (but not .cache: of course) files.

Produce with flip/flop as above, with three of the four generated by flip/flopping and earlier one:
ls -al RoundCorner*.mpc
-rw-rw-r-- 1 nicolas nicolas 314 2012-03-15 16:27 RoundCorner8NE.mpc
-rw-rw-r-- 1 nicolas nicolas 286 2012-03-15 16:25 RoundCorner8NW.mpc
-rw-rw-r-- 1 nicolas nicolas 314 2012-03-15 16:27 RoundCorner8SE.mpc
-rw-rw-r-- 1 nicolas nicolas 314 2012-03-15 16:27 RoundCorner8SW.mpc

Produced directly using the code below

Code: Select all

convert -size 16x16 xc:none -draw "fill white rectangle 0,0 15,15 fill black circle 15,15 15,0" -background white -alpha shape -strip RoundCorner8NW.mpc
convert -size 16x16 xc:none -draw "fill white rectangle 0,0 15,15 fill black circle 0,15 15,15" -background white -alpha shape -strip RoundCorner8NE.mpc
convert -size 16x16 xc:none -draw "fill white rectangle 0,0 15,15 fill black circle 15,0 15,15" -background white -alpha shape -strip RoundCorner8SW.mpc
convert -size 16x16 xc:none -draw "fill white rectangle 0,0 15,15 fill black circle 0,0 15,0" -background white -alpha shape -strip RoundCorner8SE.mpc
convert RogerRabbit.mpc \
RoundCorner8NW.mpc -gravity northwest -composite \
RoundCorner8NE.mpc -gravity northeast -composite \
RoundCorner8SW.mpc -gravity southwest -composite \
RoundCorner8SE.mpc -gravity southeast -composite \
-quality 70 FramedRogerRabbit.jpg
which is now "nicolas' best".

ls -al RoundCorner8*mpc
-rw-rw-r-- 1 nicolas nicolas 286 2012-03-15 16:37 RoundCorner8NE.mpc
-rw-rw-r-- 1 nicolas nicolas 286 2012-03-15 16:37 RoundCorner8NW.mpc
-rw-rw-r-- 1 nicolas nicolas 286 2012-03-15 16:37 RoundCorner8SE.mpc
-rw-rw-r-- 1 nicolas nicolas 286 2012-03-15 16:37 RoundCorner8SW.mpc

In addition, the resulting final images are not exactly identical (in pixel content, I mean), which makes me wonder whether the masks are also different. (Not that I care much.)
Last edited by NicolasRobidoux on 2012-03-15T14:51:44-07:00, edited 3 times in total.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: fast IM code to add rounded corners to image with known

Post by NicolasRobidoux »

The final images are only slightly different. It mildly makes sense that, esp. in Q8, you get a slightly different result computing directly and flip/flopping, esp. since I don't exactly use operations which are mirror images of each other.
Post Reply