如何在c语言中读取图像的像素?

4
假设我们的位图图像高度为M,宽度为N。在此实验中,我们将始终假设宽度N是4的倍数,这简化了文件中的字节布局。对于此图像,像素数组以以下方式精确地存储3 x N x M字节:

每组3个字节表示一个像素,其中字节按顺序存储像素的蓝色、绿色和红色值。

像素按行分组。例如,像素数组中前3 x N个字节表示图像最上面一行的像素。

pixel_array_offset 是像素数组开始的位置。

给出如下struct pixel

struct pixel {
    unsigned char blue;
    unsigned char green;
    unsigned char red;
};

以下是实现该功能的要求:

/*
 * Read in pixel array by following these instructions:
 *
 * 1. First, allocate space for m "struct pixel *" values, where m is the
 *    height of the image.  Each pointer will eventually point to one row of
 *    pixel data.
 * 2. For each pointer you just allocated, initialize it to point to
 *    heap-allocated space for an entire row of pixel data.
 * 3. ...
 * 4. ...
 */
struct pixel **read_pixel_array(FILE *image, int pixel_array_offset, int width, int height) {

}

首先,为m个"struct pixel *"值分配空间。我认为它实际上是为像素值数组分配空间。因此我放置了:

unsigned char **ptrs = height * malloc(sizeof(struct pixel));

对于第二步,我不太明白我应该做什么。我认为我需要一个for循环来为所有像素数据的行分配空间。但是我不知道里面应该放什么。

for (int i=0, i<height, i++) {

        }

你确定你的图像是无符号字符吗?也就是说,所有像素值都在0-255之间?你应该将其设置为模板,以便它可以处理许多不同类型的图像。许多图像可以是无符号短整型、短整型、浮点型,并且需要按照特定的方式分配。要为像素数组分配空间,你需要这样做:unsigned char* image = new unsigned char[width_of_image * height_of_image]。此外,你是如何读取GDAL、libjpg、libnt2等内容的呢?有许多不同类型的图像。每种类型都有自己的库,你需要使用这些库来打开头文件以获取元数据/读取数据。 - Omid CompSCI
注意:对于 BMP 图像,文件中的行长度始终是 4 字节的倍数,称为“步幅”。因此,如果图像宽度为 11 像素,则需要 36 字节的存储空间来存储 33 个 BGR 字节。你的示例通过“在本实验中,我们将始终假设宽度 N 是 4 的倍数,这简化了文件中的字节布局”来回避这个问题。 - Weather Vane
@ Weather Vane 我不熟悉这个图像。但我只是在开头添加了更多的需求信息。希望这样会让您更清楚。 - user8314628
第一步是为每行内存分配指针数组的空间。然后,您需要为这些指针中的每一个分配内存以创建一个结构体数组。 - Weather Vane
1
所以从技术上讲,第一步是为 m "struct pixel *" 分配空间。m x struct pixel * 如何变成 unsigned char **ptrs?也许是 struct pixel **ptrs?(现在从技术上讲,由于指针就是指针就是指针,而且它是一个 char 类型,所以你不会违反严格别名规则,因此你很幸运)。 - David C. Rankin
显示剩余2条评论
1个回答

5

如果您想分配一个二维数组,首先需要分配一个struct pixel *类型的数组:

struct pixel **ptrs = malloc(height * sizeof(struct pixel*));

这里需要注意几个更改:
  1. 你正在为struct pixel分配指针,而不是unsigned char
  2. malloc()返回指针。将指针乘以整数是无效的。
  3. 乘法在括号中,因为它有助于计算要分配的正确字节数。
接下来,您需要为2D数组中的每一行分配一个struct pixel数组:
for (int i=0, i<height, i++) {
    ptrs[i] = malloc(width * sizeof(struct pixel));
}

现在数组已经完全分配好了,您可以用数据填充它了:
ptrs[5][6] = { 255, 0, 0}; // a blue pixel

最后,记得在程序退出前释放所有指针:free()
for (int i=0, i<height, i++) {
    free(ptrs[i]);
}

free(ptrs);

这里的问题是关于从二维数组中读取数据。但你提到了写入。请写出从二维数组中读取数据的代码。 - RAP
@AdityaRao 这个问题是关于分配内存,而不是读取或写入。一旦所有指针都被分配,您可以像处理静态数组一样进行读取和写入。 - Code-Apprentice

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接