[SOLVED] Better way to produce this png ?

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
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: [SOLVED] Better way to produce this png ?

Post by anthony »

I finally generated one that uses MVG though I was disappointed that you still can't really do more with gradient generation in MVG than what the vertical linear gradients, and need about 6 lines of MVg to just to that!.

OKay enough rant here is my latest result...
Image
The script to generate this allows the generated image (for the bar anyway) at any size. and any interger percentage.
and you can use any thickness of glass including 0 (none)
http://www.imagemagick.org/Usage/scripts/cylinder_bar
(give it a hour or so to appear -- and the update to the script)

As mentioned before my method for glass shading it tricky.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Totor
Posts: 10
Joined: 2010-11-26T13:04:13-07:00
Authentication code: 8675308

Re: [SOLVED] Better way to produce this png ?

Post by Totor »

thank's
I test this evening
Totor
Posts: 10
Joined: 2010-11-26T13:04:13-07:00
Authentication code: 8675308

Re: [SOLVED] Better way to produce this png ?

Post by Totor »

i'had a look to the script.
I must say that the result is pretty class :)
I do not understand the part MVG mainly because I do not have the basics of color management, canvas and so on...
also, Moreover, it seems slower using MVG :?
More than 1 sec for one at the beginning... after 2 changes (use of here-document instead of series of "echo", and aborting using an other instance of convert for the label)it down to 0,7 sec

next, i've work on mine and delete some shadow effects to the limit duration of creation.
this duration has been reduced to 0.3sec
Image
Image


it suits me !
thank's for all
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: [SOLVED] Better way to produce this png ?

Post by anthony »

I finally got around to writing up the examples that resulted from this discussion in IM Examples.

See Drawing, Cylinders
http://www.imagemagick.org/Usage/draw/#cylinders

Included is a pointer to the final script for generating the cylinder percentage bar, shown above.
http://www.imagemagick.org/Usage/scripts/cylinder_bar
The script is highly customizable, and generate most values from the desired final image size and colors wanted. A separate label generating function can be replaced with your own version.

If you use it, please contribute you changes and results.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Totor
Posts: 10
Joined: 2010-11-26T13:04:13-07:00
Authentication code: 8675308

Re: [SOLVED] Better way to produce this png ?

Post by Totor »

hi !

first of all, i've seen few weeks ago that you already post an element of the topic : http://www.imagemagick.org/script/comma ... essing.php

I never thought this script would have aroused such interest ..specially the use of roundrectangle to draw the cylinder ;)

i've work on your script to improve it's speed level : 1,5 sec to generate an icon 320*200 with the original script.
for this, I replaced all the "echo" by the syntax "here-document" and i remove the use of the second "convert" for the label (which was the black point).

now, generation time is decreased to 0,5 sec

speed is improved but the readability of the code is broken :/
now, I think I'll use this script because it is as fast as the one I kept and with more quality rendering

the script :

Code: Select all

#!/bin/bash
#
# cylinder_bar [percent [image]]
#
# Create a Cylindrical Percentage Bar and Label
#
# Method makes use of a shading overlay to generate more realisitic
# glass effects, especially at the ends of the 'glass' cylinder.
# It uses a drawn layers approach.
#   * White background layer (also providing the shape for later shadows)
#   * Draw over with green 3D cylinder of the right lenght
#   * Overlaid with a Transparent shaded glass effect.
#   * Final edge drawing of the glass cylinder
#   * Shadow effects of the whole result
#   * A shadowed label, generated and appended as a seperate image
#
####
#
# Anthony Thyssen   30 November 2010
#
# Using a technique for generating cylinders using rounded rectangles
# originally demonstrated by "Totor" on ImageMagick Users Forum...
#   http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&p=66100
#
# Warning this makes use of some fancy BASH shell script methods running
# sub-processes to generating the draw commands read into the primary command
# via bash inline named pipes. That is the construct "<(...)" is replaced by a
# named pipe, which is basically like a temporary file containing either drawing
# commands which were echo'ed, or a generated image.  Very tricky
#
percent="${1:-"50"}"

width=320
height=100

offset=10    # offset from edges, large enough to hold shadow
thickness=2  # glass thickness betwwn outside and colored inside cylinder

# The bar colors (before glass shading)
bar_color1=lime
bar_color2=green
bar_color3=green2  # end cap color (before glass shading)

background=White   # The final background color to use (can be "none")
                   # Alternatives:  Lavendar, Gainsboro, LemonChiffon

# Now calculate the other constants of the cyliner from the above.
glass_radius=$((height/2-offset))              # 40
glass_endcap=$((glass_radius/2))               # 20
glass_length=$((width-glass_radius-2*offset))  # 260 - excludes endcaps

bar_radius=$((glass_radius-2*thickness))
bar_endcap=$((bar_radius/2))
bar_length=$((glass_length*percent/100))


draw_base() {
cat<<EOF
  # Draw the background base of the glass cylinder
  #
  # Translate all coordinates to be relative to center of end
  translate $((offset+glass_endcap)) $((height/2))
  # Create white base image for all cylinders
  fill white stroke snow3 stroke-width 1
  roundrectangle -$glass_endcap,-$glass_radius \
                      $((glass_length+glass_endcap)),$glass_radius  \
                      $glass_endcap,$glass_radius
  # Draw left endcap ellipse of glass tube
  fill none  stroke snow3  stroke-width 1
  roundrectangle -$glass_endcap,-$glass_radius \
                      $glass_endcap,$glass_radius \
                      $glass_endcap,$glass_radius

  # Draw percentage bar on top of that base
  #
  # Gradient for percentage bar (a light gradient)
  # You really should have more control of the gradient generation than this!
  push defs
  push gradient 'bar_gradient' linear 0,0 0,$height
  stop-color $bar_color1   0%
  stop-color $bar_color2 100%
  pop gradient
  pop defs
  # Draw bar - main body
  push graphic-context
  fill 'url(#bar_gradient)' stroke snow4 stroke-width 1
  roundrectangle -$bar_endcap,-$bar_radius \
                      $((bar_length+bar_endcap)),$bar_radius \
                      $bar_endcap,$bar_radius
  pop graphic-context
  # Draw Bar - endcap
  translate $bar_length 0
  fill $bar_color3 stroke snow4 stroke-width 1
  roundrectangle -$bar_endcap,-$bar_radius \
                      $bar_endcap,$bar_radius  \
                      $bar_endcap,$bar_radius
EOF
}

draw_glass_shading() {
cat <<EOF
  # Draw a shading image for the glass transparency
  #
  # NOTE: The image generated is a shading mask.
  # As such black will be transparent, white will become opaque-black
  #
  # Translate all coordinates to be relative to center of end
  translate $((offset+glass_endcap)) $((height/2))
  # Gradient for glass shading of inside contents
  push defs
  push gradient 'glass_gradient' linear 0,0 0,$height
  stop-color 'black'   0%
  stop-color 'gray60' 100%
  pop gradient
  pop defs
  # Draw the shading overlay for glass cylinder
  push graphic-context
  fill 'url(#glass_gradient)'
  roundrectangle -$glass_endcap,-$glass_radius \
		$((glass_length+glass_endcap)),$glass_radius  \
		$glass_endcap,$glass_radius
  pop graphic-context
  # Now glass end a solid shade, almost fully transparent
  translate $glass_length 0
  fill gray20
  roundrectangle -$glass_endcap,-$glass_radius \
                      $glass_endcap,$glass_radius  \
                      $glass_endcap,$glass_radius
EOF
}

draw_glass_edges() {
cat <<EOF
  # Draw the final overlay of foreground edges to the glass cylinder
  #
  # Translate all coordinates to be relative to center of end
  translate $((offset+glass_endcap)) $((height/2))
  # draw the shading overlay for glass cylinder
  fill None stroke snow4 stroke-width 2
  roundrectangle -$glass_endcap,-$glass_radius \
                      $((glass_length+glass_endcap)),$glass_radius  \
                      $glass_endcap,$glass_radius
  # now make right end almost fully transparent
  translate $glass_length 0
  fill None stroke snow4 stroke-width 1
  roundrectangle -$glass_endcap,-$glass_radius \
                      $glass_endcap,$glass_radius  \
                      $glass_endcap,$glass_radius
EOF
}
label_image() {
  # Create a secondary label image
  #
  #convert
  cat<<EOF
   -background None \( -font ~/fonts/Garfield.ttf -size ${width}x${height} \
          -fill red -stroke snow4 -strokewidth 1 \
          label:'$percent %' \
          \
          -trim +repage \
          \( +clone -background firebrick3 -shadow 80x3+3+3 \
          \) +swap -background none -layers merge \)
EOF
}

# ------------------
# Main program...

# Put it all together...
eval "convert -size ${width}x${height} -background None mvg:<(draw_base) \
        \( mvg:<(draw_glass_shading) -background black -alpha shape \
        \) -composite \
        -draw @<(draw_glass_edges) \
        \
        -trim +repage \
        \( +clone -background snow4 -shadow 80x3+3+3 \
        \) +swap -background none -layers merge +repage \
        \
        $(label_image) \
        -gravity center -insert 0 -append \
        -background $background -extent ${width}x$((2*height)) \
        '${2:-"show:"}'"

exit 0

# Replace the last group of lines with this to Remove label completly
        \
        -background $background -extent ${width}x${height} \
        "${2:-"show:"}"

# or these to please label on top of the cylinder
        \
        <(label_image) \
        -background none -gravity center -extent ${width}x${height} \
        -composite -bordercolor $background -border 0 \
        "${2:-"show:"}"

User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: [SOLVED] Better way to produce this png ?

Post by anthony »

You don't seem to have lost much in the way of comments on how it works.

I have forgotten that draw MVG will accept # ... line comments
Also as you are no longer using echo you don't need the end of line \ to continue the command
Draw ignores end of lines (except with regard to # comments) treating them as just another space.

I have updated the cylinder)bar script in IM Examples, and added some comments about some
of the fancy use of shell functions for <(...) and $(...) BASH syntax.


Essentially my addition to this discussion was to close it off not that I .. finially... gotten around to adding appropriate examples to IM examples for using roundrectangle for easy cylinder drawing.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply