Solved QImage converting to RGB and saving new image!
-
What would be best
A. Convert image from RGBA to RGB -> Save it
B. Make a new image with the size of the original image, paint the background black, then paint the original image over the new image -> savethis is what i have so far
This is the File Dialog to select image
void MainWindow::on_BUTTON_SELECTIMAGE_MATRIX_clicked() { QString fileName = QFileDialog::getOpenFileName(this, tr("Open Image"), "c\\", tr("Image Files (*.png *.jpg *.bmp)")); ui->TEXT_IMG_PATH->setText(fileName); }
then send the image to this function that would do the converting
void MainWindow::imageHandler(QImage img) { QImage img2{img.size(), QImage::Format_RGB32}; img2.save("test.jpg"); }
-
Hi
I think convert
https://doc.qt.io/qt-5/qimage.html#convertToFormat
but since it returns a copy, the difference would not be
that huge but you avoid a bitblt (drawing it) -
@mrjj ty for that :) i'll try that! just a quick question! how do i get the image from
MainWindow::on_BUTTON_SELECTIMAGE_MATRIX_clicked()
tovoid MainWindow::imageHandler(QImage img)
-
Hi,
Use the path you got to construct a QImage and then call your other method with it.
-
void MainWindow::on_BUTTON_SELECTIMAGE_MATRIX_clicked() { QString fileName = QFileDialog::getOpenFileName(this, tr("Open Image"), "c\\", tr("Image Files (*.png *.jpg *.bmp)")); ui->TEXT_IMG_PATH->setText(fileName); imageObject = new QImage(); imageObject->load(fileName); if(!fileName.isEmpty()) { imageHandler(imageObject); } }
void MainWindow::imageHandler(QImage *img) { QImage img2{img->size(), QImage::Format_RGB32}; img2.save("test.jpg"); qDebug() << "Converting Complete"; }
Correct? the reason im asking is cause
qDebug() << "Converting Complete";
this was fired! but i can't find the file :S -
img2.save("test.jpg");
but i can't find the file :SThen try saving it with an absolute path instead of relative to the current directory?
Test the return result of thesave()
? -
so i found the picture in the
build
folder! and uhm... it looks weird!ORIGINAL:
and this is the copy from QImage (img2)
-
i got it working! :) but now the question remains can this be done with
Qimage
(from my python script)# Shift the fucker arround to being RGB565 self.final = [(r >> 3) << 11 | (g >> 2) << 5 | (b >> 3) for (r, g, b) in img.getdata() ]
extracting R,G,B from the image and store them in an array that i can send off to my 32x32 Matrix for display :)
-
@Kris-Revi
If just for image format conversion, QImage has predefined format for RGB565:QImage::Format_RGB16
The image is stored using a 16-bit RGB format (5-6-5).So you can convert the image to RGB565 directly using QImage converting function:
QImage newImage = img.convertToFormat(QImage::Format_RGB16);
But if you just need those arrays, AFAIK, there's no such convenient function to exact R,G,B arrays like in python.
You can write your own though. -
@Bonnie Ty for that :) still trying to figure out a way to get the RGB colors of each pixel and store them in a List :/
-
@Kris-Revi
That's not difficult in C++ at all.
The simplest and safest but not most efficient way is to get every pixel and save the R,G,Bint size = img.width() * img.height(); QVector<int> R, G, B; R.reserve(size); G.reserve(size); B.reserve(size); for(int y = 0; y < img.height(); y++) for(int x = 0; x < img.width(); x++) { QRgb rgb = img.pixel(x, y); R.append(qRed(rgb)); G.append(qGreen(rgb)); B.append(qBlue(rgb)); }
You can optimize the code to be more efficient by directly iterating from
img.constBits()
if you want. -
@Bonnie this is from my python PyQt5 script (that is tested and works)
[6371, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 6371, 2113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2113, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 288, 704, 320, 96, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, 1536, 8064, 3456, 3584, 3488, 480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 13349, 26219, 19912, 3456, 14275, 10081, 3360, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2273, 29678, 63359, 52761, 40339, 26218, 5760, 1504, 8800, 18432, 2048, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4258, 2113, 48631, 23210, 31663, 65471, 28140, 1376, 11072, 47168, 22528, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147, 6, 42261, 8422, 16938, 65503, 59164, 13574, 832, 34880, 26624, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 256, 704, 928, 3009, 2883, 27917, 4327, 21167, 59196, 56987, 32078, 2784, 26656, 20480, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 32, 608, 3424, 3296, 3552, 3680, 5696, 3456, 992, 29838, 54906, 50680, 34000, 2752, 20512, 10240, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 64, 960, 3584, 3488, 3200, 5760, 5824, 5760, 5664, 3520, 5345, 34063, 44278, 25612, 672, 8512, 2048, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 672, 3520, 5728, 7936, 12259, 12195, 7969, 5824, 5728, 5600, 1312, 7233, 19847, 7618, 1280, 1216, 8512, 2048, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 128, 3200, 3552, 5728, 14211, 30700, 24553, 10114, 5824, 5728, 5632, 3456, 1088, 1408, 1760, 5696, 3456, 7040, 12352, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 384, 3296, 3520, 5728, 14180, 24553, 18374, 9985, 5792, 3648, 5600, 3456, 1120, 9379, 38769, 51032, 46710, 23691, 10464, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 480, 3296, 3488, 5664, 7841, 7937, 7905, 5760, 5696, 5632, 5568, 3392, 1088, 17479, 65535, 65535, 61245, 48567, 12645, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 416, 3200, 3424, 5568, 5632, 5632, 5664, 5632, 5600, 5536, 3424, 1248, 992, 19560, 65535, 65503, 59164, 50712, 19049, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 256, 960, 3296, 3392, 5504, 3456, 3456, 5504, 3456, 3392, 1248, 3168, 832, 25707, 65471, 61277, 54970, 46486, 21130, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 64, 672, 3040, 3200, 3296, 3328, 3328, 3328, 3296, 3232, 3168, 3008, 672, 31887, 59100, 52825, 48599, 38066, 14791, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 256, 704, 2944, 3072, 3104, 3168, 3168, 3104, 3072, 2944, 768, 640, 29646, 44405, 44373, 38034, 27501, 6339, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 288, 576, 736, 2848, 2912, 2880, 2880, 768, 704, 640, 8708, 31727, 38034, 31727, 27469, 12710, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 224, 448, 544, 576, 576, 640, 608, 576, 10789, 21130, 29550, 25388, 23243, 14791, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 96, 224, 352, 416, 416, 6563, 16936, 23211, 21130, 14886, 8676, 4545, 8547, 10468, 4096, 2048, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2113, 6371, 12646, 19017, 16872, 12678, 14791, 2433, 608, 896, 2753, 14823, 12483, 8192, 4096, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2113, 6371, 4386, 4258, 10565, 14759, 12934, 7809, 14308, 3744, 17351, 48567, 31305, 20480, 2112, 128, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 256, 6339, 8484, 21130, 57050, 26251, 9953, 16357, 16005, 65535, 61147, 33158, 23464, 865, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 352, 2337, 4226, 16936, 54938, 65535, 57147, 9410, 12099, 7968, 36273, 56923, 40147, 29710, 2497, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 480, 224, 10533, 46486, 61277, 63390, 65503, 46646, 7489, 5984, 7426, 19465, 23307, 17064, 192, 0, 0, 0, 2145, 2113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 480, 4417, 31663, 50712, 54970, 59164, 61309, 65407, 23882, 5888, 5856, 1472, 3200, 736, 160, 0, 0, 0, 2113, 6371, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2177, 2401, 2657, 10885, 35889, 44405, 50744, 57019, 57051, 40658, 16165, 20422, 12131, 7617, 7553, 5057, 2241, 2145, 2145, 2145, 6371]
and this is the C++ with the code snippet you gave me
QVector(24, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 24, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 99, 74, 8, 49, 33, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 115, 247, 206, 156, 99, 16, 0, 33, 74, 8, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 8, 189, 90, 123, 255, 107, 0, 41, 189, 90, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 165, 33, 66, 255, 231, 49, 0, 140, 107, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 107, 16, 82, 231, 222, 123, 8, 107, 82, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 8, 0, 115, 214, 198, 132, 8, 82, 41, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 16, 16, 16, 16, 8, 16, 132, 173, 99, 0, 33, 8, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 8, 16, 24, 41, 41, 24, 16, 16, 16, 0, 24, 74, 24, 0, 0, 33, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 8, 8, 16, 49, 115, 90, 33, 16, 16, 16, 8, 0, 0, 0, 16, 8, 24, 49, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 8, 8, 16, 49, 90, 66, 33, 16, 8, 16, 8, 0, 33, 148, 198, 181, 90, 41, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 8, 8, 16, 24, 24, 24, 16, 16, 16, 16, 8, 0, 66, 255, 255, 239, 189, 49, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 8, 8, 16, 16, 16, 16, 16, 16, 16, 8, 0, 0, 74, 255, 255, 231, 198, 74, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 8, 8, 16, 8, 8, 16, 8, 8, 0, 8, 0, 99, 255, 239, 214, 181, 82, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 123, 231, 206, 189, 148, 57, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 115, 173, 173, 148, 107, 24, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 0, 0, 0, 33, 123, 148, 123, 107, 49, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 82, 115, 99, 90, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 66, 90, 82, 57, 33, 16, 33, 41, 16, 8, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 24, 49, 74, 66, 49, 57, 8, 0, 0, 8, 57, 49, 33, 16, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 24, 16, 16, 41, 57, 49, 24, 49, 8, 66, 189, 123, 82, 8, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 33, 82, 222, 99, 33, 57, 57, 255, 239, 132, 90, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 16, 66, 214, 255, 222, 33, 41, 24, 140, 222, 156, 115, 8, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 181, 239, 247, 255, 181, 24, 16, 24, 74, 90, 66, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 123, 198, 214, 231, 239, 255, 90, 16, 16, 0, 8, 0, 0, 0, 0, 0, 8, 24, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 41, 140, 173, 198, 222, 222, 156, 57, 74, 41, 24, 24, 16, 8, 8, 8, 8, 24)
i loaded the same picture! why are they different?
-
@Kris-Revi
I'm sure that what you have is a RGB value array, not R,G,B arrays. :)
So you need the iterating way.
But this way you need to know the detailed format and decide the byte size of every pixel first.
For example, a RGB565 image need 16bits for every pixel, so we should usequint16
type to read:QVector<quint16> RGB565; RGB565.reserve(img.width() * img.height()); for(int y = 0; y < img.height(); y++) { const quint16 *line = reinterpret_cast<const quint16*>(img.constScanLine(y)); for(int x = 0; x < img.width(); x++) RGB565 << *(line++); }
If the image is a RGB32 format image, then the type should be changed to
quint32
.
If it is RGB24, then it will be more complicated... -
@Bonnie said in QImage converting to RGB and saving new image!:
QVector<quint16> RGB565;
RGB565.reserve(img.width() * img.height());
for(int y = 0; y < img.height(); y++) {
const quint16 line = reinterpret_cast<const quint16>(img.constScanLine(y));
for(int x = 0; x < img.width(); x++)
RGB565 << *(line++);
}ty for that one m8 :) so just to clarify
every image that comes in gets copied and made into 16bit (5-6-5) so it will ALWAYS be 16bit :)
// ================================================= //
FINAL AND WORKING CODE FOR EVERYONE WHO IS INTERESSTED
// ================================================= //void MainWindow::imageHandler(QImage *img) { QImage img2{img->size(), QImage::Format_RGB16}; // The image is stored using a 16-bit RGB format (5-6-5). img2.fill(QColor(Qt::black).rgb()); // Fill the new image with a black background (needs to be filled to get the correct color data) QPainter painter(&img2); // Prepare new image for painting painter.drawImage(0, 0, *img); // Paint the original image onto the new image img2.save("./MatrixImages/test.jpg"); // Save that fucker and lets move on // Get the color 16bit (5-6-5) color data and put it in a QVector and prepare for sending to ESP32 QVector<quint16> RGB565; RGB565.reserve(img2.width() * img2.height()); for(int y = 0; y < img2.height(); y++) { const quint16 *line = reinterpret_cast<const quint16*>(img2.constScanLine(y)); for(int x = 0; x < img2.width(); x++) RGB565 << *(line++); } qDebug() << "[IMAGEHANDLER][INFO] Converting Complete"; }