【问题标题】:CS50 pset 4 resize Vertical stretching gives weird outputCS50 pset 4 resize 垂直拉伸给出奇怪的输出
【发布时间】:2017-04-26 16:43:37
【问题描述】:
#include <stdio.h>
#include <stdlib.h>

#include "bmp.h"

int main(int argc, char *argv[])
{
    // ensure proper usage
    if (argc != 4)
    {
        fprintf(stderr, "Usage: ./resize scale infile outfile\n");
        return 1;
    }

    // remember filenames
    int n = atoi(argv[1]);
    char *infile = argv[2];
    char *outfile = argv[3];

    // open input file 
    FILE *inptr = fopen(infile, "r");
    if (inptr == NULL)
    {
        fprintf(stderr, "Could not open %s.\n", infile);
        return 2;
    }

    // open output file
    FILE *outptr = fopen(outfile, "w");
    if (outptr == NULL)
    {
        fclose(inptr);
        fprintf(stderr, "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);
        fprintf(stderr, "Unsupported file format.\n");
        return 4;
    }

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


    //Changes the Width and Height of the final image
    bi.biWidth *= n;
    bi.biHeight *= n;

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

    int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // iterate over infile's scanlines
    for (int i = 1, biHeight = abs(bi.biHeight) + 1; i < biHeight; i++) {
        //array where the last line will be stored
        for (int curn = 0; curn < n; curn++) {
            long int temp = sizeof(RGBTRIPLE);
            // 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
                for (int k = 0; k < n; k++) {
                    fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
                }
            } 
            fseek(inptr, -temp * bi.biWidth, SEEK_CUR);
        }

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

        // then add it back (to demonstrate how)
        for (int k = 0; k < padding; k++)
        {
            fputc(0x00, outptr);
        }
    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // success
    return 0;
}

这是我正在使用的一长段代码。我试图理解关于同一主题的其他问题,但我无法将答案与我自己的代码相关联。我个人认为 for n 次的逻辑有问题,因为没有它会打印水平拉伸的图像,但我无法确定解决方案是什么。我的伪代码很简单:

    for each row
        for n times
            for each pixel in the row
                read from inptr
                for n times (second time)
                    write into outptr
                end of n times (second time)
            end of each pixel in the row
    skip over padding
    put the padding back
end of each row

这是应该被拉伸的Image1

这就是我使用 ./resize 4 smiley.bmp final.bmp Image3时的样子

感谢您的帮助!

【问题讨论】:

    标签: c resize logic cs50


    【解决方案1】:

    在编写BITMAPFILEHEADER
    BITMAPINFOHEADER 之前,您尚未更新biSizeImagebfSize

    此外,新文件的填充将更改。

    因此,计算新的填充,biSizeImagebfSize 使用

    padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    bi.biSizeImage = ((sizeof(RGBTRIPLE) * bi.biWidth + padding) * abs(bi.biHeight);
    bi.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    

    'intptr' 在fseek() 中的填充将不同于'outptr' 的填充。因此,将两个填充存储在
    不同的变量中。

    【讨论】:

      猜你喜欢
      • 2020-03-11
      • 1970-01-01
      • 1970-01-01
      • 2014-01-21
      • 2014-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多