How to show black-and-white image from binary data?
-
wrote on 13 Jan 2023, 07:10 last edited by w.tkm
I want to show black-and-white image from binary data.
I was able to output from binary data. But, If the image size is set to 1000*1000, the output will be rectangular instead of square.
Also, resizing does not work well and the image display is corrupted.
How can I modify the current code to achieve the desired display?#include "Widget.h" #include "ui_Widget.h" #include <QDebug> #include <QImage> #include <QPainter> #include <QMouseEvent> Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); // Set window Color QPalette Pal(palette()); Pal.setColor(QPalette::Window, "lightgreen"); this->setAutoFillBackground(true); this->setPalette(Pal); iPixSize = 1000; DrawImage(); ui->Layer->installEventFilter(this); } Widget::~Widget() { delete ui; } bool Widget::eventFilter(QObject *obj, QEvent *event) { QMouseEvent* clickEv = static_cast<QMouseEvent*>(event); if(event->type() == QEvent::MouseButtonPress ) { if(clickEv->button() == Qt::LeftButton){ iPixSize += 100; qImage = qImage.scaled(iPixSize, iPixSize, Qt::IgnoreAspectRatio); } else if (clickEv->button() == Qt::RightButton){ iPixSize -= 100; qImage = qImage.scaled(iPixSize, iPixSize, Qt::IgnoreAspectRatio); } ui->Layer->update(); return true; } if( event->type() == QEvent::Paint ) { QPainter painter(ui->Layer); painter.drawImage(100, 100, qImage); painter.end(); return true; } return false; } void Widget::DrawImage() { // QImage set. qImage = QImage(iPixSize, iPixSize, QImage::Format_Mono); qImage.setDevicePixelRatio(3.0); qImage.setColor(0, QColor{ Qt::white}.rgba() ); qImage.setColor(1, QColor{ Qt::black}.rgb()); int iPixX = 0; int iPixY = 0; // Binary data set. unsigned char* ucImageData = new unsigned char[125000]; memset(ucImageData, 0, sizeof(*ucImageData)); for(int i = 0; i < 125000; i++) { ucImageData[i] = 170; // Example binary data. for ( int j = 7; j >= 0; j-- ) { qImage.setPixel(iPixX,iPixY, ( (ucImageData[i] >> j) & 1 ) ); iPixX++; if ( iPixX == iPixSize ) { iPixX = 0; iPixY++; } } } }
One bit of binary data is one pixel.
For example, when [ ucImageData = 170 ]
■□■□■□■□
will be displayed as. -
I want to show black-and-white image from binary data.
I was able to output from binary data. But, If the image size is set to 1000*1000, the output will be rectangular instead of square.
Also, resizing does not work well and the image display is corrupted.
How can I modify the current code to achieve the desired display?#include "Widget.h" #include "ui_Widget.h" #include <QDebug> #include <QImage> #include <QPainter> #include <QMouseEvent> Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); // Set window Color QPalette Pal(palette()); Pal.setColor(QPalette::Window, "lightgreen"); this->setAutoFillBackground(true); this->setPalette(Pal); iPixSize = 1000; DrawImage(); ui->Layer->installEventFilter(this); } Widget::~Widget() { delete ui; } bool Widget::eventFilter(QObject *obj, QEvent *event) { QMouseEvent* clickEv = static_cast<QMouseEvent*>(event); if(event->type() == QEvent::MouseButtonPress ) { if(clickEv->button() == Qt::LeftButton){ iPixSize += 100; qImage = qImage.scaled(iPixSize, iPixSize, Qt::IgnoreAspectRatio); } else if (clickEv->button() == Qt::RightButton){ iPixSize -= 100; qImage = qImage.scaled(iPixSize, iPixSize, Qt::IgnoreAspectRatio); } ui->Layer->update(); return true; } if( event->type() == QEvent::Paint ) { QPainter painter(ui->Layer); painter.drawImage(100, 100, qImage); painter.end(); return true; } return false; } void Widget::DrawImage() { // QImage set. qImage = QImage(iPixSize, iPixSize, QImage::Format_Mono); qImage.setDevicePixelRatio(3.0); qImage.setColor(0, QColor{ Qt::white}.rgba() ); qImage.setColor(1, QColor{ Qt::black}.rgb()); int iPixX = 0; int iPixY = 0; // Binary data set. unsigned char* ucImageData = new unsigned char[125000]; memset(ucImageData, 0, sizeof(*ucImageData)); for(int i = 0; i < 125000; i++) { ucImageData[i] = 170; // Example binary data. for ( int j = 7; j >= 0; j-- ) { qImage.setPixel(iPixX,iPixY, ( (ucImageData[i] >> j) & 1 ) ); iPixX++; if ( iPixX == iPixSize ) { iPixX = 0; iPixY++; } } } }
One bit of binary data is one pixel.
For example, when [ ucImageData = 170 ]
■□■□■□■□
will be displayed as.@w-tkm Why don't you use QImage QImage::Format_Mono or QImage::Format_MonoLSB as format and then simply draw the image instead of drawing each pixel manually?
-
@w-tkm Why don't you use QImage QImage::Format_Mono or QImage::Format_MonoLSB as format and then simply draw the image instead of drawing each pixel manually?
-
@jsulm
Since I want to generate images based on the binary data sent to us, I cannot take the means of loading the original image.@w-tkm said in How to show black-and-white image from binary data?:
I cannot take the means of loading the original image
I'm not talking about loading original picture, but using your binary data to create a QImage by using https://doc.qt.io/qt-6/qimage.html#fromData-2
What image format is used for your original image you're sending? -
@w-tkm said in How to show black-and-white image from binary data?:
I cannot take the means of loading the original image
I'm not talking about loading original picture, but using your binary data to create a QImage by using https://doc.qt.io/qt-6/qimage.html#fromData-2
What image format is used for your original image you're sending? -
wrote on 13 Jan 2023, 09:16 last edited by
@w-tkm said in How to show black-and-white image from binary data?:
I was able to output from binary data. But, If the image size is set to 1000*1000, the output will be rectangular instead of square.
Source pixels or screen pixels may not be square, or may differ in aspect ratio. Hard to say what applies to your case.
There is no original format because the binary data is automatically generated by the program.
So the source just sends you a million bits in random arrangement? Of course not... it is sending you data in some arrangement. Chances are this is left to right, top to bottom, 8 pixels per byte and yu can use something like this to make the QImage much faster:
#include <QGuiApplication> #include <QByteArray> #include <QImage> #include <QDebug> int main(int argc, char *argv[]) { QGuiApplication a(argc, argv); // Build a test raw image. QByteArray data; data.reserve(1024*128); for (int row = 0; row < 1024; ++row) { // 1024 rows for (int col = 0; col < 128; ++col) { // 128 bytes = 1024 pixels data.append(0xaa); } } // Convert to QImage // Be sure to read about the lifetime requirements on the source buffer. QImage result(reinterpret_cast<uchar*>(data.data()), 1024, 1024, 128, QImage::Format_Mono); result.setColorCount(2); result.setColor(0, QColor("black").rgb()); result.setColor(1, QColor("white").rgb()); qDebug() << result; result.save("/tmp/test.png"); return 0; }
1/6