Performance 如何在Qt4中高效地移动像素点

Performance 如何在Qt4中高效地移动像素点,performance,qt,text,marquee,pixmap,Performance,Qt,Text,Marquee,Pixmap,我已经使用Qt4实现了一个字幕文本小部件。我首先将文本内容绘制到一个pixmap上。然后调用painter.drawTiledPixmap(offsetX,offsetY,myPixmap)将此pixmap的一部分绘制到绘制设备上 我的想象是,Qt将用myPixmap中的内容填充整个字幕文本矩形 有没有比用myPixmap中的内容填充新暴露的1px宽和N-px高区域更快的方法,将所有现有内容向左移动1px 实现这一目标的一种可能性是: 创建一个QGraphicscene+视图,并将pixmap放

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

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

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

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

  • 创建一个QGraphicscene+视图,并将pixmap放在该视图上两次(与QGraphicsPixmapItem一样),使它们彼此相邻
  • 调整视图大小以适合(一)个像素贴图的大小
  • 然后,您只需重新定位视图的视口,从一个像素贴图移动到下一个像素贴图,而不是重新绘制像素贴图
  • 在末端向后跳转以创建循环

  • 这可能更快,也可能不会更快(就性能而言)-我还没有测试过它。但是,如果只是为了实验,可能值得一试。

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

    下面是创建包含文本标签的新滚动区域的代码示例。您可以使用
    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

    。这是我以前用较慢的硬件做的把戏。基本上,图像缓冲区的宽度是所需宽度的两倍,并且在开始时有一个额外的行。在缓冲区左侧构建映像。然后重复绘制图像,缓冲器在缓冲器中一次前进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));
    }
    
    intw=200;
    int h=100;
    int rowBytes=w*sizeof(QRgb)*2;//行缓冲区是宽度的两倍
    QByteArray缓冲区(行字节*(h+1),0xFF);//比高度多1行
    uchar*p=(uchar*)buffer.data()+行字节;//开始在第2行绘制图像内容
    QImage图像(p,w,h,rowBytes,QImage::Format_RGB32);//第一行用作滚动开始处的填充
    image.fill(qRgb(255,0,0));//好。对图像做点什么
    p=image.bits()-rowBytes/2;//从第一行(空白)的中间开始滚动
    
    对于(int i=0;i为什么不一个像素一个像素地做呢?因为缓存的工作方式是将像素一直写到它前面的一个,直到你到达最后。然后你可以通过读取另一个图像来填充最后一列


    然后,SIMD也可以很容易地对其进行优化;尽管此时您已经开始进行每个平台的优化。

    谢谢。但是QGraphicscene是基于浮点坐标的,而不是基于整数的。这种方法更快吗?我想,重要的不是qreal vs.int的使用,而是如何在内部处理图形。我猜这是一种移动该视图的视口比实际为每一帧反复绘制像素图优化得多。但正如我所说:我还没有对此进行任何测试或基准测试。如果您尝试,请告诉我您的结果,好吗?