Skip to content
/ pnm Public

PNM is a collection of open image formats. This library supports ppm, pgm and pbm formats,

License

Notifications You must be signed in to change notification settings

jcbritobr/pnm

Repository files navigation

PNM

PNM is a collection of open image formats. They are also referred as portable anymap format(PNM). This library supports ppm(portable pixmap), pgm(portable graymap) and pbm(portable bitmap) formats. There is also an encoder and decoder implementations.

  • Description
    Each file starts with a two byte magic number (in ascii) that identifies the type of the file it is (PPM, PGM, PBM) and its encoding (ascii/plain or binary/raw). The magic number is a capital P followed by a single-digit number. Below is a explanation table with ascii/binary magic number formats.
Type Magic Number Extension Color
Portable Bitmap P1/P4 .pbm 0-1(White & Black)
Portable GrayMap P2/P5 .pgm 0-255(gray scale), variable, black to white range
Portable PixMap P3/P6 .ppm 16 777 216 (0-255 for each RGB channel), some support for 0-65535 per channel

The ascii/plain format allow for human readability and easy transfer to other platforms. The binary/raw formats are more efficient in size but will be dependent of platforms.

  • Encoder usage
import (
    "math/rand"
    "os"
    "github.com/jcbritobr/pnm"
)

func main() {
    image := pnm.NewPGMImage(800, 800, 255, pnm.PGMBinary)
    file, err := os.Create("testdata/synimage.pgm")
    if err != nil {
        panic(err)
    }
    encoder := pnm.NewEncoder(file)

    imgbuf := image.Buffer()

    for i := range image.Buffer() {
        data := rand.Intn(255-0) + 0
        imgbuf[i] = byte(data)
    }

    err = encoder.Encode(image)
    if err != nil {
        panic(err)
    }
}
  • Decoder usage
import (
    "fmt"
    "os"

    "github.com/jcbritobr/pnm"
)

func main() {
    var image pnm.PGMImage
    file, err := os.Open("testdata/synimage.pgm")
    if err != nil {
        panic(err)
    }
    decoder := pnm.NewDecoder(file, pnm.PGMBinary)
    err = decoder.Decode(&image)

    if err != nil {
        panic(err)
    }
}
  • Using ImageBuffer and color.Model (RGBA)
import (
    "os"
    "github.com/jcbritobr/pnm"
    "github.com/jcbritobr/pnm/buffer"
    "github.com/jcbritobr/pnm/color"
)

func main() {
    var image pnm.PPMImage
    file, err := os.Open("testdata/tree_1.ppm")
    if err != nil {
        t.Errorf("fail with %v", err)
    }
    defer file.Close()

    decoder := pnm.NewDecoder(file, pnm.PPMBinary)
    err = decoder.Decode(&image)
    if err != nil {
        t.Errorf("fail to decode image %v", err)
    }

    imbuf := buffer.NewImageBuffer(image)
    rgba := color.RGBA{}
    newbuf := []byte{}
    for {
        n, _ := imbuf.Read(rgba[:])
        if n <= 0 {
            break
        }
        r, g, b, _ := rgba.RGBA()
        r = 255 - r
        g = 255 - g
        b = 255 - b
        newbuf = append(newbuf, r)
        newbuf = append(newbuf, g)
        newbuf = append(newbuf, b)
    }

    image.SetBuffer(newbuf)

    fe, err := os.Create("testdata/tree_3.ppm")
    if err != nil {
        t.Errorf("fail to create file %v", err)
    }
    defer fe.Close()

    encoder := pnm.NewEncoder(fe)
    err = encoder.Encode(&image)
    if err != nil {
        t.Errorf("Encode() = %v want %v", err, nil)
    }
}

About

PNM is a collection of open image formats. This library supports ppm, pgm and pbm formats,

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages