MathJax 3

Showing posts with label pgm. Show all posts
Showing posts with label pgm. Show all posts

Thursday, 3 September 2015

Create colour images using only standard C

In this tutorial we will see how to work with PPM images. For those of you who have missed the previous post, PPM refers to one of the image formats implemented in the Netpbm package.

In the previous post, we saw how to create a very small PGM image using a text file. We could have been doing it with any other programming language, as PGM is in text format. We will use C to create a PPM image, but before we must understand the structure of this format.

In a PGM image, each pixel is represented with one numerical value. With PPM , things change a little. Because PPM is an RGB format, we need three numerical value to represent the three channels of each pixel. If we write the data directly to a file, for three red pixels, after the header, we need to write:

  
255 0 0 255 0 0 255 0 0 ... 

The magic number for a PPM image is P3, if the file is written in ascii mode, and P6 if it's written directly in binary. The following is a program that create a 5 by 3 PPM image containing random colours:

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

int main()
{
  FILE * file = fopen("image.ppm", "wb");
 
  if(!file)
    {
      printf("Error! Cannot open file image.ppm");
      exit(EXIT_FAILURE);
    }

  int width = 5;
  int height = 3;
  int i, j;
  

  //header
  fprintf(file, "P6\n%d %d\n255\n", width, height);
 
  for(i=0; i<height; i++)
    for(j=0; j<width; j++)
      {
        fputc((random()%255), file);//red

        fputc((random()%255), file);//green     
        fputc((random()%255), file);//blue
      }
  fclose(file);
  return 0;
}


The image below is a scaled version of the one generated by the code above on my machine:




In the next post we will do some image processing, using only a PPM image and our best friend language, C. 

Tuesday, 1 September 2015

Working with images in C and C++ for beginners: the Netpbm image format

C and C++ don't have any standard library to work with graphics, GUI or media, diversely from some other programming languages, which support natively such kinds of facilities. Nevertheless, a myriad of open source libraries written in C and C++ does exist, which can be used to manipulate virtually any image or media type and to build GUIs for any kind of device or platform.


 However, using third-party libraries makes writing a program that operates on images, for the C/C++ beginner, a little tricky. This is due, in part, to the complexity of the installation and configuration process of these libraries, in part, to the new API which a user must learn before using them.


 But, if you are a beginner and all you want is to experiment with images in C or C++, regardless of the image's format, there's an easy shortcut to it.




The Netpbm image formats


 In the Netpbm package are implemented various portable image formats, supported by all major platforms. What makes these formats great for beginners, is the fact that they can be used without installing any development library, thus without learning any new API.


 In fact, in the Netbpm image formats, data can be represented in Ascii code, which makes creating an image file as easy as writing to a text file. Data can also be written directly in binary mode, using always the standard C/C++ functions, normally used to write text to a common text stream.


 The main image types among the Netpbm are three: PBM, PGM and PPM.

 The P stands for "portable", while the M stands for "map". The B, the G and P in the middle, stand for "bitmap", "grey" and "pixmap", respectively. Also, there is an alpha and an arbitrary depth format.


 The header section of a Netpbm image is very minimalistic and simple. It is made by a magic number, used as a descriptor for the type of data, and some values, defining the size of the image and the maximum number of colours in it.


 The header attributes are as follow:


image extensionmagic numberimage colours
PBMP1(ascii) P4(binary)2 black/white
PGMP2(ascii) P5(binary)255 Greys
PPMP3(ascii) P6(binary)255 RGB

So, for example, if we wanted to create an image with a width of 7 and with a height of 6 containing only grey pixels, with a value between 0 and 255, we'd write the following header:

P2            
7 6
255


Soon after the header, we can start writing the image's data, inserting each pixel's value in the exact order in which it appears on the screen

0000000
02552552552552550
02551281281282550
02551281281282550
02552552552552550
0000000
Save the above text in a file and name myimage.pgm, and you have a nice greyscale Netpbm image.

 Now, this is a very small image, but it's big enough to understand how "it" works. The one below is a scaled version:





In the next post, we will see how it's simple to create cool images using C or C++.