You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

生成.ppm格式棋盘格图像仅特定Tile尺寸生效的问题求助

棋盘格PPM图像生成程序的Tile宽度异常问题

我编写了一个C程序,用于生成指定长宽、Tile尺寸及双色的.ppm格式棋盘格图像。程序使用一维size_t数组按行优先存储RGB像素值(每个像素包含3个取值范围为[0,255]的整数,数组总长度为像素数的3倍)。

我尝试过多种实现方式:单循环结合模运算填充像素、逐Tile填充等,最终选择逐行从上到下填充的方式。调试后发现程序存在异常:

  • Tile高度参数任意值均能正常工作
  • Tile宽度参数仅为20或100时,500x500的图像生成正确;即使是500的因数(如10、25、250等)也无法正常生成,表现为Tile高度显示异常

程序为确定性实现,相同输入输出一致,无非法指针操作或未初始化变量,已尝试重启系统排查。未在相关技术平台找到解决方案。以下是Tile宽度设为25时的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define IMAGE_SIZE_X 500
#define IMAGE_SIZE_Y 500
#define IMAGE_ARRAY_SIZE 3*IMAGE_SIZE_X*IMAGE_SIZE_Y
#define MAX_PIXEL_VALUE 255


/*
    Creates a .ppm binary image file, given a file path (relative or absolute) with the file
    extension, and two positive integer dimensions (horizontal and vertical pixels), a positive
    maximum pixel color value (commonly 255), and a one-dimensional array of non-negative integers
    representing RGB (red, green blue) pixel values, in that order. Returns EXIT_SUCCESS on
    success.

    If a file with the given path already exists, the file is overwritten.
    If the file could not be opened for writing, errno is set, an error message is printed to
    stderr, and EXIT_FAILURE is returned. If the file could not be closed properly, errno is set,
    and EXIT_FAILURE is returned.
*/
int write_ppm(const char* filepath, size_t* pic, const size_t size_x, const size_t size_y, const size_t maxval) {
    //  open the file as a binary file, create the file first if it does not exist
    FILE *fp = fopen(filepath, "wb");
    if(!fp) {
        fprintf(stderr, "Failed to open file named \"%s\" for writing\n", filepath);
        return EXIT_FAILURE;
    }

    //  header
    fprintf(fp, "P6\n%zu %zu\n%zu\n", size_x, size_y, maxval);

    //  populate the RGB pixel values
    for(size_t i = 0; i < 3*size_x*size_y; i+=3)
        fprintf(fp, "%c%c%c", (unsigned char) pic[i], (unsigned char) pic[i+1], (unsigned char) pic[i+2]);

    //  close the file
    if(fclose(fp) != 0)
        return EXIT_FAILURE;
    else
        return EXIT_SUCCESS;
}


//  create a checkerboard pattern on an array representing a .ppm file,
//  given two colors and the two side lengths of the checkerboard tiles
void checkerboard_ppm(size_t* pic,
                      const size_t size_x,
                      const size_t size_y,
                      const size_t color0[3],
                      const size_t color1[3],
                      const size_t tileLength_x,
                      const size_t tileLength_y)
{
    int color = 0;

    for(size_t row = 0; row < size_y; row++) {
        for(size_t col = 3*size_x*row; col < 3*size_x*(row+1); col += 3) {
            //  swap colors when reaching the rightmost part of a tile,
            //  but not at the right edge of the image
            if(((col/3) % tileLength_x == 0) && ((col/3) % size_x != 0))
                color = 1 - color;
            if(color == 0) {
                pic[col]     = color0[0];
                pic[col + 1] = color0[1];
                pic[col + 2] = color0[2];
            }
            else {
                pic[col]     = color1[0];
                pic[col + 1] = color1[1];
                pic[col + 2] = color1[2];
            }
        }
        //  swap colors after writing a number of rows equal to the tile height
        if((row + 1) % tileLength_y == 0)
            color = 1 - color;
    }
}


int main() {
    const size_t RED  [3] = {255,   0,   0},
                 BLUE [3] = {  0,   0, 255};

    size_t image[IMAGE_ARRAY_SIZE];
    checkerboard_ppm(image, IMAGE_SIZE_X, IMAGE_SIZE_Y, RED, BLUE, 25, 20);
    write_ppm("output.ppm", image, IMAGE_SIZE_X, IMAGE_SIZE_Y, MAX_PIXEL_VALUE);
    return EXIT_SUCCESS;
}

内容的提问来源于stack exchange,提问作者Adam El-Sawaf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:14:53