The PGM Header

P2
# feep.pgm
24 7
15

The PGM Data

Use numbers between 0 and 15

Scale Value


PGM is a basic simple image format. The header for this pgm is set, but displayed. The data is editable. I think the program is somewhat safe. The image data is from the above web page.

The HTML file:

<html>
<head>
    <script src="engine.js" defer></script>
</head>
<body>
<canvas id="canvas" style="border:2px solid"></canvas>
<p>
<h3> The PGM Header</h3>
<pre>
P2
# feep.pgm
24 7
15
</pre>
<h3>The PGM Data</h3>
Use numbers between 0 and 15
<p>
<textarea id="data"  style="border:2px solid" rows="8" cols="80">
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
0  3  3  3  3  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15 15 15 15  0
0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0 15  0
0  3  3  3  0  0  0  7  7  7  0  0  0 11 11 11  0  0  0 15 15 15 15  0
0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0  0  0
0  3  0  0  0  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15  0  0  0  0
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
</textarea>
<p>
<p> <input type="number" id="scaleValue" value=5>Scale Value</input>
<button id="redraw">Redraw</button>
<p>
<hr>
<a href="http://davis.lbl.gov/Manuals/NETPBM/doc/pgm.html">PGM</a> is a basic simple image format.  The header for this pgm is set, but displayed.  The data is editable.  I think the program is somewhat safe.  The image data is from the above web page.
<hr>
</body>
</html>

engine.js

"use strict"

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext('2d')
const dataInput = document.getElementById("data");

const RedrawButton = document.getElementById("redraw")
const ScaleInput = document.getElementById("scaleValue");


const cols = 24
const rows = 7
const levels = 15
let scale = 10
let data = new Array(rows*cols) 

ScaleInput.value = scale;

function GetScaleValue() {
    const oldScaleValue = scale;

    scale = parseInt(ScaleInput.value);
    if (isNaN(scale) || scale < 1 || scale > 50) {
        scale = oldScaleValue;
        ScaleInput.value = scale;
    }
}

function Draw() {
   canvas.width = cols * scale
   canvas.height = rows * scale

   ctx.fillStyle = "white";
   ctx.fillRect(0,0, canvas.width, canvas.height)
   ctx.strokeStyle = "white"

   for(let row = 0; row < rows; ++row) {
      for(let col = 0; col < cols; ++col) {
          let idx = col + row*cols;
          let grey = data[idx]/levels;
          let value = (grey*100) + "%"
          ctx.fillStyle = "rgb(" +  value + "," +  value + ", " +  value + ")"
          ctx.fillRect(col*scale, row*scale, scale, scale);
          ctx.strokeRect(col*scale, row*scale, scale, scale);
      }
   }

}

function GetData() {
   let numbers = dataInput.value.split(/\s+/)

   for(let row = 0; row < rows; ++ row) {
      for(let col = 0; col < cols; ++col) {
          let value = 0;
          let idx = col + row*cols;
          if (idx < numbers.length) {
               value = parseInt(numbers[idx]);
               if (isNaN(value) || value < 0 || value > levels){
                   value = 0;
               }
          }
          data[idx] = value 
      }
   }
}

function Redisplay() {
    GetScaleValue()
    GetData()
    Draw()
}

Redisplay();
RedrawButton.addEventListener('click', Redisplay);