0
votes

I've written some code that should make a new image. My background image has black areas, when the for loop comes on a black pixel then it should draw in the new image a blue one instead otherwise it should just draw the original pixel. Thought I could do that like this but the program keeps running.

   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();

Is my for loop wrong or is it my painter? It sais QImage::pixel: coordinate (292,981) out of range but for soo many pixels, it is also not fast enough to use.

1
What do you mean by "the program keeps running"? It never comes out of the for loop? You don't get the result you expect?Bart
Is it simply that the loop is incredibly slow? It seems to me that transforming a large image by reading and writing individual pixels like that is going to lag a little!Robinson
What's a better approach then? I thought maybe only redraw the blue pixels but I don't know how to loop over the image.user1007522
Tell us what the problem is. Does it never finish? Does it finish, but is it slow? Is the result you get wrong? ....Bart
How black is that .jpg? JPEG compression optimizes image sizes for human consumption. Since humans can't distinguish black and dark grey very well, compression may change black to grey. It will certainly do so for thin black lines (<8 px) on a white background.MSalters

1 Answers

2
votes

As noted in the comments, drawing pixels one by one can be incredibly slow. Even pixel-by-pixel access can be quite slow. E.g. the following is probably faster, but still not very good:

  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);
      }
    }
  }

The quicker solution involves direct bitoperations via scanline(). You might want to call convertToFormat() first, so you don't need to deal with the different possible scanline formats.

As a creative hack, call createMaskFromColor to make all black pixels transparent, and then paint over a blue background.