Я хотел бы распечатать/сохранить QGraphicsScene
в формате Mono. Я сделал так, чтобы сцена содержала только один цветной объект (в одном из окон он на самом деле черно-белый).
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, я вижу, что рендеринг в моноизображение использует Qt::ThresholdDither
.
Если бы я, по крайней мере, мог применить другой дизеринг к рендерингу за один шаг, без необходимости сначала создавать цветное изображение, а затем дизеринг для нового монохромного изображения, это было бы огромным улучшением. Память и время очень важны.
Хотя, возможно, мне действительно нужен быстрый способ просмотреть каждый пиксель и установить его в 1, если его интенсивность выше 0,5, и в 0, если ниже? Это по-прежнему будет означать отдельный шаг после создания изображения rgb32, хотя... и по какой-то причине выполнение этого "вручную" всегда медленнее, чем встроенные методы.
Update2: элемент, нарисованный в этом примере, представляет собой прямоугольник с градиентной кистью. Я также разделил цвета на 4 QGraphicsScenes: если цвет == цвет1, то цвет2,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());
}