【问题标题】:Qt draw a blue pixel if the original pixel was black in a new image如果原始像素在新图像中是黑色的,Qt 会绘制一个蓝色像素
【发布时间】:2012-02-16 21:45:20
【问题描述】:

我编写了一些代码来制作新图像。我的背景图像有黑色区域,当 for 循环出现在黑色像素上时,它应该在新图像中绘制一个蓝色图像,否则它应该只绘制原始像素。以为我可以这样做,但程序继续运行。

   QApplication a(argc, argv);
int c, m, y, k, al;
QColor color;
QColor drawColor;
QImage background;
QImage world(1500, 768, QImage::Format_RGB32);
QSize sizeImage;
int height, width;
background.load("Background.jpg");
world.fill(1);
QPainter painter(&background);
sizeImage = background.size();
width = sizeImage.width();
height = sizeImage.height();

for(int i = 0; i < height; i++)
{
    for(int z = 0; z < width; z++)
    {
        color = QColor::fromRgb (background.pixel(i,z) );
        color.getCmyk(&c,&m,&y,&k,&al);

        if(c == 0 && m == 0 && y == 0 && k == 0) //then we have black as color and then we draw the color blue
        {
            drawColor.setBlue(255);
            painter.setPen(drawColor);
            painter.drawPoint(i,z);
        }
    }

}


//adding new image to the graphicsScene
QGraphicsPixmapItem item( QPixmap::fromImage(background));
QGraphicsScene* scene = new QGraphicsScene;
scene->addItem(&item);

QGraphicsView view(scene);
view.show();

是我的 for 循环错误还是我的画家?它说 QImage::pixel: 坐标 (292,981) 超出范围,但是对于这么多像素,它也不够快使用。

【问题讨论】:

  • “程序一直运行”是什么意思?它永远不会出现在 for 循环中?你没有得到你期望的结果?
  • 仅仅是因为循环非常慢吗?在我看来,通过像这样读取和写入单个像素来转换大图像会有点滞后!
  • 那有什么更好的方法呢?我想也许只重绘蓝色像素,但我不知道如何循环图像。
  • 告诉我们问题出在哪里。它永远不会结束吗?它完成了,但它很慢吗?结果你错了吗? ....
  • .jpg 有多黑? JPEG 压缩优化图像大小以供人类消费。由于人类无法很好地区分黑色和深灰色,因此压缩可能会将黑色变为灰色。对于白色背景上的细黑线(

标签: c++ qt


【解决方案1】:

如 cmets 中所述,逐个绘制像素可能非常慢。即使是逐像素访问也可以是quite slow。例如。以下可能更快,但仍然不是很好:

  const QRgb black = 0;
  const QRgb blue = 255;
  for(int y = 0; y < height; y++) {
    for(int x = 0; x < width; x++) {
      if (background.pixel(x,y) == black) {
         background.SetPixel(blue);
      }
    }
  }

更快的解决方案是通过scanline() 直接进行位操作。您可能想先致电convertToFormat(),这样您就无需处理可能的不同扫描线格式。

作为创意技巧,请致电createMaskFromColor 使所有黑色像素透明,然后在蓝色背景上绘制。

【讨论】:

  • 谢谢,速度很快,但代码没有任何变化为蓝色。
  • 好吧,我省略了实际的绘画部分。这只是改变QImage background。你仍然需要一个painter.drawImage() 电话。 (哦,而且对黑色很挑剔。深灰色不是黑色)。
  • 好吧,所以在整个 while 循环之后,我只需要再次绘制图像还是您的意思是在 if 测试中?
  • @user1007522:在for循环之后;这就是你获得速度的方式。您将只访问一次视频卡内存,用于一次大数据传输。他们很擅长。
  • K 我明白了,但如果我还是painter.drawImage(0,0,background);而画家是在世界图像上定义的,那么静止的世界就像原始图像一样。在我用 ilustrator 绘制的图像中,黑色是十六进制 00000。
猜你喜欢
  • 2019-07-25
  • 1970-01-01
  • 2015-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-19
  • 2018-09-28
相关资源
最近更新 更多