Quick photo rotation

Difference between version 15 and 16 - Previous - Next
[Richard Suchenwirth] 2004-09-28 - Here's code for [photo image rotation] by +90 or -90 degrees only, 
but it runs reasonably fast:

======
 proc imgrot90 {img {clockwise 0}} {
    set w [image width $img]
    set h [image height $img]
    set matrix [string repeat "{[string repeat {0 } $h]} " $w]
    if $clockwise {
        set x0 0; set y [expr {$h-1}]; set dx 1; set dy -1 
    } else {
        set x0 [expr {$w-1}]; set y 0; set dx -1; set dy 1 
    }
    foreach row [$img data] {
        set x $x0
        foreach pixel $row {
            lset matrix $x $y $pixel
            incr x $dx
        }
        incr y $dy
    }
    set im2 [image create photo -width $h -height $w]
    $im2 put $matrix
    set im2
 }
======
----
[WikiDbImage rotext.jpg]

[RS] 2006-04-25: One frequently-asked-for feature is rotation of text, which can be done with the above code, plus the following:

======
 proc rotext {w x y text args} {
    package require Img
    raise [toplevel .tt]
    pack [eval [list label .tt.l -text $text] $args]
    update idletasks
    set i0 [image create photo -data .tt.l]
    destroy .tt
    $w create image $x $y -image [imgrot90 $i0]
    image delete $i0
 }
 #--Testing demo, usage example:
 pack [canvas .c -width 100 -height 80]
 update idletasks ;# to prevent occasional loss of the first item
 rotext .c 20 50 "Hello" -fg red -font {Courier 11}
 rotext .c 50 50 "vertical world"
======
----
[KPV] asked for rotation with transparent background (just like text items on [canvas] normally are). My solution is to copy pixels only if their colors differs from a specified "background" color:

======
 proc imgrot90t {img {clockwise 0} {bg {255 255 255}}} {
    set w [image width $img]
    set h [image height $img]
    set im2 [image create photo -width $h -height $w]
    for {set i 0} {$i<$h} {incr i} {
         for {set j 0} {$j<$w} {incr j} {
             if $clockwise {
                 set color [$img get $j [expr {$h-$i-1}]]
             } else {
                 set color [$img get [expr {$w-$j-1}] $i]
             }
             if {$color ne $bg} {
                 $im2 put [eval format #%02x%02x%02x $color] -to $i $j
             }
         }
    }
    set im2
 }
======

Just change ''imgrot90'' in ''rotext'' to ''imgrot90t'', and give the desired items ''-bg white'' (which in [photo] terms is reported as {255 255 255}), or modify accordingly ... :)
----
   * For fast arbitrary rotation (and scaling) see: [Enhanced photo image copy command]   * For very fast rotation and scaling see: [LRIPhoto]
   * [vertical labels] also has code for rendering, and rotating, text into a photo image.
   * [Rotate text and images using img extension] also has code for rendering, and rotating, text into a photo image.
   * [tablelist with vertical header/label text - text2rotatedimage], [JOB] 17-12-12: an implementation to manipulate tablelist's header labels to show up vertically.

<<categories>> Arts and crafts of Tcl-Tk programming | Image Processing