canvas2mvg
Die Prozedur canvas2mvg
erzeugt aus dem Inhalt des Canvas-Elements einen String für ImageMagick-Vektorgrafik. Wenn Sie diesen in eine Datei mit Endung .mvg
speichern, kann ImageMagick dies in ein anders Dateiformat umwandeln, etwa .jpg
oder .gif
.
proc canvas2mvg canvas { set col2hex {color { if {[winfo exists $color] && [winfo class $color] eq "Canvas"} then { set color [$color cget -bg] } if {$color eq ""} then { set result none } else { set result # foreach x [winfo rgb . $color] { append result [format %02x [expr {int($x / 256)}]] } } set result }} set splinecoords2mvg {{coords {canBeClosed yes}} { set closed [expr {$canBeClosed && [lindex $coords 0] == [lindex $coords end-1] && [lindex $coords 1] == [lindex $coords end]}] if {$closed} then { lassign [lrange $coords end-3 end] x0 y0 x1 y1 set x [expr {($x0+$x1)/2.0}] set y [expr {($y0+$y1)/2.0}] lset coords end-1 $x lset coords end $y set coords [concat $x $y $coords] } if {[llength $coords] == 6} then { lreplace $coords 2 1 Q } else { lappend result {*}[lrange $coords 0 1] set co1 [lrange $coords 2 end-4] set co2 [lrange $coords 4 end-2] foreach {x1 y1} $co1 {x2 y2} $co2 { lappend result $x1 $y1 [expr {($x1+$x2)/2.0}] [expr {($y1+$y2)/2.0}] } lappend result {*}[lrange $coords end-3 end] lreplace $result 2 1 Q } }} array set mode {fill "" stroke "" strokewidth "" joinstyle "" capstyle "" fontfamily "" fontsize ""} lappend result [list viewbox 0 0 [winfo width $canvas] [winfo height $canvas]]\ [list stroke none]\ [list fill [apply $col2hex $canvas]]\ [list rectangle 0 0 [winfo width $canvas] [winfo height $canvas]] foreach item [$canvas find all] { set type [$canvas type $item] lappend result "# $type ... [$canvas gettags $item]" # outline width if {$type in {polygon oval arc rectangle line}} then { set width [$canvas itemcget $item -width] if {$width != $mode(strokewidth)} then { set mode(strokewidth) $width lappend result [list stroke-width $width] } } # fill, stroke if {$type in {polygon oval arc rectangle}} then { set fill [apply $col2hex [$canvas itemcget $item -fill]] if {$mode(fill) ne $fill} then { set mode(fill) $fill lappend result [list fill $fill] } set stroke [apply $col2hex [$canvas itemcget $item -outline]] if {$mode(stroke) ne $stroke} then { set mode(stroke) $stroke lappend result [list stroke $stroke] } } # joinstyle if {$type in {polygon line}} then { set joinstyle [$canvas itemcget $item -joinstyle] if {$mode(joinstyle) ne $joinstyle} then { set mode(joinstyle) $joinstyle lappend result [list stroke-linejoin $joinstyle] } } # line color, capstyle if {$type in {line}} then { if {$mode(fill) ne "none"} then { set mode(fill) none lappend result [list fill none] } set stroke [apply $col2hex [$canvas itemcget $item -fill]] if {$mode(stroke) ne $stroke} then { set mode(stroke) $stroke lappend result [list stroke $stroke] } set capstyle [dict get {butt butt projecting square round round}\ [$canvas itemcget $item -capstyle]] if {$mode(capstyle) ne $capstyle} then { set mode(capstyle) $capstyle lappend result [list stroke-linecap $capstyle] } } # text color, font, size if {$type in {text}} then { if {$mode(stroke) ne "none"} then { set mode(stroke) none lappend result [list stroke none] } set fill [apply $col2hex [$canvas itemcget $item -fill]] if {$mode(fill) ne $fill} then { set mode(fill) $fill lappend result [list fill $fill] } set font [$canvas itemcget $item -font] # font-family, font-size if {$font in font names} then { set fontsize [font configure $font -size] set fontfamily [font configure $font -family] } else { if {[llength $font] == 1} then { set fontsize 12 } else { set fontsize [lindex $font 1] } set fontfamily [lindex $font 0] } if {$fontsize < 0} then { set fontsize [expr {int(-$fontsize / [tk scaling])}] } if {$mode(fontsize) ne $fontsize} then { set mode(fontsize) $fontsize lappend result [list font-size $fontsize] } # # Attention! In some cases, IM assumes 72dpi, # where 90dpi is necessary. # Then, on cmd line, use switch -density as follows: # convert -density 90 test.mvg test.png # if {$mode(fontfamily) ne $fontfamily} then { set mode(fontfamily) $fontfamily lappend result [list font $fontfamily] } # # Attention! Care that IM has access to fonts. # If not, an error msg is shown, # then the default font is used silently. # } set line {} set coords [$canvas coords $item] switch -exact -- $type { line { # start of path lappend line path 'M set smooth [$canvas itemcget $item -smooth] if {[string is true -strict $smooth]} then { if {[$canvas itemcget $item -arrow] eq "none"} then { lappend line {*}[apply $splinecoords2mvg $coords] } else { lappend line {*}[apply $splinecoords2mvg $coords false] } } elseif {[string is false -strict $smooth]} then { lappend line {*}[lrange $coords 0 1] L {*}[lrange $coords 2 end] } else { lappend line {*}[lrange $coords 0 1] C {*}[lrange $coords 2 end] } append line ' lappend result $line } polygon { lappend line path 'M set smooth [$canvas itemcget $item -smooth] if {[string is false -strict $smooth]} then { lassign $coords x0 y0 lassign [lrange $coords end-1 end] x1 y1 set x [expr {($x0+$x1)/2.0}] set y [expr {($y0+$y1)/2.0}] lappend line $x $y L {*}$coords $x $y Z } elseif {[string is true -strict $smooth]} then { if {[lindex $coords 0] != [lindex $coords end-1] || [lindex $coords 1] != [lindex $coords end]} then { lappend coords {*}[lrange $coords 0 1] } lappend line {*}[apply $splinecoords2mvg $coords] } else { lappend line {*}[lrange $coords 0 1] C {*}[lrange $coords 2 end] } append line ' lappend result $line } oval { lassign $coords x0 y0 x1 y1 lappend line ellipse [expr {($x0+$x1)/2.0}] [expr {($y0+$y1)/2.0}]\ [expr {$x1-($x0+$x1)/2.0}] [expr {$y1-($y0+$y1)/2.0}] 0 360 lappend result $line } arc { lappend result [list push graphic-context] lappend result [list stroke-linejoin miter] # lappend result [list stroke-linejoin bevel] # lappend result [list stroke-linejoin round] lappend line path 'M lassign $coords x0 y0 x1 y1 set rx [expr {($x1-$x0)/2.0}] set ry [expr {($y1-$y0)/2.0}] set x [expr {($x0+$x1)/2.0}] set y [expr {($y0+$y1)/2.0}] set f [expr {acos(0)/90}] set start [$canvas itemcget $item -start] set startx [expr {cos($start*$f)*$rx+$x}] set starty [expr {sin(-$start*$f)*$ry+$y}] set angle [expr {$start+[$canvas itemcget $item -extent]}] set endx [expr {cos($angle*$f)*$rx+$x}] set endy [expr {sin(-$angle*$f)*$ry+$y}] # start point lappend line\ [expr {($startx+$x)/2.0}] [expr {($starty+$y)/2.0}]\ $startx $starty lappend line A # radiusx, radiusy lappend line $rx $ry # angle -- always 0 lappend line 0 # "big" or "small"? lappend line [expr {$angle-$start > 180}] # right side (always) lappend line 0 # end point lappend line $endx $endy # close path lappend line L $x $y Z append line ' lappend result $line lappend result [list pop graphic-context] } rectangle { lappend result\ [list push graphic-context]\ [list stroke-linejoin miter]\ [concat rectangle $coords]\ [list pop graphic-context] } text { lassign [$canvas bbox $item] x0 y0 x1 y1 lappend line text $x0 $y1 append line " '[$canvas itemcget $item -text]'" lappend result $line } image - bitmap { set img [$canvas itemcget $item -image] set file [$img cget -file] lassign [$canvas bbox $item] x0 y0 lappend result [list image over $x0 $y0 0 0 '$file'] } default { lappend result\ "# not yet done:\ [$canvas type $item] [$canvas coords $item] ([$canvas gettags $item])" } } } join $result \n }
11.3.2022
<< | Heimatseite | Verzeichnis | Stichworte | Autor | >>