bitmap image file manipulation using bitmap file structure in c - c

I want to implement a simple command line based image editor. The program will
provide a text based menu, which provides several functions for user to manipulate a windows
bitmap (.bmp) image file. The menu will include load image, rotate image, mirror image, save image
and quit options. The load image option will be used to open and read pixel values from a given
bitmap file. This option will also print out the basic properties, such as dimensions and total size, of the given file. The rotate and mirror options will manipulate previously read pixel values. An image
must be loaded before applying these options. The save option will save the pixel values in the
memory to a bitmap file with a given filename.
Which approach do you recommend for me about this project and about bitmap file structure?
It would be very appreciated if you give me advice even about one particular topic for example load the file.

libbmp will make your program all but trivial to implement.

If you really want to use C then try the libbmp library http://code.google.com/p/libbmp/
However, I'd recommend using C#, then the task would be trivial with the System.Drawing namespace.

This function is used for loading a bmp file to memory.
you have to declare first a header file with bmp structure
BMP* load_BMP(char *filename);
BMP *bmp; // local integer for file loaded
FILE *in; // pointer for file opening
int rowsize;
int row, col, color, i;
unsigned char b;
in=fopen(filename,"rb"); // open binary file
if (in==NULL)
{
printf("Problem in opening file %s.\n",filename);
return NULL;
}
bmp=(BMP*) malloc(sizeof(BMP)); //memory allocation
if (bmp==NULL)
{
printf("Not enough memory to load the image.\n");
return NULL;
}
fread(bmp->BM,2,1,in);
if (bmp->BM[0]!='B' || bmp->BM[1]!='M')
{
printf("Bad BMP image file.\n");
free(bmp);
return NULL;
}
fread(&bmp->fileSize,4,1,in);
fread(&bmp->Reserved1,2,1,in);
fread(&bmp->Reserved2,2,1,in);
fread(&bmp->imageOffset,4,1,in);
fread(&bmp->imageHeaderSize,4,1,in);
fread(&bmp->imageWidth,4,1,in);
rowsize=4*((3*bmp->imageWidth+3)/4); //calculate rowsize because of padding
fread(&bmp->imageHeight,4,1,in);
fread(&bmp->colorPlanes,2,1,in);
fread(&bmp->compressionMethod,4,1,in);
fread(&bmp->imageSize,4,1,in);
fread(&bmp->hPPM,4,1,in);
fread(&bmp->vPPM,4,1,in);
fread(&bmp->paletteColors,4,1,in);
fread(&bmp->paletteImportantColors,4,1,in);
bmp->data=(unsigned char*) malloc(bmp->imageSize); //allocate memory for image data array
if (bmp->data==NULL)
{
printf("There is not enough memory to load the image\n");
free(bmp);
return NULL;
}
for(row=0;row<bmp->imageHeight;row++) //read picture data
{
for(col=0;col<bmp->imageWidth;col++)
for(color=0;color<=2;color++)
fread(&bmp->data[row*rowsize+3*col+color],
sizeof(unsigned char),1,in);
//read extra bytes for end of row padding
for(i=0;i<rowsize-3*bmp->imageWidth;i++)
fread(&b,1,1,in);
}
fclose(in);
return bmp;
}

Related

Mirror image read from 2D array in C

I am writting a program in C in which i'm reading a bmp image with a 2D array. I am supposed to have as output the original image + its inverse right next to each other.
The code I have here should be doing that but the images print on top of each other. I appreciate the help if anyone knows how I can fix that.
int main(void) {
// Opens file to read the image from
FILE * infile = fopen("inputImage.bmp", "rb");
// Creates file to write the image to after modifications
FILE * outfile = fopen("flip.bmp", "wb");
//Bmp images have headers the next 3 lines of code store the header of the input image
unsigned char headersPart1[2];
int filesize;
unsigned char headersPart2[48];
// This space[] [] creates the array to which to write the input image AND its inverse right next to each other the image file is 160 * 240
// The 3 is for the rgb values.. since its a 2D array we want to use every single //part of the image to work with
unsigned char space[160][3*240];
//The array to which to copy the results to (original image + INVERSE)
unsigned char mirror[160][3*480];
fread(headersPart1,sizeof(char) ,2,infile);
fread(&filesize,sizeof(char) ,4,infile);
fread(headersPart2,sizeof(char) ,48,infile);
fread(space,sizeof(char) ,filesize-54,infile);
// copying what in the original image array (space[][]) into the new //array mirror[][]
for ( int row = 0; row < 240*3 ; row++ ) {
for (int col = 0 ; col < 160; col++) {
char temp = space[col][row];
mirror[col][row] = space[col][row];
//Starts printing the inverse of the original image, starting at the index where the original image will end
mirror[col][720+row]= space[col][719-row];
space[col][row] = temp;
}
}
// Puts everything back into the outfile , once i save and run on GCC this gives me an image and its inverse on top of each other
fwrite(headersPart1,sizeof(char) ,2,outfile);
fwrite(&filesize,sizeof(char) ,4,outfile);
fwrite(headersPart2,sizeof(char) ,48,outfile);
//sends whats in mirror [][] to the outfile
//54 is the size of the header (bmp images))
fwrite(mirror,sizeof(char) ,filesize-54,outfile);
return 0;
}
PS: I'm running this on GCC
The BMP file format you can find here
Your loader is not complete regarding support different versions of BMP, check resolution, color-depth, the presens of palette etc.
But for what you want to use this for, you probably have a fixed input, always the same resolution etc.
But you want the resulting image to be twice as wide. Hence some details in the headers has to change:
"filesize"
"the bitmap width in pixels (signed integer)"

C programming and OpenCV (How to read an image from a file and load it for further processing in openCv)

I have created a file in C which contains the filemanes of images. The code is given below ("Leaves" is a dataset of images. I am storing the image names in a file):
FILE *fp;
system("dir /B D:\\opencvprojects\\platphenotypeFinal\\platphenotypeFinal\\Leaves > file.txt");
file.txt looks like this:
1001.jpg
1002.jpg
1003.jpg
1004.jpg
1005.jpg
1006.jpg
1007.jpg
Now I want to read each image from the file, do the background subtraction in openCV and save the results for all these images in another file.
OriginalImage=cvLoadImage("Leaves\\1007.jpg",CV_LOAD_IMAGE_GRAYSCALE);
I know how to read a single image (using the above code), but I want to automatically read each image of the file, do the processing, and save the result in another file, and the process continues in a loop until all images are taken care of.Thus, an output file will be generated containing the file names (same as the input file names) of binary images.
Your help will be very much appreciated.
int main()
{
CvMoments moments;
CvMemStorage *connectedCompStorage = cvCreateMemStorage (0);
CvSeq *temp = NULL; //used to loop through contour perimeter checking
CvSeq *connectedComp = NULL;
FILE *fp;
char buffer[9];
system("dir /B D:\\opencvprojects\\platphenotypeFinal\\platphenotypeFinal\\Leaves > file.txt");
fp = fopen ("file.txt", "r+");
OriginalImage = cvLoadImage("Leaves\\1108.jpg",CV_LOAD_IMAGE_GRAYSCALE);
}
opencv has a nice glob function to read a whole directory:
(and please, do not use opencv's C-api !)
vector<String> files;
glob("D:\\opencvprojects\\platphenotypeFinal\\platphenotypeFinal\\Leaves\*.jpg", files);
for (size_t i=0; i<files.size(); i++)
{
Mat m = imread(files[i]);
// process image
}

can't read bmp file perfectly

I am newbie in C ,I write a c code for simply reading a bmp file of 2448x280 pixels having 32 bit depth and writing it into new bmp file. For this I read pixels one by one. I am reading header perfectly , but the problem is after completing read and write operation on pixels, the current position original image is= 2741814, which is right according to me but result image is have its position = 2903490. So, please tell me where is the mistake.
Here is my code:-
#include<stdio.h>
#include<conio.h>
void main(void)
{
long int length;
int count,r,c,p;
FILE *image;
FILE *result;
char read_pixels;
image=fopen("image.bmp","rb");
result=fopen("result.bmp","w+");
for(count=0;count<54;count++)
{
fread(&read_pixels,1,sizeof(read_pixels),image);
fprintf(result,"%c",read_pixels);
}
for(c=0;c<280;c++)
{
for(r=0;r<2448;r++)
{
for(p=0;p<4;p++)
{
fread(&read_pixels,1,sizeof(read_pixels),image);
fprintf(result,"%c",read_pixels);
}
}
}
fseek(image,0,SEEK_CUR);
length=ftell(image);
printf("position of image after reading pixels =%d\n",length);
fseek(result,0,SEEK_CUR);
length=ftell(result);
printf("position of result after writing pixels=%d\n",length);
fclose(image);
fclose(result);
getch();
}

unsigned char pixel_intensity[] to image; C code, Linux

I have a data array of pixel intensity (e.g. unsigned char pixel_intensity[4] = {0, 255, 255, 0}) and I need to create image in C code on Linux (Raspberry Pi).
What is the easiest way to do it?
I would suggest using the netpbm format as it is very easy to program. It is documented here and here.
I have written a little demonstration of how to write a simple greyscale ramp to a 100x256 image below.
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *imageFile;
int x,y,pixel,height=100,width=256;
imageFile=fopen("image.pgm","wb");
if(imageFile==NULL){
perror("ERROR: Cannot open output file");
exit(EXIT_FAILURE);
}
fprintf(imageFile,"P5\n"); // P5 filetype
fprintf(imageFile,"%d %d\n",width,height); // dimensions
fprintf(imageFile,"255\n"); // Max pixel
/* Now write a greyscale ramp */
for(x=0;x<height;x++){
for(y=0;y<width;y++){
pixel=y;
fputc(pixel,imageFile);
}
}
fclose(imageFile);
}
The header of the image looks like this:
P5
256 100
255
<binary data of pixels>
And the image looks like this (I have made it into a JPEG for rendering on here)
Once you have an image, you can use the superb ImageMagick (here) tools to convert the image to anything else you like, e.g. if you want the greyscale created by the above converted into a JPEG, just use ImageMagick like this:
convert image.pgm image.jpg
Or, if you want a PNG
convert image.pgm image.png
You can actually use the PGM format images directly on the web, by convention, the MIME type is image/x-portable-graymap

My function is copying a PGM image file to PPM in a different way

I have a very simple function that saves a PPM image:
void WriteCImage(CImage *cimg, char *filename)
{
FILE *fp;
int i,n;
fp = fopen(filename,"w");
fprintf(fp,"P6\n");
fprintf(fp,"%d %d\n",cimg->C[0]->ncols,cimg->C[0]->nrows);
fprintf(fp,"255\n");
n = cimg->C[0]->ncols*cimg->C[0]->nrows;
for (i=0; i < n; i++)
{
fputc(cimg->C[0]->val[i],fp);
fputc(cimg->C[1]->val[i],fp);
fputc(cimg->C[2]->val[i],fp);
}
fclose(fp);
}
as you can see, this function receives a matrix (in CImage format) and writes the image data in the ASCII file. It seems correct, but every time I copy a grayscale image to a PPM image I have problems. Look at the code:
//that's a PGM grayscale image
gt = ReadImage(argv[1]);
//creating an RGB image with same dimensions of the PGM image
nwcimg = CreateCImage(gt->nrows,gt->ncols);
n=gt->nrows*gt->ncols;
//iterate through the PGM image
for(index=0;index<n;index++)
{
// just a copy of the grayscale image value to all 3 layeres
//of the PPM (RGB) image
nwcimg->C[0]->val[index]=gt->val[index];
nwcimg->C[1]->val[index]=gt->val[index];
nwcimg->C[2]->val[index]=gt->val[index];
}
WriteCImage(nwcimg,"gt-copied.ppm");
DestroyCImage(&nwcimg);
DestroyImage(&gt);
what problem i have? well, the code seems correct and simple. But when the cimage matrix/vector is written as a file, i can see that the two pictures are not the same. Seems like the pixels of the PGM image are 'shifted' or 'mirrored' in the copied image.
You can see the Image File and The RGB copy
Shouldn't
for(index=0;index<n;index++) {
nwcimg->C[0]->val[index]=gt->val[index];
nwcimg->C[1]->val[index]=gt->val[index];
nwcimg->C[2]->val[index]=gt->val[index];
be
for(index=0;index<n;index) {
nwcimg->C[0]->val[index]=gt->val[index++];
nwcimg->C[1]->val[index]=gt->val[index++];
nwcimg->C[2]->val[index]=gt->val[index++];
? The for loop in your file writer writes 3 bytes per loop. The loop in your reader consumes only 1 byte per loop then copies it into three separate arrays.

Resources