-1

I have a function ℚ -> ℚ -> Bool taking a Cartesian coordinate, where true stands for black and false for white. Is there any existing library that I can use to "rasterize" it into a bitmap image?

amalloy
  • 89,153
  • 8
  • 140
  • 205

2 Answers2

1

The PBM file format is a pretty simple text-based image file format. See https://en.wikipedia.org/wiki/Netpbm for a description. It's easy to write code to produce PBM files.

For the function λ x y → x ≤ᵇ y, the below code outputs the following PBM file contents:

P1
20 10
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 
1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 
1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 

The lines mean the following:

  • P1 is a magic number that identifies the file format.
  • 20 10 are the width and height of the image.
  • Each of the remaining lines represents one line of the image. 1 represents a black pixel and 0 a white pixel.

Put the above contents in a .pbm file (say, test.pbm) and you have something that you can open in image processing tools that support PBM files.

The makePBM function takes the width and height of the image to be produced, the x and y starting points in ℚ, the step to make in ℚ for each pixel in the x and y direction, and the ℚ → ℚ → Bool function to be evaluated.

--guardedness is only required, because I use IO for demonstration purposes.

{-# OPTIONS --guardedness #-}

module Raster where

open import Data.Bool using (Bool ; if_then_else_)
open import Data.Nat using (ℕ ; zero ; suc)
open import Data.Nat.Show using (show)
open import Data.Rational using (ℚ ; 0ℚ ; 1ℚ ; _+_ ; _≤ᵇ_)
open import Data.String using (String ; _++_)
open import IO using (Main ; run ; putStrLn)

-- width height offset-x offset-y step-x step-y function
makePBM : (w h : ℕ) → (ox oy sx sy : ℚ) → (ℚ → ℚ → Bool) → String
makePBM w h ox oy sx sy f = header ++ bitmap h oy
  where
  header : String
  header = "P1\n" ++ show w ++ " " ++ show h ++ "\n"

  row : (n : ℕ) → (x y : ℚ) → String
  row zero    x y = "\n"
  row (suc n) x y = pixel ++ " " ++ row n (x + sx) y
    where pixel = if f x y then "1" else "0"

  bitmap : (n : ℕ) → (y : ℚ) → String
  bitmap zero    y = ""
  bitmap (suc n) y = row w ox y ++ bitmap n (y + sy)

testPBM : String
testPBM = makePBM 20 10 0ℚ 0ℚ 1ℚ 1ℚ (λ x y → x ≤ᵇ y)

main : Main
main = run (putStrLn testPBM)
123omnomnom
  • 294
  • 1
  • 10
0

I'd be very surprised if there were. I'm not aware of any work on image manipulations in Agda.

Having said that, it should be relatively easy to do.

  1. Create a m x n matrix of type Vector (Vector ℕ m) n from Data.Vec.Functional containing (i,j) at the ith row and jth column.

  2. Map each (i,j) to the desired range of coordinates in the image.

  3. Map the function f : ℚ -> ℚ -> Bool over each the entire matrix.

user2667523
  • 190
  • 1
  • 9