如何在Qt4中有效地移动像素图的像素

时间:2010-04-26 08:29:51

标签: performance qt text marquee pixmap

我使用Qt4实现了一个字幕文本小部件。我首先将文本内容绘制到像素图上。然后通过调用painter.drawTiledPixmap(offsetX,offsetY,myPixmap)将这个像素图的一部分绘制到绘图设备上

My Imagination是,Qt将使用myPixmap中的内容填充整个字幕文本矩形。

有没有更快的方法,将所有现有内容向左移动1px,然后使用myPixmap中的内容填充新曝光的1px宽和N-px高区域?

4 个答案:

答案 0 :(得分:1)

问候,

实现这一目标的一种可能性是:

  1. 创建一个QGraphicsScene + View并将pixmap放在那两次(如QGraphicsPixmapItem),这样它们就在彼此旁边。
  2. 调整视图大小以适合(一)像素图的大小。
  3. 然后,您只需重新定位视图的视口,而不是重新绘制像素图,从一个像素图移动到下一个像素图。
  4. 跳回到最后创建循环。
  5. 这可能会或可能不会更快(就性能而言) - 我还没有测试过。但是,如果只是为了实验,可能值得一试。

答案 1 :(得分:1)

您的方法可能是自使用低级绘画方法以来最快的方法之一。您可以在低级绘制和QGraphicsScene选项之间实现中间方法:使用包含标签的滚动区域。

以下是创建包含文本标签的新滚动区域的代码示例。您可以使用QTimer自动滚动标签以触发滚动效果,从而为您提供一个漂亮的选框小部件。

QScrollArea *scrollArea = new QScrollArea();

// ensure that scroll bars never show
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

QLabel *label = new QLabel("your scrolling text");

// resize the scroll area : 50px length and an height equals to its content height.
scrollArea->resize(50, label->size().height());
scrollArea->setWidget(label);
label->show(); // optionnal if the scroll area is not yet visible

使用QScrollArea::scrollContentsBy(int dx, int dy) dx参数等于-1,滚动区域内的文字标签可以从左向右移动一个像素。

答案 2 :(得分:1)

好。这是我过去常常使用较慢硬件的技巧。基本上,图像缓冲区的分配宽度是所需的两倍,开头有一条额外的线。构建缓冲区左侧的图像。然后重复绘制图像,缓冲区中的缓冲区一次前进1个像素。

int w = 200;
int h = 100;
int rowBytes = w * sizeof(QRgb) * 2; // line buffer is twice as the width
QByteArray buffer(rowBytes * (h + 1), 0xFF); // 1 more line than the height
uchar * p = (uchar*)buffer.data() + rowBytes; // start drawing the image content at 2nd line
QImage image(p, w, h, rowBytes, QImage::Format_RGB32); // 1st line is used as the padding at the start of scroll
image.fill(qRgb(255, 0, 0)); // well. do something to the image

p = image.bits() - rowBytes / 2; //  start scrolling at the middle of the 1st (blank) line
for(int i=0;i<w;++i, p+=sizeof(QRgb)) {
    QImage  scroll(p, w, h, rowBytes, QImage::Format_RGB32); // scrool 1 pixel at a time
    scroll.save(QString("%1.png").arg(i));
}

我不确定这会比仅更改图像的偏移并将其绘制成海峡更快。今天的硬件非常强大,这使得许多旧技巧变得毫无用处。但玩晦涩的技巧很有趣。 :)

答案 3 :(得分:0)

为什么不逐个像素地进行呢?由于缓存的工作方式是将像素一直写到一个像素之前,直到你到达终点。然后,您可以通过阅读其他图像填写最后一列。

然后很容易SIMD优化它;虽然你现在开始进入每个平台的优化。