Печать / сохранение QGraphicsScene для монохромного изображения очень низкого качества

Я хотел бы распечатать / сохранить QGraphicsScene в моно формате. Я заставил сцену содержать только один цветной объект (в одном из окон он на самом деле черно-белый).

OutputView::OutputView(QWidget *parent)
: QGraphicsView(parent) {...}void OutputView::saveToImage()
{
QImage image(scene()->sceneRect().size().toSize(), QImage::Format_Mono);
image.fill(Qt::transparent);
QPainter painter(&image);
painter.setRenderHint(QPainter::Antialiasing); // seems to do nothing
render(&painter);
image.save("output.png");
painter.end();

// to test rgb, i am adding that - but I really need only mono
// I don't know why the background is black, but since I don't intend to use the color version, it is not relevant
QImage image1(scene()->sceneRect().size().toSize(), QImage::Format_RGB32);
image1.fill(Qt::transparent);
QPainter painter1(&image1);
render(&painter1);
image1.save("output1.png");
painter1.end();
}

Качество черно-белого изображения очень плохое!

Я ожидал, что красные пиксели станут черными, но только некоторые из них сделали. Для 4-й панели я ожидал, что все черные пиксели будут размещены как черные на монофоническом выходе, но опять же, только некоторые из них сделали.

введите описание изображения здесь

Есть ли способ сделать черно-белое изображение с черными пикселями, где объект имеет цвет, и белым в другом месте?

Я могу легко изменить код, который генерирует цветовые участки, чтобы выводить черный вместо исходного цвета, но это, похоже, не решает проблему (4-я панель имеет черный цвет, но моно изображение не содержит всех пикселей ).

Мне нужно моно из-за стоимости памяти …

Как сделать так, чтобы сцены правильно выводились в QImage?

Update1: Я даже пытался сменить цветное изображение — результат был пугающим (слишком светлый в областях, которые должны быть темнее, странные артефакты, плюс я добавляю дополнительный шаг, который занимает много времени и, что хуже всего, добавляя очень большое изображение RGB. .. чего именно я пытаюсь избежать, мне нужно монохромное изображение из-за очень ограниченных ресурсов)

    QImage image(scene()->sceneRect().size().toSize(), QImage::Format_RGB32);
image.fill(Qt::transparent);
QPainter painter(&image);
painter.setRenderHint(QPainter::Antialiasing); // seems to do nothing
render(&painter);
painter.end();
QImage image11 = image.convertToFormat(QImage::Format_Mono,
Qt::MonoOnly | Qt::DiffuseDither);
image1.save("output.png");

введите описание изображения здесь

Играя со встроенными методами qt dither, я вижу, что рендеринг в моно изображение использует Qt::ThresholdDither,

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

Хотя, возможно, мне действительно нужен быстрый способ пройти каждый пиксель и установить его на 1, если его интенсивность выше .5, и на 0, если ниже? Это все равно будет означать отдельный шаг после создания образа rgb32 … и по какой-то причине делать это «вручную» всегда медленнее, чем встроенные методы.

Update2: элемент, нарисованный в этом примере, представляет собой прямоугольник с градиентной кистью. Я также разделил цвета на 4 QGraphicsScenes: если color == color1, то color2,3,4 = Qt :: white и так далее.

void Item::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
{
QRadialGradient radialGradient(0, 0, 300, 100, 100);
radialGradient.setColorAt(0.0, color1);
radialGradient.setColorAt(0.27, color2);
radialGradient.setColorAt(0.44, Qt::white);
radialGradient.setColorAt(0.76, color3);
radialGradient.setColorAt(1.0, color4);
QBrush brush = QBrush(radialGradient);
painter->setBrush(brush);
painter->drawRect(boundingRect());
}

2

Решение

На данный момент мое решение:

  • для каждого элемента на сцене, если требуется преобразовать его в изображение, поместите его на сцену вместе со всеми объектами, которые сталкиваются и находятся над ним

  • сохранить прямоугольник клипа объекта в цветное изображение

  • преобразовать изображение в монохромный, используя Qt::OrderedDither, что создает меньше артефактов

  • разместить изображение на месте предмета на сцене

  • конвертировать сцену без монохромного использования по умолчанию (Qt::ThresholdDither)

Это может потребовать меньше памяти (в зависимости от размера элементов), но с высокой вероятностью многократно применять один и тот же процесс и сохранять в формате изображения области, расположенные друг над другом.

0

Другие решения


По вопросам рекламы [email protected]