3
votes

My purpose is to provide a widget in which I can display an image, click anywhere on this image and display where I clicked. To do this I used Qt's image viewer example. I simply added a method to draw on the pixmap when I click :

void drawGCP(int x, int y)
{
    // paint on a "clean" pixmap and display it
    // origPixmap is the pixmap with nothing drawn on it
    paintedPixmap = origPixmap.copy();  
    QPainter painter(&paintedPixmap);
    painter.setPen(Qt::red);
    painter.drawLine(x - lineLength, y, x+lineLength, y);
    painter.drawLine(x, y - lineLength, x, y + lineLength);
    label->setPixmap(paintedPixmap);
}

It works perfectly fine. The problem comes when I zoom in. The label is resized, and I don't know how, some sort of blur is added to the image. Which is what I want. But, the cross that I draw is also blurred, and the lines are several screen-pixels wide. I want the cross to be always 1-pixel wide.

I tried to do the same thing with a QGraphicsView and QGraphicsPixmapItem. QGraphicsView has a built-in zoom, but here the blur is not applied.

How can I draw 1-pixel wide lines over a QPixmap displayed by a zoomable QLabel ?

update: Here is how I call drawGCP :

void ImageGCPPicker::scaleImage(double factor)
{
    scaleFactor *= factor;
    if (scaleFactor < MIN_ZOOM)
    {
        scaleFactor /= factor;
        return;
    }
    if (scaleFactor > MAX_ZOOM) 
    {
        scaleFactor /= factor;
        return;
    }

    horizontalScrollBar()->setValue(int(factor * horizontalScrollBar()->value() + ((factor - 1) * horizontalScrollBar()->pageStep()/2)));
    verticalScrollBar()->setValue(int(factor * verticalScrollBar()->value() + ((factor - 1) * verticalScrollBar()->pageStep()/2)));

    label->resize(scaleFactor * label->pixmap()->size());
    drawGCP(GCPPos.x(), GCPPos.y());
}

As you can see I draw the cross after the scaling is done.

1
draw the cross after zoom.UmNyobe
@UmNyobe Maybe it is that simple. But I don't see how to do it differently from what I do. Can you take a look at my update please ?undu

1 Answers

0
votes

The issue is that you are painting your cross then zooming, when you should zoom then painting.

label->setPixmap(paintedPixmap);

will scale paintedPixmap, with your cross already painted on the pixmap. You can modify drawGCP as follow:

  1. create a paintedPixmap with the label dimension
  2. Adjust the position int x, int y using the scale factor
  3. Paint the cross on paintedPixmap with the new coordinates.

Basically

void drawGCP(int x, int y, double factor)
{
    //redundant with factor
    bool resizeneeded = (label->size() != origPixmap(size));
    paintedPixmap = resizeneeded ? origPixmap.scaled(label->size()) : origPixmap.copy() ;  
    QPainter painter(&paintedPixmap);
    painter.setPen(Qt::red);

    //adjust the coordinates (can be done when passing parameters)
    x *= factor;
    y *= factor;
    painter.drawLine(x - lineLength, y, x+lineLength, y);
    painter.drawLine(x, y - lineLength, x, y + lineLength);

    //will not scale pixmap internally
    label->setPixmap(paintedPixmap);
}