2015-04-23 7 views
2

Я хотел бы распечатать/сохранить QGraphicsScene в формате Mono. Я сделал сцену, содержащую только один цветной объект (в одном из окон он на самом деле черно-белый).Печать/сохранение 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-й панели я ожидал, что все черные пиксели будут помещены как черные в монофонический выход, но опять же, только некоторые из них.

enter image description here

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

Я могу легко изменить код, который генерирует цветовые секции, для вывода черного вместо исходного цвета, но это, похоже, не решает проблему (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"); 

enter image description here

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

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

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

Обновление2: Элемент, нарисованный в этом примере, представляет собой прямоугольник с градиентной щеткой. Я также разделил цвета на 4 QGraphicsScenes: if 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()); 
} 
+0

Отвернутое моно изображение выглядит совершенным тоже мной. Какая у вас конкретная проблема? Недифференцированное изображение просто пороговое, чтобы уменьшить среднюю ошибку. Вам нужно будет опубликовать полноразмерные примеры изображений и точный код, используемый для их рендеринга; если есть ошибки Qt, которые будут тестовыми. Как есть, вы не предоставляете достаточно деталей. –

+0

Мой вклад в рендеринг - это QGraphicsScene, содержащий коллекцию объектов в одном цвете. Выход должен быть монохромным растровым изображением из-за ограничений памяти. Также было бы здорово, чтобы он был как можно быстрее. Код, который я показал, - который сначала отображает моно-коллекцию объектов в гигантское изображение rgb, затем сбрасывает изображение гигантского rgb обратно в моно, имеет следующие проблемы: (1) добавляет гигантское изображение rgb (2) добавляет очень много времени шаг (3) качество выхода низкое (точки распространения ошибок, более светлый цвет) – Thalia

ответ

0

Сейчас мое решение:

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

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

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

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

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

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