JuicyPixels provides Haskell types and image-building functions for turning validated PNM data into PNG files. Its Codec.Picture module distinguishes grayscale and RGB images at 8- and 16-bit depths, allowing image processing code to preserve pixel representation. section 13.1.1 section 13.3.2
The main pieces used in a PNM-to-PNG pipeline are:
- Pixel8 and Pixel16 represent grayscale channel values; PixelRGB8 and PixelRGB16 construct RGB pixels at matching bit depths. section 13.1.1
- DynamicImage stores image alternatives such as ImageY8, ImageY16, ImageRGB8, and ImageRGB16. section 13.1.1 section 13.3.2
- generateImage builds an Image from a coordinate-to-pixel function, width, and height. section 13.3.2
- writeDynamicPng writes a DynamicImage to a filesystem path and returns IO (Either String Bool). section 13.3.2
Converting a validated PNM image
Represent the image polymorphically as PnmImage px, then convert each dynamic case with its matching JuicyPixels constructor. For example, a grayscale 8-bit value becomes ImageY8 (pnmToImage img), while a color 16-bit value becomes ImageRGB16 (pnmToImage img). The conversion uses generateImage and retrieves each pixel by its row-major vector index. Finally, writeAsPng path img calls writeDynamicPng to save the result. section 13.3.2
Listing 13.17 The function to transform PNM images to JuicyPixels image values
dynamicPnmToDynamicImage :: DynamicPnmImage -> P.DynamicImage
dynamicPnmToDynamicImage (DynamicPnmImage img) =
case img of
PnmGray8Bit {} -> P.ImageY8 $ pnmToImage img #1
PnmGray16Bit {} -> P.ImageY16 $ pnmToImage img #1
PnmColor8Bit {} -> P.ImageRGB8 $ pnmToImage img #1
PnmColor16Bit {} -> P.ImageRGB16 $ pnmToImage img #1
where #1
pnmToImage :: P.Pixel px => PnmImage px -> P.Image px
pnmToImage pnmImg =
P.generateImage build (pnmWidth pnmImg) (pnmHeight pnmImg) #2
where
build x y = #3
pnmPixels pnmImg V.! (y * (pnmWidth pnmImg) + x)
Use the complete conversion listing to inspect how pixel type refinement selects ImageY8, ImageY16, ImageRGB8, or ImageRGB16. section 13.3.2
