PPM

PPM, or "Portable PixMap", is an image format of the PNM family. It is a part of PBM Plus - a large numbers of image converters and manipulators. In PPM every pixel is represented by three bytes for red, green, and blue channel. No compression, and no transparency, as far as RS is aware.

Tk images can be read and written in PPM format using photo (as of which version?).

See also

Reader

RS 2006-06-02: Here is a reader that parses a "P3" format PPM string (like read from a file) and creates a photo from it:

 proc ppm-photo ppm {
   regsub -all {#[^\n]*\n} $ppm " " ppm ;# strip out comments
   foreach {type w h max} $ppm break
   foreach {r g b} [lrange $ppm 4 end] {
      set r [expr {int(255.*$r/$max)}]
      set g [expr {int(255.*$g/$max)}]
      set b [expr {int(255.*$b/$max)}]
      lappend row [format #%02X%02X%02X $r $g $b]
      if {[llength $row] == $w} {
         lappend rows $row
         set row {}
      }
   }
   set im [image create photo]
   $im put $rows
   set im
 }

#-- Testing:

 set data {P3
 4 4
 15
 0 0 0 0 0 0 0 0 0 15 0 15
 0 0 0 0 15 7 0 0 0 0 0 0
 0 0 0 0 0 0 0 15 7 0 0 0
 15 0 15 0 0 0 0 0 0 0 0 0
 }
 ppm-photo $data

#-- produces the following image (zoomed by a factor of 9): WikiDbImage ppm.jpg A larger ray-tracing image to test with is at https://web.archive.org/web/20060502010206/http://pages.cpsc.ucalgary.ca:80/~cherlin/sample.ppm - I was happy to see that IrfanView and my little proc agreed on how to render it :^)

aricb From P3 PPM to photo image in 17 lines! I'm impressed.

AMG: Why are floating-point numbers used in the RGB scaling code? The following is equivalent, simpler, and faster:

      set r [expr {255*$r/$max)}]
      set g [expr {255*$g/$max)}]
      set b [expr {255*$b/$max)}]

Test:

for {set max 1} {$max < 1024} {incr max} {
    for {set i 0} {$i < $max} {incr i} {
        if {int(255.*$i/$max) != 255*$i/$max} {puts "$i/$max"}
    }
}

This code never prints, so there is never a discrepancy, for all valid RGB values (in $i) for all $max values from 1 through 1024.


AK - 2010-08-12 11:19:57

Unknown about the floating point stuff. I put a derivative of this into CRIMP and used integer math without problems.