0
//CREATE A PROGRAM TO RESIZE A BITMAP FILE
//include C libraries
#include <stdio.h>
#include <stdlib.h>
#include <math.h>


#include "bmp.h"

int main(int argc, char* argv[])
{
//Output error if incorrect ammount of arguments is entered
if(argc != 4)
{
    fprintf(stderr,"Input a resize integer, a source file , and new file name");
    return 1;
}


//Set pointers to the input and outputfile names from the argument line
char* infile = argv[2];
char* outfile = argv[3];

//Set the resize number factor to a float number from the argument line
float n = atof(argv[1]);

//Output error if number factor is negative or over 100.
if( n <= 0 || n > 100)
{
    fprintf(stderr,"Input a integer between 0 and 100 to resize the image");
    return 2;
}


//Open the input file.Output an error if the file can not be found or opened.
FILE *inptr = fopen(infile, "r");
if(inptr == NULL)
{
    fprintf(stderr,"cannot open file%s\n",infile);
    return 3;
}

//Open the output file.Output an error if a file can not be created.
FILE *outptr = fopen(outfile, "w");
if(outptr == NULL)
{
    fprintf(stderr,"cannot create file%s",outfile);
    return 4;
}


//Temp data storage from the file header for the input file.
BITMAPFILEHEADER bf;

fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

//Temp data storage from the info header for the input file.
BITMAPINFOHEADER bi;


//Read input file.
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

// ensure infile is (likely) a 24-bit uncompressed BMP 4.0
    if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
        bi.biBitCount != 24 || bi.biCompression != 0)
    {
fclose(outptr);
fclose(inptr);
fprintf(stderr, "Unsupported file format!!!!!!!!.\n");
return 4;
    }

// Temp data storage for output file
BITMAPFILEHEADER out_bf;
BITMAPINFOHEADER out_bi;

//Set output file data storage equal to the input file data storage
out_bf=bf;
out_bi=bi;

//Multiply input file width and height by the factor argument
out_bi.biWidth = round(bi.biWidth * n);
out_bi.biHeight = round(bi.biHeight * n);

//Find the ammount of  padding needed for input and output file.
int inpadding= (4-(bi.biWidth * sizeof(RGBTRIPLE))%4)%4;
int outpadding=(4-(out_bi.biWidth * sizeof(RGBTRIPLE))%4)%4;

//resize the input file data into the output file.
out_bi.biSizeImage = ((out_bi.biWidth * sizeof(RGBTRIPLE)) + outpadding) * abs(out_bi.biHeight);
out_bf.bfSize = bf.bfSize - bi.biSizeImage + out_bi.biSizeImage;

//write header to output
fwrite(&out_bf,sizeof(BITMAPFILEHEADER),1,outptr);
fwrite(&out_bi,sizeof(BITMAPINFOHEADER),1,outptr);

int inHeight = abs(bi.biHeight);
//int outHeight = out_bi.biHeight;
int inWidth = bi.biWidth;


//iterate over infile height
for(int i = 0 ; i < inHeight ; i++ )
{


        //iterate over output height
    for(int j = 0; j < n; j++ )
    {

                 //Iterate over  input width
            for(int k = 0; k < inWidth; k++ )

            {


                //Read pixels of the input file.
                RGBTRIPLE triple;

                fread(&triple, sizeof(RGBTRIPLE),1,inptr);

                //Iterate over the output width.
                    for(int m = 0 ; m < n ; m++)
                    {

                            //Write pixels into output file.
                        fwrite(&triple,sizeof(RGBTRIPLE),1,outptr);
                    }

            }

        // skip over padding in infile

        fseek(inptr, inpadding, SEEK_CUR);

        //Add padding into the output file.

        for (int k = 0; k < outpadding; k++)
        {
            fputc(0x00, outptr);
        }

        //Set cursor to beginning of scanline
        fseek(inptr, -(inWidth * 3 + inpadding ), SEEK_CUR);
    }

//Set cursor to the end of the scanline
fseek(inptr, inWidth*3+inpadding, SEEK_CUR);
}


fclose(inptr);
fclose(outptr);
return 0;

}

Hi, i have been stuck on this problem for one week now. My program can resize BMP images over a factor of one however When i try to make the image smaller it does not work. I have tried countless things and i cannot figure it out please help.

-1

There are multiple ways to scale down, even if you're just dropping lines/columns. I want to mention three, but there are probably more.

One way is to calculate 1/n, write 1 horizontally resized input line and skip (1/n)-1. Obviously works only if 1/n is an integer, and this integer evenly divides input dimensions, but all the tests are done with numbers working well with this approach.

The way I chose combines scaling up and down by repeating/dropping lines. It calculates how much the output is "behind" the input, and writes a line whenever output is behind. It works like

diff is initially 0 (or minus input height / 2 for more symmetry)
for every input line
    read the line into array
    add output height to diff
    while diff greater than 0
        write horizontally resized input line
        subtract input height from diff

In both cases, horizontal resize works equivalently to vertical.

Another way is for every output pixel to calculate the corresponding input pixel and fseek to its absolute position (using SEEK_SET).

| improve this answer | |

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .