Presentation is loading. Please wait.

Presentation is loading. Please wait.

Reading Netpbm Images.

Similar presentations


Presentation on theme: "Reading Netpbm Images."— Presentation transcript:

1 Reading Netpbm Images

2 Every file on your computer is stored in the only format a computer knows: 0’s and 1’s.
It’s our job as computer scientists to give meaning to these 0’s and 1’s so that we can store more than just a state of electricity. With just those two symbols, we created the binary number system to represent positive and negative numbers through the development of two’s complement. Next, we developed the ability to store letters and symbols by creating the arbitrary ASCII chart.

3 One such system was developed named the “Netpbm” format.
Now, imagine that you are tasked with the development of a system that can map 0’s and 1’s into a picture. How will you use the binary number system and the ASCII chart to create a file that is easy to read for humans and computers? One such system was developed named the “Netpbm” format. It is similar to JPG, PNG, and many other formats, but without complicated file headers and inherent compression. The format is so easy to use that you can open it with Notepad and easily see all of the data inside of the image file as ASCII text. There are .PBM files, .PGM files, and .PPM files. Let’s start by looking at .PBM files.

4 THE PBM IMAGE FORMAT PBM stands for Portable BitMap.
It’s format number is 1. It’s max value is 1. It can only store the colors 0 and 1. 0 is BLACK, and 1 is WHITE. Let’s look at an example of a PBM image on the next slide and a picture of what it represents.

5 Viewing the data produces:
An example PBM image The following picture shows a P1 PBM image that has a width of 30, height of 7, max value of 1, and image data that spells “MONROE”. Viewing the data produces:

6 80 on the ASCII chart is “P”.
Viewing the data in HEX 50 in Base-16 is 80 in Base-10. 80 on the ASCII chart is “P”. 31 in Base-16 is 48 in Base-10. 48 on the ASCII chart is “1”. HEX --- DEC --- ASCII Char 0d16 = = Carr. Return 0a16 = = Line Feed 2016 = = Space 3016 = = 0 = = 1

7 Viewing the data in BINARY
This is why we don’t view files in binary.

8 How do we read from the file?
Well, we just saw that reading the file straight as 0’s and 1’s will take us all year. So intead, let’s use Java’s FileInputStream and call its read() method. Whenever you call read(), the method will return to you the next eight bits from the file. Eight bits is one byte. So, we are going to take down this problem one byte at a time! The best way to visualize the read() method is to visualize a blinking cursor that starts at the beginning of the file’s text. Everytime you call the method, the cursor advances one byte worth of information and returns it to you. If you don’t store it into a variable or use it, then that data has essentially been skipped.

9 Skipping and Reading Data
The code above opens the file from the variable name. The type of variable name must String, and it must store the exact file name that you want to open. This could be “MyImage.pbm”. Then, the code makes a file input stream from that data and calls the read() method. The data was not stored or used anywhere, so it essentially has been skipped over. The first byte of data was “P”. Finally, the format is stored by reading in the next byte and subtracting 48 from it. Why 48? Because numbers on the ASCII chart start at 48.

10 All we need to do to skip over them is write:
Skipping CR and LF After every line in these image files is a carriage return, followed by the linefeed character. We need to skip both of these to get to the next line of information in the file. Keep in mind, their ASCII values are 13 and 10. All we need to do to skip over them is write: fis.read(); And now the cursor has sucessfully moved past those two characters! For reference, the header of the previous mentioned “MONROE” image file is shown below. We skipped 50 (P), stored 31 (1) into format, and now have just skipped 0d (CR) and 0a (LF). Let’s continue reading!

11 Reading Multi-Digit Numbers
For the format, we only had to use fis.read() once. That was because we knew it was a one digit number. The next number we are going to read from the image file is the width of the image in pixels. This could be a number anywhere from one to one million. How will we know how many times to call fis.read()? Also, how will we combine all of those reads into a single integer in memory? I’m glad you asked! For this problem, we are going to need to write a while-loop that keeps reading bytes from the file until it hits a space. We need to update an integer called width via multiplying it by 10 and adding each digit in.

12 Storing Height and Max Value Here’s a quick cheat sheet:
More while-loops like the previous slide’s with some tweaks will work to store in the height and max value from the file. Look at the header of your file closely! Here’s mine again: Here’s a quick cheat sheet: Keep reading the width until you hit a space. (cur != 32) Keep reading the height until you hit a CR (cur != 13) Keep reading the max value until you hit a CR. (cur != 13) Don’t forget to call fis.read() to skip LF’s too!

13 Debugging Header Reading
The following code will immensely help you debug your code if you think you have a problem reading in your header!

14 Let’s move on to reading the data that makes up the image!
Reading the Image Data Let’s move on to reading the data that makes up the image! In a P1 image (.PBM), each digit in the file represents an entire pixel’s data. It’s color is either 0 (black) or 1 (white). Because we know that each piece of data only contains one digit, we could write a nested for-loop such as the following:

15 How does that code work? This code first assigns image to a new 2D array that has height number of rows and width number of columns. Then, it uses a nested for-loop to go through each spot in the array. When it gets to a spot, it assigns it fis.read() – 48. This means that it is assigned the next byte from the file subtracted by 48 so that it is converted from a character to an int. If we aren’t on the very last column, we need to skip the space that follows this number in the image. Finally, after we have read all of this column, we need to skip the carriage return and linefeed characters that are at the end of each line in the image. When you are finished storing all of the data from the image, you can close the file input stream to free up the memory.

16 Viewing the image in a JFrame
Now that we have all of the image data loaded into the 2D array called image, we are ready to view the data using Swing! Let’s make a JFrame with a custom JPanel!

17 Viewing the image in a JFrame
The JPanel will need to override the paintComponent method in order to draw the pixels by using the g.fillRect() method call. You’ll need a nested for-loop in order to go through all of the data in the image array!

18 PGM stands for Portable Grey Map, and uses the format P2.
THE PGM IMAGE FORMAT PGM stands for Portable Grey Map, and uses the format P2. It is exactly like P1, except the color values can range from 0 to the specified max value, which defines shades from black (0) to grey (127) to white (255). Here is an example:

19 How to read PGM images The header for a P2 image is the same as the header for a P1 image, so no changes needed there! Though, to read in the image data values, you now cannot just use image[r][c] = fis.read(); because a single digit may not be all of the data value! You will need to use a while loop that stops when you hit a space (32) or carriage return (13), and then store that entire number into image[r][c]. This loop will look very similar to how you kept reading in values for the width, height, and max value until you hit a space or carriage return!

20 PPM stands for Portable Pix Map, and uses the format P3.
THE PPM IMAGE FORMAT PPM stands for Portable Pix Map, and uses the format P3. It is exactly like P2, where the color values can range from 0 to the specified max value, but the image data is not all grey values! Each number represents how much of a single color channel is visible. The order is RED, GREEN, BLUE. Notice how every third number is a larger value than the previous two? That means that this image must be colored blue!

21 image = new int[height][width][channels]
How to read PPM images To read this data, change your image data array to three dimensions! image = new int[height][width][channels] Where height is the number of rows in the image, width is the number of columns in the image, and channels is the number of color channels. You should have 1 color channel in P1 and P2 images, and have 3 color channels for P3 images. Now, you can write a triple-nested-for-loop to read in the data: for(int r = 0; r < height; r++) { for (int c = 0; c < width; c++) { for(int x = 0; x < channels; x++) { // Read Data Here } // Skip CR and LF here

22 Congrats! You can view images!


Download ppt "Reading Netpbm Images."

Similar presentations


Ads by Google