如何使用C将BMP图像裁剪成两半

问题描述 投票:0回答:1

我正在编写一个程序,读取 BMP 文件,然后输出相同的 BMP 文件,但裁剪成两半。我通过简单地将 BMP 高度分成两半来实现此目的,这会导致 BMP 图像的上半部分被裁剪掉。但是,我只能剪掉上半部分。我试图找到一种方法来裁剪 BMP 图像的下半部分,但像素似乎从文件的底部开始写入,我试图让它们从文件的一半开始,或者可能从自上而下。

// Update the width and height in the BMP header
    header.width = newWidth;
    header.height = newHeight;

    printf("New header width: %d\n", header.width);
    printf("New header height: %d\n", header.height);

    // Write the modified BMP header to the output file
    fwrite(&header, sizeof(BMPHeader), 1, outputFile);

    // Calculate the padding
    int padding = (4 - (header.width * (header.bpp / 8)) % 4) % 4;

    // Copy the image data
    unsigned char pixel[4];
    for (int y = 0; y < newHeight; y++) {

            for (int x = 0; x < header.width; x++) {
                fread(pixel, sizeof(unsigned char), header.bpp / 8, inputFile);
                fwrite(pixel, sizeof(unsigned char), header.bpp / 8, outputFile);
            }
            for (int p = 0; p < padding; p++) {
                fputc(0, outputFile); // Write padding for the new image
            }

    }

    // Close the files
    fclose(inputFile);
    fclose(outputFile);

    printf("BMP image cropped successfully\n");

这基本上是执行图像裁剪的所有代码。我只使用 stdio.h 和 stdlib.h 库,并希望保持这种状态。输出的图像是原始图像的下半部分,但我希望也能够找到一种方法来保留上半部分。我使用的原始 BMP 图像是 3200x1200,我将新高度设置为 600 而不是 1200,这样新图像可以垂直切成两半。

编辑: header.height 和 header.width 变量都是正值。 header.height = 1200, header.width = 3200 原来。

Original BMP image (3200x1200) Cropped image (3200x600)

c crop bmp
1个回答
0
投票
int originalHeight = header.height;
...
int lineSize = newWidth * header.bpp / 8 + padding;
int skippedLines = originalHeight - newHeight;
long skippedBytes = ((long)lineSize) * skippedLines;

fseek(inputFile, skippedBytes, SEEK_CUR); // Skip half the lines at top.
unsigned char *linePixels = malloc(lineSize);
for (int y = 0; y < newHeight; y++) {
    fread(linePixels, sizeof(unsigned char), lineSize, inputFile);
    // You could copy the old padding.
    //memset(linePixels + lineSize - padding, '\0', padding);
    fwrite(linePixels, sizeof(unsigned char), lineSize, outputFile);
}
free(linePixels);

这将跳过阅读包含顶行的前半部分(反转 y 方向)。

正如已经评论的那样,还有更多

header
字段(
biSizeImage
)。 BMP 格式包含许多变体。 另外复制一点缓冲,每个 3-4 个字节更多,会更好。 当我引入
lineSize
时,我将其用作缓冲区大小。代码不会变得更少,而是变得更多可读。

© www.soinside.com 2019 - 2024. All rights reserved.