0

First of all I know there are a lot of other questions like this but I have looked at all of them. They have helped a lot but I am still stuck. I can't see anything logically wrong with my code, but the picture comes out distorted. Any help appreciated.

// iterate over infile's scanlines
    for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
    {
    //create an RGBTRIPLEs array named line of size (bi.biwidth)
        RGBTRIPLE line[bi.biWidth];

        // 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 n times to resize horizontally
            for(int l = 0; l < n; l++)
            {
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);

                //store the line into the array
                line[l] = triple;
            }

            for (int m = 0; m < n; m++)
            {
                fwrite(&line, sizeof(line), 1, outptr);

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

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

Following your code, it appears that you're not using the array as you're supposed to. An array should store a whole scanline, whether that scanline is resized or not, and each element in it should be written n times in case the stored scanline is NOT resized or just one time if the stored scanline is already resized.

Let me demonstrate with a simple example. Given the following BMP image and the resizing factor as 2,

00ff00 00ff00 00ff00 000000
00ff00 ffffff 00ff00 000000
00ff00 00ff00 00ff00 000000

At the first iteration of the very outer for loop, the array should store

00ff00 00ff00 00ff00 // in case you prefer storing it unresized

Or

00ff00 00ff00 00ff00 00ff00 00ff00 00ff00 // in case you prefer storing it resized

Notice that you have to determine beforehand whether you decided to store it resized or not because eventually, you'll need to specify the size of the RGBTRIPLEs array.

What you're really doing is that you're sort of mixing up between the approaches. You're reading an RGBTRIPLE at a time, but you're not storing the RGBTRIPLE in the array or resizing it horizontally (i.e., writing it n times) and storing it in the array. Rather, you're just writing it n times to the new BMP and storing it n times in the array. And then you're writing the whole array n times.

Also, you shouldn't be skipping over the padding each time you read an RGBTRIPLE from the old BMP. You should only do that after you read a whole scanline.

So, in short, you should do the following

Approach #1: Storing the Original Scanline:

for each scanline in the original BMP
{
    for each RGBTRIPLE in that scanline
    {    
        read the current RGBTRIPLE
        store it into the current index in the array
    }

    // now you already read and stored a whole scanline
    // it's time to write to the new BMP

    do n times // we're to repeat the nested process n times to resize vertically
    {
        for each RGBTRIPLE in the array
        {
            write the current RGBTRIPLE n times // to resize it horizontally
        }

        // now you wrote a whole resized scanline to the new BMP

        add the new padding to the new BMP
    }

    skip over the old padding in the original BMP
}

Approach #2: Storing the Scanline Resized:

this approach won't differ that much from the previous one.

for each scanline in the original BMP
{
    for each RGBTRIPLE in that scanline
    {    
        read the current RGBTRIPLE
        store n copies of it into the array
    }

    // now you already read a whole scanline, resized it horizontally and stored it
    // it's time to write to the new BMP

    do n times // we're to repeat the nested process n times to resize vertically
    {
        write the whole array once

        // now you wrote a whole resized scanline to the new BMP

        add the new padding to the new BMP
    }

    skip over the old padding in the original BMP
}

Hope that helps!

2
  • to "store n copies of it into the array" (approach 2 line 4) would you use a loop? How would you nest the loops so that the computer knows to read one triple, then store it n times? – Sofia Sep 15 '14 at 2:45
  • @Sofia maybe you should use a variable to keep track of the current index in the array and a simple loop to put the RGBTRIPLE in the array n times! – Kareem Sep 15 '14 at 8:04
1

You're not making use of your RGBTRIPLE array. You declare it, but then you directly write the temporary triples you read from your infile into your outfile. Instead, try to read your infile one RGBTRIPLE at a time, storing it n times in that array, and at the end of each horizontal line, writing that array n times (each time with padding) into your outfile.

Your code does not account for vertical resizing! You not only need to write each RGBTRIPLE n times into your outfile, you also need to write that whole line n times into your outfile!

Hope this helps.

2
  • Oh, and be careful: Your RGBTRIPLE array needs to be of size n times the width of the original picture, not just the width of the original picture, because you want to be storing each RGBTRIPLE from the original picture n times in that array! – pat_krat Sep 13 '14 at 18:07
  • I'm trying to do exactly what you are saying, but it's not working. As far as I can tell, I'm reading the RGBTRIPLEs, storing them in the array n times, and writing them to the outfile n times ( with my l and m loops). With regards to the comment, my biWidth is already times n. I still don't understand why my code is wrong. – Sofia Sep 14 '14 at 3:12

You must log in to answer this question.

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