【问题标题】:How to trace the missing pixels when using drawLine使用drawLine时如何跟踪丢失的像素
【发布时间】:2012-03-13 08:04:54
【问题描述】:

我们知道,在 qt 中绘制图像时,会使用 qpainter。最近,我使用 drawLine() 函数来绘制用户正在涂鸦的任何内容。这是通过将来自 mouseMoveEvent 的 lastPoint 和 currentPoint 传递给实现 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();
}

【问题讨论】:

  • 什么是drawLineTo?你怎么知道“像素丢失”?你为什么要打扰这些事情?
  • @UmNyobe,我在上面进行了编辑,显示了 drawLineTo 定义,我知道在 mouseMoveEvent() 中的 qDebug() 的帮助下绘制时像素丢失了。你看,如果我们画一条直线,那么这条线中的所有像素都应该被正确跟踪,但是有些像素被跳过了,我相信这是因为调用时发生了 user->kernel 和 kernel->user 切换画家引擎在图像上绘图。我对此感到困扰,因为我很想知道 drawLine() 是如何在两者之间添加像素
  • 缺少像素是什么意思?您期望得到 qith qDebug 什么?您得到了什么?
  • @webclectic,我画了一条直线,比如从 (10,10) 到 (100,10) (不完全是直线,但是是的,它看起来像一条直线),以及像素正如我在上面的评论中所说的那样,绘制的不是连续的,我认为这是因为函数调用开销。因此,不是在 (10,10) 到 (100,10) 之间获取所有“绘制”像素,而是在 mouseMoveEvent 发生时没有跟踪一些像素。当我们在图像上涂鸦时,是否可以获取所有“绘制”的像素值?

标签: qt qt4 qpainter


【解决方案1】:

首先,不要使用mouseEvent()。实际上处理鼠标事件应该尽可能快地完成。此外,查看 Qt 源代码也不是一个好主意,它可能会造成混淆。而是假设 Qt 为您提供了工作,并首先尝试回答“我做错了什么?”。正如我所说,在鼠标事件中绘制肯定是错误的。

您的描述确实很主观,也许您的输出图像更好。您是否正在尝试模仿笔(例如在 windows 油漆中)?在这种情况下,鼠标按钮必须按下吗?这是你的变量scribbling的目的吗?

还有更多。按照文档,QMouseEvent::buttons() 总是返回鼠标移动事件的所有按钮的组合。这很有意义:鼠标移动独立于按钮。这意味着

if ((event-&gt;buttons() &amp; 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) 线的两个端点都满足这个等式,因此您可以轻松找到 ab。现在您需要做的就是从x0 增加到x1 您想要的像素(例如 1),并计算相应的 y 值,每次节省 point(x,y)

因此将遍历pixelList 中保存的所有点,并对任意两个连续点重复此过程。

【讨论】:

  • 供您参考,我没有在 mouseEvent 中绘制,我的绘制应用程序类似于 Qt 示例小部件项目中的 Scribble。我也使用了上面描述的 mouseEvents,除了我们在涂鸦时不需要 event->buttons() 和 Qt::LeftButton 条件检查。然而尝试使用 posF() 而不是 pos()。让我看看
  • 是的,但是您正在绘制图像...并且您调用 update();
  • 使用 QMouseEvent 的 posF() 已完成尝试。看,渲染不错,但我想知道我是否可以得到所有绘制的像素值?
  • 它应该是你的 QPen 的颜色。在这种情况下是蓝色的。
  • 是的,在这种情况下它是蓝色的。我查看了这个链接:stackoverflow.com/questions/1219827/… 答案是在两个子像素之间使用 drawLine。就我而言,我想知道是否有任何方法可以计算我们作为参数发送给 drawLine() 的任意两个像素之间的所有子像素?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多