代码之家  ›  专栏  ›  技术社区  ›  stanleyxu2005

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

  •  1
  • stanleyxu2005  · 技术社区  · 15 年前

    我用Qt4实现了一个字幕文本小部件。我先把文本内容画在一个pixmap上。然后调用painter.drawTiledPixmap(offsetX,offsetY,myPixmap)将这个pixmap的一部分绘制到绘制设备上

    我的想象是,Qt将用myPixmap中的内容填充整个字幕文本矩形。

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

    4 回复  |  直到 15 年前
        1
  •  1
  •   Stephen Chu    15 年前

    好。这是我以前用较慢的硬件做的把戏。基本上,图像缓冲区的宽度是所需宽度的两倍,在开始处有一个额外的行。在缓冲区左侧构建图像。然后用缓冲器在缓冲器中一次前进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));
    }
    

    我不确定这会比仅仅改变图像的偏移量并绘制它更快。今天的硬件真的很强大,这使得很多老把戏都没用了。但玩一些晦涩难懂的把戏是很有趣的

        2
  •  1
  •   Robin    15 年前

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

    1. 调整视图大小以适合(一个)pixmap的大小。
    2. 在结尾处向后跳转以创建循环。

    这可能更快,也可能不会更快(在性能方面)-我没有测试过它。但也许值得一试,哪怕只是为了实验。

        3
  •  1
  •   Lohrun    15 年前

    您的方法可能是最快的方法之一,因为您使用低级绘制方法。可以在低级绘制和 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 .

        4
  •  0
  •   Goz    15 年前

    然后SIMD也很容易对其进行优化;尽管你现在已经开始进行单平台优化了。