Version 1 of Rotating a Tk Photo Image

Updated 2002-09-06 07:39:00

BLT provides a command that allows rotation and scaling of images.

The img_rotate package does simple rotation (90,180, etc): [L1 ]

GPS: Below is a simple working prototype for image rotation by n degrees. It's slow because it's written in Tcl, but it seems to work properly.


  #!/bin/wish8.3

  proc - {num1 num2} {
    return [expr {$num1 - $num2}]
  }
  proc + {num1 num2} {
    return [expr {$num1 + $num2}]
  }
  proc * {num1 num2} {
    return [expr {$num1 * $num2}]
  }
  proc / {num1 num2} {
    return [expr {$num1 / $num2}]
  }
  proc cos {angle} {
    return [expr cos($angle)]
  }
  proc sin {angle} {
    return [expr sin($angle)]
  }
  proc toInt {num} {
    return [expr int($num)]
  }

  proc main {} {

    set img [image create photo -file ../Experimental/hand.gif]

    set width [image width $img]
    set height [image height $img]

    pack [label .l -image $img]

    set imgMod [image create photo -width $width -height $height]

    set twoPi [expr {acos(-1) * 2}]
    set deg 15

    set radian [* $deg [/ $twoPi 360]]
    set cosTheta [cos $radian]
    set sinTheta [sin $radian]

    for {set y 0} {$y < $height} {incr y} {

      for {set x 0} {$x < $width} {incr x} {
        set col [$img get $x $y]
        foreach {red green blue} $col break
        set hexCol [format "#%2.2x%2.2x%2.2x" $red $green $blue]
        set newX [toInt [* $x $cosTheta]]
        set newY [toInt [+ $y [* $x $sinTheta]]]

        if {$newX < 0 || $newY < 0 || $newX > $width || $newY > $height} {
          continue
        }
        $imgMod put $hexCol -to $newX $newY
      }
    }

    pack [label .l2 -image $imgMod]
  }
  main

RS notes that rotation by non-multiples of 90 degrees makes the target image bigger - it seems to follow these formulas (w and h being original width and height, a the rotation angle):

 w' = w cos a + h cos (90-a)
 h' = w sin a + h sin (90-a)

Category Graphics