任务是将bmp图像缩放为一个因子。我的代码直观地工作,当我检查缩放后的图片的十六进制且大小正确时,它看起来是正确的,但是check50表示图片太大。我通过下载图片检查了大小,并通过CS50 IDE查看了十六进制。我还尝试了GitHub上的其他代码,但该代码也被Check50拒绝。有什么错误?预先感谢!
// Copies a BMP file
#include <stdio.h>
#include <stdlib.h>
#include "bmp.h"
int main(int argc, char *argv[])
{
// ensure proper usage
if (argc != 4)
{
printf("Usage: copy infile outfile\n");
return 1;
}
// remember filenames
int factor = atoi(argv[1]);
char *infile = argv[2];
char *outfile = argv[3];
if(factor < 0 || factor > 100)
{
printf("facor must be between 0 and 100\n");
return 15;
}
// open input file
FILE *inptr = fopen(infile, "r");
if (inptr == NULL)
{
printf("Could not open %s.\n", infile);
return 2;
}
// open output file
FILE *outptr = fopen(outfile, "w");
if (outptr == NULL)
{
fclose(inptr);
printf("Could not create %s.\n", outfile);
return 3;
}
// read infile's BITMAPFILEHEADER
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi;
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);
printf("Unsupported file format.\n");
return 4;
}
//adjust fileheader
BITMAPFILEHEADER bf_out = bf;
BITMAPINFOHEADER bi_out = bi;
//HEIGHT AND WIDTH
bi_out.biWidth = bi.biWidth * factor;
bi_out.biHeight = bi.biHeight * factor;
// determine padding for scanlines
int padding = (4 - (bi_out.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
//IMAGESIZE
bi_out.biSizeImage = bi_out.biHeight * bi_out.biWidth * sizeof(RGBTRIPLE)+ padding;
//BITMAPFILEHEADER
bf_out.bfSize = bi_out.biSizeImage - sizeof(BITMAPFILEHEADER) - sizeof(BITMAPINFOHEADER);
// write outfile's BITMAPFILEHEADER
fwrite(&bf_out, sizeof(BITMAPFILEHEADER), 1, outptr);
// write outfile's BITMAPINFOHEADER
fwrite(&bi_out, sizeof(BITMAPINFOHEADER), 1, outptr);
printf("Original bfSize: %d\n", bf.bfSize);
printf("Resized bfSize: %d\n", bf_out.bfSize);
printf("Bitmapinfoheader: %lu\n", sizeof(BITMAPINFOHEADER));
printf("Bitmapfileheader: %lu\n", sizeof(BITMAPFILEHEADER));
printf("Original biSizeImage: %d\n", bi.biSizeImage);
printf("Resized biSizeImage: %d\n", bi_out.biSizeImage);
printf("Original biWidth: %d\n", bi.biWidth);
printf("Original biHeight: %d\n", bi.biHeight);
printf("Resized biWidth: %d\n", bi_out.biWidth);
printf("Resized biHeight: %d\n", bi_out.biHeight);
// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
// temporary storage
RGBTRIPLE triple[bi.biWidth];
// iterate over pixels in scanline
for (int j = 0; j < bi.biWidth; j++)
{
// read RGB triple from infile
fread(&triple[j], sizeof(RGBTRIPLE), 1, inptr);
}
for(int l = 0; l < factor; l++)
{
for(int o = 0; o < bi.biWidth; o++)
{
for(int g = 0; g < factor; g++)
{
fwrite(&triple[o], sizeof(RGBTRIPLE), 1, outptr);
}
}
for (int k = 0; k < padding; k++)
{
fputc(0x00, outptr);
}
}
}
// close infile
fclose(inptr);
// close outfile
fclose(outptr);
// success
return 0;
}
答案 0 :(得分:0)
//BITMAPFILEHEADER
bf_out.bfSize = bi_out.biSizeImage - sizeof(BITMAPFILEHEADER) - sizeof(BITMAPINFOHEADER);
文件大小是图片大小加标题大小。不是负数。
您可以替换它
// temporary storage
RGBTRIPLE triple[bi.biWidth];
// iterate over pixels in scanline
for (int j = 0; j < bi.biWidth; j++)
{
// read RGB triple from infile
fread(&triple[j], sizeof(RGBTRIPLE), 1, inptr);
}
仅需一次fread调用。无需循环。
RGBTRIPLE triple[bi.biWidth];
fread(triple, sizeof(RGBTRIPLE), bi.biWidth, inptr);
您还需要计算原始图像的填充,然后在读入缓冲区后查找过去。
答案 1 :(得分:0)
在网上寻找解决方案后,我终于设法找到了一个我也能理解的代码。也许它将帮助有类似问题的人。此解决方案适用于while循环而不是for循环,并且填充是在内部循环之外完成的,尽管代码几乎相同。
v[1]=NA
func(v,na.rm=T)