Как отследить недостающие пиксели при использовании drawLine - PullRequest
0 голосов
/ 13 марта 2012

Мы знаем, что для рисования изображения в qt используется qpainter. Недавно я использовал функцию drawLine (), чтобы рисовать все, что пишет пользователь. Это было сделано путем передачи lastPoint и currentPoint из mouseMoveEvent к пользовательской функции, которая реализует drawLine (). Я передал аргументы для этой пользовательской функции, как указано ниже:

void myPaint::mouseMoveEvent(QMouseEvent *event) {  
qDebug() << event->pos();
   if ((event->buttons() & Qt::LeftButton) && scribbling) {
    pixelList.append(event->pos());
    drawLineTo(event->pos());
    lastPoint = event->pos();
   }
}

Теперь с помощью qDebug () я заметил, что при рисовании пропускаются некоторые пиксели, но рисунок получается точным. Я посмотрел на источник qt-painting, где увидел, что drawLine () вызывает drawLines (), который использует qpainterPath для рисования фигуры на изображении.

Мой вопрос таков: есть ли способ отследить эти «пропущенные» пиксели или какой-либо подход, чтобы найти все нарисованные пиксели?

Спасибо!

void myPaint::drawLineTo(const QPoint &endPoint) {    
QPainter painter(image); //image is initialized in the constructor of myPaint
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(QPen(Qt::blue, myPenWidth, Qt::SolidLine, Qt::RoundCap,Qt::RoundJoin));
painter.drawLine(lastPoint, endPoint);
modified = true;
lastPoint = endPoint; //at the mousePressEvent, the event->pos() will be stored as
                      // lastPoint 
update();
}

1 Ответ

2 голосов
/ 13 марта 2012

Для начала, не рисуйте mouseEvent(). На самом деле обработка события мыши должна быть выполнена как можно быстрее. Кроме того, смотреть на источник Qt не очень хорошая идея, это может сбивать с толку. Скорее предположим, что то, что дает вам Qt, и сначала попытайтесь ответить «Что я делаю неправильно? Как я уже сказал, рисование в событии мыши определенно неправильно.

Ваше описание действительно субъективно, возможно, изображение вашего вывода лучше. Вы пытаетесь эмулировать ручку (как в Windows рисовать)? В этом случае кнопка мыши должна быть нажата? это цель вашей переменной scribbling?

Есть еще. следуя документации, QMouseEvent :: buttons () всегда возвращает комбинацию всех кнопок для события перемещения мыши. Что имеет смысл: движения мыши не зависят от кнопок. Это значит

if ((event->buttons() & Qt::LeftButton)

всегда будет правдой.

Предположим, вы хотите нарисовать путь мыши, когда нажата левая кнопка. Тогда вы используете что-то вроде:

void myPaint::mousePressEvent(QMouseEvent *event){
     scribbling = true;
     pixelList.clear();
}

void myPaint::mouseReleaseEvent(QMouseEvent *event){
     scribbling = false;
}

void myPaint::mouseMoveEvent(QMouseEvent *event) {  
  if ( scribbling) {
    pixelList.append(event->pos());
  }
}

void myPaint::paintEvent(){
  QPainter painter(this)
  //some painting here
  if ( scribbling) {
     painter.setRenderHint(QPainter::Antialiasing);
     painter.setPen(QPen(Qt::blue, myPenWidth, Qt::SolidLine, Qt::RoundCap,Qt::RoundJoin));
    // here draw your path
    // for example if your path can be made of lines, 
    // or you just put the points if they are close from each other
  }

  //other painting here
}

Если после всего этого у вас нет хорошего рендеринга, попробуйте использовать точность с плавающей точкой (медленнее), то есть QMouseEvent::posF() вместо QMouseEvent::pos().

РЕДАКТИРОВАТЬ:
"Я хочу знать, есть ли способ вычислить все подпиксели между любыми двумя пикселями, которые мы отправляем в качестве аргументов в drawLine"
Да, есть. Я не знаю, почему вы должны делать такие вещи, но это действительно просто. Линия может быть охарактеризована уравнением

   y = ax + b

Обе конечные точки линии p0 = (x0, y0) и p1 = (x1, y1) удовлетворяют этому уравнению, поэтому вы легко можете найти a и b. Теперь все, что вам нужно сделать, это увеличить с x0 до x1 на сумму пикселей, которые вы хотите (скажем, 1), и для вычисления соответствующего значения y, каждый раз сохраняя point(x,y).

Поэтому пройдемся по всем точкам, сохраненным в pixelList, и повторим этот процесс для любых двух последовательных точек.

...