In this assignment, you will develop a simple program for loading and displaying an image formatted in the PPM P6 format

Objectives

This assignment is designed to teach you the basics of working with:

  • Image files and file formats
  • The structure of a web application that uses Javacsript, HTML, and simple HTML5 canvas operations
  • Javascript syntax and developing programs in Javascript
  • Submitting assignments using git and GitHub.
  • Testing your program.
  • My and the grader’s expectations for programs and our rubrics.

Part 1: Setting up your repository

If you haven’t already, you need to create an account on GitHub. You should also enable academic access if you haven’t already by “Requesting a discount” for your “Individual Account”.

Next, you’ll create a repository for your assignment. If you are a 433 student, please follow this link, where as if you are a 533 student, please follow this link

If you aren’t comfortable yet with git, please try out some tutorials online! try.github.io is great, as is http://rogerdudler.github.io/git-guide/, https://www.atlassian.com/git/tutorials, and https://git-scm.com/docs/gittutorial.

We will use git the entire semester, and this assignment is meant to get you started. Feel free to use a GUI client for git, but you may also want to consider learning how to use it from a terminal. Since I will managing the repositories, you likely will only need to learn four commands:

git clone
git add
git commit
git push

Part 2: Your program

To start with, your repo includes 3 files and 1 directory.

First examine index.html in a text editor. Please change the title of this html file and feel free to make any other cosmetic changes to the look and layout. This webpage includes only three components: (1) An html canvas with the id canvas, (2) A div tag that includes both a input tag for loading files and an empty href tag to download images for saving, and (3) a script tag that imports the template Javascript file a01.js.

Within a01.js, you’ll find a couple of components. First, we access the DOM objects associated with the canvas and the load/save elements. We also directly access the context of the canvas. We next connect up listeners for the file load and save elements. Finally, we define two empty functions (that you will fill in) for loading (or uploading) the input file and for saving (or downloading) the displayed image. Your main task in this assignment is to complete these two functions. Feel free to define helper functions as needed.

You can assume all PPM images will be provided in the P6 format. PPM images have a simple format, that you must parse:

P6  
# COMMENTS always start with a pound sign, skip these lines  
[WIDTH] [HEIGHT]  
[MAX VALUE] 
[RAW DATA]

For this assignment, you need only support PPM files with a [MAX VALUE] of 255. All portions of the above header are in ASCII except for the raw data, which is encoded directly as binary data.

Image Reader

Parsing files like this in Javascript can be a bit tricky. You will have to employ the FileReader class in Javascript and the function readAsBinaryString() I recommend the following helpful documentation: https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsBinaryString if you want to understand the example I provided.

After loading, you should have the entire file as one long Javascript String. Note that Strings are encoded UTF-16 characters, which will cause problems when parsing the older PPM format. But, at least you will get access to the high-level String methods. I recommend reading https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods. In particular, you’ll have to parse the ASCII header line-by-line, and then check if the first character of the line begins with a comment.

After parsing the header to extract the width and height, you’ll then need to interpret the raw bytes as integers. To do so, you’ll need a key Javascript function charCodeAt() (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt)

Image Display

Internally, you can store the raw data in whatever format you like at this point. I recommend using a Uint8Array of length \(4\times W\times H\) , which stores the RGB channels of the image, as well as a fourth A channel, in the format used by the ImageData object of the canvas. Each of the R, G, and B channels store their values in one byte, and for now just assume the A channel will always be stored as the value 255. Note that Uint8Array is one of the typed arrays in Javascript, which provide a bit more fine-grained control over the memory layout than a standard Javascript array.

Once you’ve read the uploaded image, you’ll want to both update the size of the canvas as well as fill in the pixel information. You may find this tutorial particularly helpful: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas

Image Writer

Finally, to complete the download functionality, you need to do the loading steps roughly in reverse. Particularly, your download function should get the current width and height of the canvas as well as accessing the current data of the canvas using ctx.getImageData(). While in this assignment we are only loading/saving one image at a time, future assignments will manipulate the canvas between loading/saving, so you want to be always saving what is displayed, not what is stored in any intermediate buffers.

To save, you will need to (1) create a string header, (2) access the raw byte data from the canvas and convert it to character bytes, and (3) update the anchor tag (dynamically) to save the file. To prepare the output data, you’ll create a new Uint8Array that is the length of the header plus \(3\times W \times H\). For step (1), you should make use of charCodeAt to convert the header string to ASCII bytes. For (2), you will skip the A channel from the data stored in the context. Finally, for (3), you should create a new Blob from the encoded PPM file and then update the href of the output tag using createObjectURL. I’ve provided an example skeleton to get you started as these calls are tricky to discover.

Testing / Debugging

The expectation is that we will use this file I/O routine in numerous future assignments, potentially with modifications. Design carefully with this in mind!

Test your program with the images found in the data/ subdirectory of the default repo. You may also want to test with other images you find – you should be able to convert them to PPM format using a variety of tools, but be careful as some converters may produce images with the extension .ppm where the [MAX VALUE] may not always be 255 or the format may not be P6.

Written Component: Survey

For the written portion of the assignment, create a second plain-text ASCII file, named survey.txt, and also place it in the top-level directory of your git-repository. Commit and push this file after filling out the following survey, with answers formatted roughly like this:

1. I loved video games and want to know how they work.

2. Cool ways to make pictures with computers!  

3. C++ (10), Python (5), LOLCODE (2)

...

You are not required to answer any of the questions if you don’t want to, but non-submission does not count! Please write “no answer” for any question that you choose not to answer.

I am going to use the answers to calibrate the remainder of the course, so this is an opportunity for you to influence where the course goes. There are no right or wrong answers in this questionnaire. All I ask is you answer honestly, without trying to figure out what I might want to read. The more you write, the more I’ll know about your expectations and what you are interested in.

Survey Questions

  1. Why are you taking this course?

  2. What do you think you’ll learn in this course?

  3. List the three programming languages you are most comfortable with, with how many years of experience you have with each

  4. What experience do you have with Javascript? Have you used OOP in Javascript?

  5. What’s the best computer graphics you’ve ever seen? Why do you like it?

  6. What’s the worst computer graphics you’ve ever seen? Why do you not like it?

  7. Tell me about something cool you learned recently. If you were meeting with a friend, what would you chat about? Possible answers: books, movies, TV shows, blogs, podcasts, etc. It does not have to be about computer graphics.

Submission

You should use git to submit all source code files. The expectation is that your code will be graded by cloning your repo and then executing it within a modern browser (Chrome, Firefox, etc.)

Please provide a README.md file that provides a text description of how to run your program and any parameters that you used. Also document any idiosyncrasies, behaviors, or bugs of note that you want us to be aware of.

To summarize, my expectation is that your repo will contain:

  1. A README.md file
  2. A survey.txt file, pushed to the repo on Sep. 09, 2019 04:59:59 PM
  3. A index.html file
  4. A a01.js file
  5. Any other .js files that you authored.
  6. (Optionally) any other test images that you want.

Grading

Deductions

Reason Value
Program crashes due to bugs -10 each bug at grader's discretion to fix


Point Breakdown of Features

Requirement Value
Consistent modular coding style, clear organization of files 10
External documentation (README.md) 5
Class documentation, Internal documentation (Block and Inline). Wherever applicable / for all files 15
Expected output / behavior based on the assignment specification, including

Loading: Correctly parsing P6 PPM format and storing it internally.20
Properly resizing the canvas on load and tracking the image dimensions throughout the program.15
Displaying: Code correctly displays the PPM image in an HTML Canvas15
Saving: allowing the user to save (download) the displayed image20

70
Total 100


Cumulative Relationship to Final Grade

  • Programming: Worth 3% of your final grade

  • Written Assignment (Survey completion): Worth 1% of your final grade