I am working on resize for pset4 and I can't get my code to work. It resizes smiley.bmp just fine but when I try to run it with small.bmp it comes back all wrong. I can't figure out what I have done wrong!
Here is my code:
Thanks!
CS50 Stack Exchange is a question and answer site for students of Harvard University's CS50. It only takes a minute to sign up.
Sign up to join this communityI am working on resize for pset4 and I can't get my code to work. It resizes smiley.bmp just fine but when I try to run it with small.bmp it comes back all wrong. I can't figure out what I have done wrong!
Here is my code:
Thanks!
Your code is amazing! I love how you save temporarily in an array every pixel of every row. This pset is definitely the second hardest one to me (pset5 is the hardest). But it is the most rewarding (graphics are always rewarding). It took me about 30 hours to do this pset the first time and I love your wit and approach. After pset5, CS50 just get easier easier. And I can see that you are having no problem thinking critically. Keep the good work.
I noticed 5 things that might cause you errors:
SOLVING PEEK
Comparing your file headers with theirs (theirs should be correct):
If you execute
./resize 7 small.bmp small7.bmp
then
~cs50/pset4/resize 7 small.bmp small7s.bmp
you can do
~cs50/pset4/peek small7.bmp small7s.bmp
That command will show you both BITMAPFILEHEADER
s and both BITMAPINFOHEADER
s side by side. If they're equal, they show in green. if they are not equal, they show in red.
When I compared your small7.bmp
against their small7s.bmp
, it showed two differences:
bfSize
and biSizeImage
1.- biSizeImage
:
This was your formula for it:
bi.biSizeImage = ((bi.biWidth) * abs(bi.biHeight) * sizeof(RGBTRIPLE)) + paddingb;
You need the amount of pixels in a row (bi.biWidth
) times the size of a pixel (sizeof(RGBTRIPLE)
) plus the padding (which each unit is smaller than a pixel). All that, times the amount of rows (abs(bi.biHeight)
). That will give you:
bi.biSizeImage = ((bi.biWidth) * sizeof(RGBTRIPLE) + paddingb) * abs(bi.biHeight);
2.- bf.bfSize
:
The line that writes bf
to the resulting file is before the line that changes bf.bfSize
.
I suggest you move these two lines to right before you write the bi
. For example:
// WRITING BF IS RIGHT BEFORE WRITING BI
// write outfile's BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
// write outfile's BITMAPINFOHEADER
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
RESIZING THE IMAGE
3.- Your outer most loop executes biHeight
times. biHeight
is the original height times the factor since it gets changed on line 93. However, you have a loop that writes every row resizeby - 1
times inside of this outer most loop.
Divide by resizeby
your biHeight
in the outer most loop. For example:
// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight)/resizeby; i < biHeight; i++)
{
4.- This piece of code is inside of the loop that goes pixel by pixel in every row:
// skip over padding, if any
fseek(inptr, padding, SEEK_CUR);
// then add it back (to demonstrate how)
for (int k = 0; k < paddingb; k++)
{
fputc(0x00, outptr);
}
You don't want to skip padding and write padding after reading every pixel. You want to do it after every row.
Cut it and put it outside of the originalWidth
loop that has a j
counter on line 109. For example:
// iterate over pixels in scanline
for (int j = 0; j < originalwidth; j++)
{
// temporary storage
RGBTRIPLE triple;
// read RGB triple from infile
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
originalred = triple.rgbtRed;
originalgreen = triple.rgbtGreen;
originalblue = triple.rgbtBlue;
verticalred[j] = triple.rgbtRed;
verticalgreen[j] = triple.rgbtGreen;
verticalblue[j] = triple.rgbtBlue;
// write RGB triple to outfile
for (int aa = 0; aa < resizeby; aa++)
{
fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
}
} // CURLY BRACE THAT CLOSES originalWidth LOOP LINE ~136
// skip over padding, if any
fseek(inptr, padding, SEEK_CUR);
// then add it back (to demonstrate how)
for (int k = 0; k < paddingb; k++)
{
fputc(0x00, outptr);
}
5.- When you are going to repeat every row on the loop that you use your vertical arrays, you need to add padding after every row.
Copy and paste your padding loop after every row on that section. For example:
//resize vertical
//vertical storage
RGBTRIPLE vertical;
for (int dd = 0; dd < resizeby - 1; dd++)
{
for (int bb = 0; bb < originalwidth; bb++)
{
for (int cc = 0; cc < resizeby; cc++)
{
vertical.rgbtRed = verticalred[bb];
vertical.rgbtGreen = verticalgreen[bb];
vertical.rgbtBlue = verticalblue[bb];
fwrite(&vertical, sizeof(RGBTRIPLE), 1, outptr);
}
}
// COPY AND PASTE THESE THREE LINES FROM LINES 136-138
// LINE NUMBERS ACCORDING TO ORIGINAL CODE ON PASTEBIN
for (int k = 0; k < paddingb; k++)
{
fputc(0x00, outptr);
}
}