C++使用 3D 动态数组和向量

发布于 2024-09-26 13:10:25 字数 1592 浏览 5 评论 0原文

我是 C++ 新手,对此感到有点沮丧。下面,在 PixelsVector 中,我将每个像素 RGB 浮点值存储在 Pixel 中并想要转储 所有值都存储到带有pixelsArray的字节数组中,这样我就可以输出到图像文件。高度和宽度是指图像尺寸。下面的代码工作正常,但我需要指定 PixelArray 在运行时的大小,因为它可能并不总是 500x500 图像。

// WIDTH and HEIGHT specified at run-time
vector<vector<Pixel>> pixelsVector (WIDTH, vector<Pixel> (HEIGHT));

...

unsigned char pixelsArray[500][500][3];

for (int i = 0; i < 500; i++)
{
    for (int j = 0; j < 500; j++)
    {
        // Returns RGB components
        vector<float> pixelColors = pixelArray[i][j].getColor();

        for (int k = 0; k < 3; k++)
        {
            pixels[i][j][k] = pixelColors.at(k);
        }
    }
}

// write to image file
fwrite(pixelsArray, 1, 500*500*3, file);

如果我输入 HEIGHT 和 WIDTH 而不是上面的 500 和 500,则会出现错误,因为它们不是常量值。现在使用 3D 向量似乎确实有效,但 fwrite 不会将向量作为其第一个参数。我尝试使用三指针数组但是 它似乎根本不起作用——也许我用错了它。这里它使用 3D 矢量作为 PixelArray:

vector<vector<Pixel>> pixelsVector (WIDTH, vector<Pixel> (HEIGHT));

...

vector< vector< vector<unsigned char> > > pixelsArray;

for (int i = 0; i < HEIGHT; i++)
{
    pixels.push_back(vector< vector<unsigned char> >());

    for (int j = 0; j < WIDTH; j++)
    {
        pixels[i].push_back(vector<unsigned char>());

        vector<float> pixelColors;
        pixelColors = pixelArray[i][j].getColor();

        for (int k = 0; k < 3; k++)
        {
            pixels[i][j][k] = pixelColors.at(k);
        }
    }
}

// Error
fwrite(pixelsArray, 1, 500*500*3, file);

建议?

I'm new to C++ and getting a bit frustrated with it. Below, in pixelsVector, I am storing each pixel RGB float-value in Pixel and want to dump
all the values to a byte array with pixelsArray so I can output to an image file. HEIGHT and WIDTH refer to the image dimensions. The code below works fine, but I need to specify
the sizes of pixelsArray at run-time, because it may not always be a 500x500 image.

// WIDTH and HEIGHT specified at run-time
vector<vector<Pixel>> pixelsVector (WIDTH, vector<Pixel> (HEIGHT));

...

unsigned char pixelsArray[500][500][3];

for (int i = 0; i < 500; i++)
{
    for (int j = 0; j < 500; j++)
    {
        // Returns RGB components
        vector<float> pixelColors = pixelArray[i][j].getColor();

        for (int k = 0; k < 3; k++)
        {
            pixels[i][j][k] = pixelColors.at(k);
        }
    }
}

// write to image file
fwrite(pixelsArray, 1, 500*500*3, file);

If I put HEIGHT and WIDTH instead of 500 and 500 above, I get an error since they are not constant values. Now using a 3D vector does seem to work, but fwrite won't take a vector for its first argument. I tried using a triple-pointer array but
it doesn't seem to work at all - maybe I was using it wrong. Here it is using a 3D vector for pixelsArray:

vector<vector<Pixel>> pixelsVector (WIDTH, vector<Pixel> (HEIGHT));

...

vector< vector< vector<unsigned char> > > pixelsArray;

for (int i = 0; i < HEIGHT; i++)
{
    pixels.push_back(vector< vector<unsigned char> >());

    for (int j = 0; j < WIDTH; j++)
    {
        pixels[i].push_back(vector<unsigned char>());

        vector<float> pixelColors;
        pixelColors = pixelArray[i][j].getColor();

        for (int k = 0; k < 3; k++)
        {
            pixels[i][j][k] = pixelColors.at(k);
        }
    }
}

// Error
fwrite(pixelsArray, 1, 500*500*3, file);

Suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小姐丶请自重 2024-10-03 13:10:25

您可以使用 Boost.MultiArray 代替向量的向量,它允许您使用 .data() 方法访问底层内存。

看起来您正在尝试操作图像,因此您可能需要考虑使用 Boost。吉尔。

You could use Boost.MultiArray insead of vectors of vectors, which lets you access he underlying memory with the .data() method.

It looks like you are trying to manipulate images, so you might want to consider using Boost.Gil.

梅倚清风 2024-10-03 13:10:25

从最后一个代码片段开始:

vector<vector<Pixel>> pixelsVector (WIDTH, vector<Pixel> (HEIGHT));

对变量使用大写名称可能会导致与宏发生名称冲突。在 C++ 中,所有大写名称通常都保留给宏。

...

vector< vector< vector<unsigned char> > > pixelsArray;

想必这个向量与下面所谓的像素相同?

如果是这样,那么标准建议是它有助于发布真实的代码。

无论如何,为了在一次有效的操作中输出这些字节,您需要将这些字节连续存储在内存中。这样,向量的向量的向量就出来了。使用单个向量(C++ 保证 std::vector 的缓冲区连续存储)。

for (int i = 0; i < HEIGHT; i++)
{
    pixels.push_back(vector< vector<unsigned char> >());

    for (int j = 0; j < WIDTH; j++)
    {
        pixels[i].push_back(vector<unsigned char>());

此时,您有一个内部向量,但它是空的,大小为 0。

        vector<float> pixelColors;
        pixelColors = pixelArray[i][j].getColor();

大概 pixelArray 是您定义的类的实例?

        for (int k = 0; k < 3; k++)
        {
            pixels[i][j][k] = pixelColors.at(k);
        }

在这里,您尝试分配给最内层空向量的不存在元素。您可以提前适当调整其大小,或者对每个值使用 push_back 方法。

此外,您确定 float 值是 0 到 255 范围内的整数(或者更一般地说,0 到 UCHAR_MAX),而不是 0 到 1 范围内的整数?

也许您需要缩放这些值。

    }
}

// Error
fwrite(pixelsArray, 1, 500*500*3, file);

如果 pixelsArray 是一个(非空)字节向量,那么您可以使用 &pixelsArray[0] 来获取指向第一个字节。

现在我知道了,上面只是剖析了一些错误的地方,并没有直接告诉你什么是正确的。 :-)

但是需要更多信息来提供执行此操作的示例代码,例如(1)您的 float 值是多少,以及(2)您想要在文件中添加什么?

不管怎样,希望这有帮助,

——阿尔夫

From the last code snippet:

vector<vector<Pixel>> pixelsVector (WIDTH, vector<Pixel> (HEIGHT));

Using uppercase names for variables you risk name collisions with macros. In C++ all uppercase names are conventionally reserved for macros.

...

vector< vector< vector<unsigned char> > > pixelsArray;

Presumably this vector is the same as is called pixels below?

If so, then the standard advice is that it helps to post real code.

Anyway, in order to output those bytes in one efficient operation you need the bytes to be contiguously stored in memory. So a vector of vectors of vectors is out. Use a single vector (C++ guarantees contiguous storage for the buffer of a std::vector).

for (int i = 0; i < HEIGHT; i++)
{
    pixels.push_back(vector< vector<unsigned char> >());

    for (int j = 0; j < WIDTH; j++)
    {
        pixels[i].push_back(vector<unsigned char>());

At this point you have an inner vector but it's empty, size 0.

        vector<float> pixelColors;
        pixelColors = pixelArray[i][j].getColor();

Presumably pixelArray is an instance of a class you have defined?

        for (int k = 0; k < 3; k++)
        {
            pixels[i][j][k] = pixelColors.at(k);
        }

Here you're trying to assign to non-existent elements of the empty innermost vector. You can either size it properly in advance, or use the push_back method for each value.

In addition, are you sure that the float values are integers in range 0 through 255 (or more generally, 0 through UCHAR_MAX) and not, say, in the range 0 through 1?

Perhaps you need to scale those values.

    }
}

// Error
fwrite(pixelsArray, 1, 500*500*3, file);

If pixelsArray had been a (non-empty) vector of bytes, then you could use &pixelsArray[0] to obtain a pointer to the first byte.

Now, I know, the above only dissects some of what's wrong, and doesn't tell you directly what's right. :-)

But some more information would be needed to give example code for doing this, like (1) what are your float values, and (2) what do you want in your file?

Anyway, hope this helps,

– Alf

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文