0

I've stuck for days in this resize problem, first, here's my code

BITMAPINFOHEADER bi1 = bi;
    bi1.biWidth = bi.biWidth * n;
    bi1.biHeight = bi.biHeight * n;
    int padding1 =  (4 - (bi1.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    bi1.biSizeImage = (bi1.biWidth* sizeof(RGBTRIPLE) + padding1) * abs(bi1.biHeight);

    BITMAPFILEHEADER bf1 = bf;

    bf1.bfSize = bi1.biSizeImage + 54;



    // write outfile's BITMAPFILEHEADER
    fwrite(&bf1, sizeof(BITMAPFILEHEADER), 1, outptr);

    // write outfile's BITMAPINFOHEADER
    fwrite(&bi1, sizeof(BITMAPINFOHEADER), 1, outptr);

    // determine padding for scanlines
    int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;



    // iterate over infile's scanlines
    for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
    {
        // write the pixels with n times height
        for (int p = 0; p<n; p++)
        {
        // iterate over pixels in scanline
        for (int j = 0; j < bi.biWidth; j++)
        {
            // temporary storage
            RGBTRIPLE triple;

            // read RGB triple from infile
            fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

            // write RGB triple to outfile
            fwrite(&triple, sizeof(RGBTRIPLE), n, outptr);
        }

        // skip over padding, if any
        fseek(inptr, padding, SEEK_CUR);


        // add padding to out file
        for (int k = 0; k < padding1; k++)
        {
            fputc(0x00, outptr);
        }
        }
    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // that's all folks
    return 0;
}

I know it's no there yet, but I have some question:

  1. How does the BMP print out the pixel? ( Let's say biWidth is 12, Height is positive, so when it's creating, it prints from the bottom left pixel and works all the way up til it reach headerinfo? Everytime it reach position 12 of a line, does it automatically jump on the upper line and continue printing at pos 13 right up the head of pos 1 where it starts?

  2. In the walkthrough video, Zamyla mentioned using fseek to return to the start pos and keep printing, what's the logic behind that fseek? ( I do know how fseek works, I just don't understand it in this resize case) Sorry for the long question. Please help...

1 Answer 1

3

Let's see if I can answer your questions. I don't think you've got a handle on how the image data is processed and displayed. First, the image will print either from top to bottom, or from bottom to top, based on the sign of biHeight. Either way, the data is read sequentially from the file.

The header data is read, telling the computer the structure of the image to be displayed to the screen. The first line of pixels will then be read and the pixels displayed to the screen, whether it is at the top of the picture or the bottom. Each subsequent line is painted to the screen in order. (From your question, it seems as if you thought that when displaying bottom to top, it would go to the end of the image data and work backward. This is not the case.) At the end of each line, the padding, if any, is skipped and the next line starts.

Zamyla was trying to explain the logic behind scaling the image vertically. For horizontal scaling, you simply display each pixel n times. But you can't do that for both horizontal and vertical scaling. For the vertical scaling, you have to process each line of pixels n times. To do that, you would go back to the beginning of a line and reprocess it until it is displayed n times, before moving on to the next line. The fseek() goes back to the beginning of the line being processed, not to the beginning of the image.

So, those are the answers to your questions. Buried in there is also an explanation of something missing from your code, but I don't want to take away all the fun. ;-) Since you've been having so much difficulty, I'll also offer some advice. Start simple. Run the program against small.bmp with a scale of 1. Using a scale of 1 means the output file should be identical to the input file. Make sure the header info is right before working on the image. Then get the image right. Once you can use ./resize to make an exact copy of an input file, then go to scale of 2. This will reveal any remaining problems to be fixed.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

1
  • Thank you so much, as you've said, I really don't understand how image data is processed and displayed, and you've made it clearer now. I've understand the role of fseek, and after some time, I replaced the fwrite to write RGBTRIPLE with a for loop and it worked!! One last question, is fwrite(&triple, sizeof(RGBTRIPLE), n, outptr) different with a for loop(int t<n) with fwrite nested inside, replace n in fwrite = 1?
    – kenlenney
    Commented Dec 17, 2015 at 6:23

You must log in to answer this question.

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