Updated 2011-11-04 22:04:52 by AK

Portable Pix Map, an image format of the PNM family. It is a part of PBM Plus - a large numbers of image converters and manipulators available on the internet.

Every pixel is represented by three bytes for red, green, and blue channel. No compression, 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 PGM.

CRIMP can read and write PPM images.

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): A larger ray-tracing image to test with is at http://www.cpsc.ucalgary.ca/~cherlin/sample.ppm [AMG: 404] - 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.