首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用指针设置8位灰度图像的像素颜色

使用指针设置8位灰度图像的像素颜色
EN

Stack Overflow用户
提问于 2020-11-29 16:18:30
回答 1查看 449关注 0票数 1

我有这样的代码:

代码语言:javascript
复制
QImage grayImage = image.convertToFormat(QImage::Format_Grayscale8);
int size = grayImage.width() * grayImage.height();
QRgb *data = new QRgb[size];
memmove(data, grayImage.constBits(), size * sizeof(QRgb));

QRgb *ptr = data;
QRgb *end = ptr + size;
for (; ptr < end; ++ptr) {
    int gray = qGray(*ptr);
}

delete[] data;

它的基础是:https://stackoverflow.com/a/40740985/8257882

如何使用该指针设置像素的颜色?

此外,使用qGray()并加载“更大”的映像似乎会导致崩溃。

这样做是可行的:

代码语言:javascript
复制
int width = image.width();
int height = image.height();
for (int y = 0; y < height; ++y) {
    for (int x = 0; x < width; ++x) {
        image.setPixel(x, y, qRgba(0, 0, 0, 255));
    }
}

但是,与显式操作图像数据相比,这是缓慢的。

编辑

好了,我现在有了这个代码:

代码语言:javascript
复制
for (int y = 0; y < height; ++y) {
    uchar *line = grayImage.scanLine(y);
    for (int x = 0; x < width; ++x) {
        int gray = qGray(line[x]);
        *(line + x) = uchar(gray);
        qInfo() << gray;
    }
}

而且看起来很管用。但是,当我使用只有黑白颜色并打印灰度值的图像时,黑色给我0,白色给我39。如何获得0-255范围内的灰度值?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-29 20:34:37

首先,您在这一行中复制了太多的数据:

代码语言:javascript
复制
memmove(data, grayImage.constBits(), size * sizeof(QRgb));

ob大小为4字节,但根据文档,Format_Grayscale8像素的大小仅为8位或1字节。如果删除sizeof(QRgb),则应该复制正确的字节数量,假设位图中的所有行都是连续的(根据文档,它们不是对齐的--它们至少与32位对齐,因此必须在size中说明这一点)。数组data不应该是Qrgb[size]类型,而应该是ucahr[size]类型。然后,您可以随意修改data。最后,您可能需要使用接受图像位为QImage的构造函数创建一个新的uchar,并将新图像分配给旧图像:

代码语言:javascript
复制
auto newImage = QImage( data, image.width(), image.height(), QImage::Format_Grayscale8, ...);
grayImage = std::move( newImage );

但是,与复制图像数据不同,您可能只需通过bits()直接修改它的数据,或者更好地通过scanLine()修改它的数据,比如:

代码语言:javascript
复制
int line, column;
auto pLine = grayImage.scanLine(line);
*(pLine + column) = uchar(grayValue);

编辑

根据scanLine文档,图像至少对齐了32位.因此,如果您的8位grayScale图像是3像素宽,一条新的扫描线将启动每4个字节。如果您有一个3x3图像,容纳图像像素所需内存的总大小将为12。下面的代码显示了所需的内存大小:

代码语言:javascript
复制
int main() {
   auto image = QImage(3, 3, QImage::Format_Grayscale8);
   std::cout << image.bytesPerLine() * image.height() << "\n";
   return 0;
}

fill方法(将所有灰色值设置为0xC0)可以实现如下所示:

代码语言:javascript
复制
   auto image = QImage(3, 3, QImage::Format_Grayscale8);
   uchar gray = 0xc0;
   for ( int i = 0; i < image.height(); ++i ) {
      auto pLine = image.scanLine( i );
      for ( int j = 0; j < image.width(); ++j )
         *pLine++ = gray;
   }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65062305

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档