Как сместить пиксели растрового изображения в Qt4 - PullRequest
1 голос
/ 26 апреля 2010

Я реализовал текстовый виджет выделения с использованием Qt4. Сначала я нарисовал текстовое содержимое на растровом изображении. А затем нарисуйте часть этого растрового изображения на устройстве рисования, вызвав painter.drawTiledPixmap (offsetX, offsetY, myPixmap)

Мое воображение заключается в том, что Qt заполнит весь текстовый прямоугольник выделенного содержимого содержимым myPixmap.

Есть ли еще более быстрый способ сместить весь существующий контент влево на 1 пиксель, а затем заполнить недавно открытую область шириной 1 пиксель и высотой N-px содержимым myPixmap?

Ответы [ 4 ]

1 голос
/ 05 мая 2010

Ваш подход, вероятно, один из самых быстрых, так как вы используете низкоуровневые методы рисования. Вы можете реализовать промежуточный подход между рисованием низкого уровня и параметром 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.

1 голос
/ 09 мая 2010

Хорошо. Это трюк, который я использовал для медленного оборудования в старые времена. Обычно буфер изображения выделяется в два раза шире, чем нужно, с 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));
}

Я не уверен, что это будет быстрее, чем просто изменить смещение изображения и нарисовать его в прямом направлении. Сегодняшнее аппаратное обеспечение действительно мощное, что делает многие старые приемы бесполезными. Но это забавно, играть неясные трюки. :)

1 голос
/ 26 апреля 2010

Привет,

одна из возможностей для достижения этой цели будет:

  1. Создайте QGraphicsScene + View и поместите растровое изображение туда дважды (как QGraphicsPixmapItem), чтобы они были рядом друг с другом.
  2. Размер представления должен соответствовать размеру (одного) растрового изображения.
  3. Затем, вместо перерисовки растрового изображения, вы просто перемещаете область просмотра вида, перемещаясь от одного растрового изображения к другому.
  4. Перейти в конец, чтобы создать цикл.

Это может быть или не быть быстрее (с точки зрения производительности) - я не проверял это. Но, может быть, стоит попробовать, хотя бы ради эксперимента.

0 голосов
/ 11 мая 2010

Почему бы просто не сделать это попиксельно? Из-за того, как кэши работают, записывая пиксель до того, как он доходит до конца. Затем вы можете заполнить последний столбец, читая с вашего другого изображения.

Тогда его довольно легко SIMD оптимизировать; хотя в этот момент вы начинаете оптимизацию для каждой платформы.

...