c++ - 在 C++ 中使用 scanLine() 方法存储所有 QImage 的像素

标签 c++ arrays qt pointers pixel

我正在尝试使用带有 scanLine()Qt 修改图像方法。此方法返回指向给定行数据的指针。我创建了如何读取行 here .现在,我能够像这样读取所有像素的值:

QRgb ** pixels;

pixels = (QRgb **) (malloc(sizeof (QRgb*) * img->width() * img->height()));

#pragma omp parallel for
for (int y = 0; y < img->height(); ++y) {
    pixels[y] = (QRgb*) img->scanLine(y);
}

for (int x = 0; x < img->width(); ++x) {
    for (int y = 0; y < img->height(); ++y) {
        int color =  qRed(pixels[y][x]);
        std::cout << "Pixel at " << x << ", " << y << " is " << color << std::endl;
    }
}

然后,我处理每个像素并尝试将它们添加到新的 QRgb ** 变量中,但这是程序在执行时失败的地方。

QRgb ** finalPixels;

finalPixels = (QRgb **) (malloc(sizeof (QRgb*) * img->width() * img->height()));

    for (int x = 0; x < img->width(); ++x) {
        for (int y = 0; y < img->height(); ++y) {

            // Process pixels[y][x]


            QColor final(/* some new value */);
            QRgb finalrgb = final.rgb();

            finalPixels[y][x] = finalrgb; // What I realy want to do - Make the program fail
            finalPixels[y][x] = &finalrgb; // Don't build : invalid conversion from ‘QRgb* {aka unsigned int*}’ to ‘QRgb {aka unsigned int}’
            finalPixels[y][x] = pixels[y][x]; // Make the program fail


        }
    }

我不明白为什么我不能将 finalPixels[y][x] 的引用更改为新的引用。变量的类型不正确?或者这不是怎么办?我阅读了一些关于二维数组和指针的内容,但我仍然无法弄清楚这里的问题是什么。

编辑

@rames 通过建议使用 pixel()setPixel() 方法回答了这个问题。这些方法更容易使用,但这不是我要找的。我的第一个实现是使用这些方法,但作为 setPixel() method's documentation说:

Warning: This function is expensive due to the call of the internal detach() function called within; if performance is a concern, we recommend the use of scanLine() to access pixel data directly.

由于我的目标是对图像应用滤镜,例如模糊、边缘检测,我需要性能,所以这就是我尝试使用 scanLine() 的原因。


我试图改变我的变量类型。然后像这样简单地改变像素的颜色:

QRgb * pixels[img->height()];


#pragma omp parallel 
for (int y = 0; y < img->height(); ++y)
   pixels[y] = (QRgb*) img->scanLine();
}

for (int x = 0; x < img->width(); ++x) {
  for (int y = 0; y < img->height(); ++y) {
      QColor c(0,0,0);
      QRgb cr = c.rgb();
      pixels[y][x] = cr;
  }
}

但当程序运行 pixels[y][x] = cr; 时,即使这样也会失败,我不明白为什么。 QtCreator 的输出是he program has unexpectedly finished.


好的,感谢@user3528438 和@Rames,我知道如何使用 scanLine() 方法修改图像的像素。但是我仍然找不到一种方法来获取变量中的所有像素。我的目标是拥有一个临时变量,这样我就可以用原始像素计算对图像的修改。这是我尝试的最后一件事:

QRgb * pixelsCopy[img->height()][img->width()];
QRgb * pColor;

for (int y = 0; y < img->height(); ++y) {
    for (int x = 0; x < img->width(); ++x) {
        pColor = new QRgb( (QRgb)img->scanLine(y)[x] );

        pixelsCopy[y][x] = pColor;
    }
}

for (int x = 0; x < img->width(); ++x) {
    for (int y = 0; y < img->height(); ++y) {
        int color =  qRed(*pixelsCopy[y][x]); // Return 0
        std::cout << "Pixel at " << x << ", " << y << " is " << color << std::endl;
    }
} 

这个编译运行的很好,但是所有的值都是0..如果我和原来的像素比较,情况就不是这样了。你能给我解释一下为什么我的值不是原来的 onces 并且在我的 *pixelsCopy 变量中都设置为 0 吗?而且,为每个像素调用 scanLine() 方法不是太重了吗?我还尝试将 *pixelsCopy 更改为 pixelsCopy,但我仍然得到 0 个值..

编辑 2

感谢@user3528438 和@Rames,我终于找到了一种将像素复制 到新变量中的方法,但我得到了奇怪的结果。我编写了一个代码来复制像素并将其重新应用于图像,但我没有得到相同的图像。

QRgb pixelsCopy[img->height()][img->width()];

for (int y = 0; y < img->height(); ++y) {
    QRgb * line = reinterpret_cast<QRgb *>(img->scanLine(y));
    for (int x = 0; x < img->width(); ++x) {
        pixelsCopy[y][x] = line[x];
    }
}

for (int x = 0; x < img->width(); ++x) {
    for (int y = 0; y < img->height(); ++y) {
        int r = qRed(pixelsCopy[y][x]);
        QColor final(r, r, r);
        img->scanLine(y)[x] = final.rgb();

    }
}

这是之前和之后: enter image description here

它看起来像是一个坐标错误,但我检查了多次并没有看到任何东西。.如果你有一个更快和/或更干净的方法来复制原始像素,它会很高兴给我建议!

最佳答案

不要使用数组。 QImage类是为像素操作而设计的,你真的应该使用这个。假设 img 变量是 QImage * 类型:

QImage finalImage(*img);
for (int y = 0; y < finalImage.height(); ++y) {
    QRgb *line = reinterpret_cast<QRgb*>(finalImage.scanLine(y));
    for (int x = 0; x < finalImage.width(); ++x) {
        QRgb pixelRgb = line[x];
        // Process pixelRgb

        QColor final(/* some new value */);
        line[x] = final.rgb();
    }
}

关于c++ - 在 C++ 中使用 scanLine() 方法存储所有 QImage 的像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40598338/

相关文章:

c++ - C++中的非虚函数与虚函数调用效率

c++如何在不同的枚举名称中具有相同的枚举成员名称而不会出现错误:redefinition; previous definition was 'enumerator'

arrays - 在 Haskell 中修改数组并记住索引

javascript - 使用lodash将数组分组为树 "children"结构

qt - Qt 中 setVisble 后不要立即重新绘制

xml - Qt如何读取XML?

c++ - 类指针失去成员?

c++ - 如何在存在 2 个网卡的情况下为 UDP 多播设置套接字?

c++ - 动态数组和函数

c++ - 隐藏以前添加到 Qt TabWidget 的选项卡