通过 fread 将 jpg/png 读入点数组中

Read a jpg/png via fread into an array of Points

本文关键字:入点 数组 png fread jpg 通过      更新时间:2023-10-16

所以我使用的是中值切割算法(样本在这里找到(,它将.raw图像读入点。实际读数在这里完成:中位数切割算法

medianCutPoints = new QList< QList<int>* >();
FILE * raw_in;
int numPoints = 617*800;
Point* points = (Point*)malloc(sizeof(Point) * numPoints);
raw_in = fopen("C:\Users\David\Desktop\image.raw", "rb");
for(int i = 0; i < numPoints; i++)
{
    fread(&points[i], 3, 1, raw_in);
}
fclose(raw_in);

然后,通过算法生成调色板。

std::list<Point> palette =
    medianCut(points, numPoints, 15);

最后,我将点存储到列表中。

for (iter = palette.begin() ; iter != palette.end(); iter++)
{
    medianCutPoints->append(new QList<int>());
    medianCutPoints->last()->append((int)iter->x[0]);
    medianCutPoints->last()->append((int)iter->x[1]);
    medianCutPoints->last()->append((int)iter->x[2]);
}

但是,这似乎仅适用于.raw,因为没有像 jpeg 或 png 那样进行压缩。如果我输入 jpg/png,颜色与应有的颜色大相径庭。这基本上让我只能想到两个选择 - 使用 jpg 和 png 库将图像解码为.raw,或者以某种方式将压缩图像的每个像素读取为 Points。

我无法理解第一个循环的工作原理。我已经习惯了 C#.NET,那么 fread 究竟是如何工作的,Point* 点是如何设置的?如果我打印出点[宽度*高度].x[0],我会从RGB代码中得到一个数字。但是如果我也做点[0].x[宽度*高度],我仍然得到一个数字。我认为这将是点[点数].x[0-2],x是RGB的3个点。

有没有办法像 fread 对.raw所做的那样,将 jpg/png 中的点*点设置为每个像素?Qt是我第一次真正接触c++,这比我能理解的要复杂一些,而且我没有太多运气去寻找它是如何工作的。

如果您使用相同的算法从 png/jpg 文件中读取,它将不起作用.png 使用无损压缩,而 jpg 使用有损压缩。其中的数据将与"原始"映像的设置方式不同。通过查看上面的算法,"原始"图像以RGB格式设置。因此,您的fread是在每个点上读取 3 个字节。点结构存储 3 个值 x[],在本例中对应于 R(红色(、G(绿色(、B(蓝色(。

请注意,点是一个数组,因此在内存中是连续的。假设你在点结构中只有 x[3],并且width*height没有溢出,points[0][width*height]会给你 points[(width*height)/3][(width*height)%3] 的值。本质上,第一个和第二个下标被添加到点的内存位置。

要使用QT读取图像,您可以尝试QImageReader。它支持多种格式:http://doc.qt.io/archives/qt-4.7/qimagereader.html#supportedImageFormats