A problem i have with palettes i need help with!
-
So i've made a Qt App that connects to my ESP32 via Socket to controll some WS2812B led strips
for many months (just to get it working) i've hard coded each palette inn on the ESP32 like this
DEFINE_GRADIENT_PALETTE( Sunset_Real_gp ) // Size: 28 bytes of program space. { 0, 120, 0, 0, 22, 179, 22, 0, 51, 255,104, 0, 85, 167, 22, 18, 135, 100, 0, 103, 198, 16, 0, 130, 255, 0, 0, 160 };
then on the Qt side i just add
pushButton
and some css to style the button with a picture of the palette
when that button was pressed i just send over a
int
like"selectedPalette": "1"
but this is not how i wanted the system! so i've done some modifications to the Qt App where i scan the
image/palettes
folder for.png
files and then generate a button for each and connect signals to slotsthe problem im having here / what i wanted to ask for help with is, is it possible in Qt to "load" that image and generate code like this? (hope that was clear enough)
{ 0, 120, 0, 0, 22, 179, 22, 0, 51, 255,104, 0, 85, 167, 22, 18, 135, 100, 0, 103, 198, 16, 0, 130, 255, 0, 0, 160 };
so that i can click a palette button then Qt generates that code and sends that over to ESP32 allowing me to just add palette images to folder and it just works!
if not is there any other way i could do this?
-
Hi,
If I understand you correctly, you want to generate a list of numbers from your image based on the pixel ARGB values, correct ?
-
Hi,
If I understand you correctly, you want to generate a list of numbers from your image based on the pixel ARGB values, correct ?
-
Hi
a (slow) way isfor (int row = 0; row < img.height(); row++) { for (int col = 0; col < img.width(); col++) { QRgb pixColor = img.pixel(row, col); qDebug() << "red" << qRed(pixColor) << endl << "green" << qGreen(pixColor) << endl << "blue" << qBlue(pixColor); } }
read also about constBits() or constScanLine()
but for a small image the speed is not so critical.However, how can we detect the POS ?
will the color change so much, we can use that to know it must be a POS there ? -
Hi
a (slow) way isfor (int row = 0; row < img.height(); row++) { for (int col = 0; col < img.width(); col++) { QRgb pixColor = img.pixel(row, col); qDebug() << "red" << qRed(pixColor) << endl << "green" << qGreen(pixColor) << endl << "blue" << qBlue(pixColor); } }
read also about constBits() or constScanLine()
but for a small image the speed is not so critical.However, how can we detect the POS ?
will the color change so much, we can use that to know it must be a POS there ? -
@Kris-Revi
These images that defines a gradiant.
Are those user defined or will you make them ? -
I don't think this is possible without the use of an indexed image (QImage::Format_Indexed8?). Given you're using this format, I think it would be a matter of calling the QImage::color() method for every color in your image (QImage::colorCount()). Then you can process that however you like.
-
So Pos is the end/start of the next gradient ?
-
Hi
You should be able to use such table with
https://doc.qt.io/qt-5/qgradient.html -
Hi
You should be able to use such table with
https://doc.qt.io/qt-5/qgradient.html -
@mrjj never worked with QPainter or QLinearGradient befor! but i'll give it a go i guess
Well fast example might help you get started.
// converts range between 0-255 to range 0 - 1 as gradient uses float mapPos(int x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } // data type to hold the info as list of ints is clumsy struct gradPosDef { int pos; int r; int g; int b; }; // define a test gradient. this you would load from a file. QList<gradPosDef> gradValues{ {0, 120, 0, 0}, {22, 179, 22, 0}, {51, 255, 104, 0}, {85, 167, 22, 18}, {135, 100, 0, 103}, {198, 16, 0, 130}, {255, 0, 0, 160} };
// creates pixmap and returns it QPixmap MainWindow::makeGradient() { // size of gradient / pixmap const int gw = 255; const int gh = 100; // define it- make it point straight from left to right QLinearGradient gradient(0, 0, gw, 0); // loop over the test gradient values for (int cc = 0; cc < gradValues.size(); cc++) { auto cur = gradValues.at(cc); // convert to new scale. you could directly use 0- 1 instead of 0-255 to avoid float scaledVal = mapPos(cur.pos, 0, 255, 0, 1); // write it out to see if we get sane values qDebug() << "org: " << cur.pos << " - " << scaledVal; // make color QColor col(cur.r, cur.g, cur.b); // set gradient point gradient.setColorAt(scaledVal, col); }; // allocate a pix map QPixmap pix(gw, gh); //assign painter to it so we can paint the gradiant QPainter p(&pix); // assign gradient to a brush. this way we can paint it QBrush grad(gradient); // fill pixmap with gradiant p.fillRect(pix.rect(), gradient); return pix; }
to use it you can do
auto pix = makeGradient(); pix.save("e:/test.png"); ui->label->setPixmap(pix);
and get
Not perfect but demonstrate one way to do it.
-
Well fast example might help you get started.
// converts range between 0-255 to range 0 - 1 as gradient uses float mapPos(int x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } // data type to hold the info as list of ints is clumsy struct gradPosDef { int pos; int r; int g; int b; }; // define a test gradient. this you would load from a file. QList<gradPosDef> gradValues{ {0, 120, 0, 0}, {22, 179, 22, 0}, {51, 255, 104, 0}, {85, 167, 22, 18}, {135, 100, 0, 103}, {198, 16, 0, 130}, {255, 0, 0, 160} };
// creates pixmap and returns it QPixmap MainWindow::makeGradient() { // size of gradient / pixmap const int gw = 255; const int gh = 100; // define it- make it point straight from left to right QLinearGradient gradient(0, 0, gw, 0); // loop over the test gradient values for (int cc = 0; cc < gradValues.size(); cc++) { auto cur = gradValues.at(cc); // convert to new scale. you could directly use 0- 1 instead of 0-255 to avoid float scaledVal = mapPos(cur.pos, 0, 255, 0, 1); // write it out to see if we get sane values qDebug() << "org: " << cur.pos << " - " << scaledVal; // make color QColor col(cur.r, cur.g, cur.b); // set gradient point gradient.setColorAt(scaledVal, col); }; // allocate a pix map QPixmap pix(gw, gh); //assign painter to it so we can paint the gradiant QPainter p(&pix); // assign gradient to a brush. this way we can paint it QBrush grad(gradient); // fill pixmap with gradiant p.fillRect(pix.rect(), gradient); return pix; }
to use it you can do
auto pix = makeGradient(); pix.save("e:/test.png"); ui->label->setPixmap(pix);
and get
Not perfect but demonstrate one way to do it.
-
@mrjj ty for that bit of code m8! :) <3
question! is this the way togo when you want to save the file to the App folder?
if ( pix.save(QDir::currentPath() + "/test.png") )
@Kris-Revi You should not write into app folder as usually normal users have no write access there!
There are better options for saving data, see https://doc.qt.io/qt-5/qstandardpaths.html -
@Kris-Revi You should not write into app folder as usually normal users have no write access there!
There are better options for saving data, see https://doc.qt.io/qt-5/qstandardpaths.html -
@Kris-Revi Did you actually read the link I gave you?
There are several locations depending on type of files:- QStandardPaths::DocumentsLocation - any documents
- QStandardPaths::PicturesLocation - for pictures (this is probably what you want)
- ...
-
You can either use QFileDialog so your users can choose where to store them or use one of the suitable proposition of QStandardPaths like
QStandardPaths::DocumentsLocation
-
@Kris-Revi Did you actually read the link I gave you?
There are several locations depending on type of files:- QStandardPaths::DocumentsLocation - any documents
- QStandardPaths::PicturesLocation - for pictures (this is probably what you want)
- ...
-
@jsulm ofcourse i read it! i was asking where do people usualy put it :) im not THAT lazy! :)
@Kris-Revi Sorry if I was rude!
Where to put the data depends on data types. It looks like you want to store a picture, so QStandardPaths::PicturesLocation would be the proper location. Or you ask the user where to store as @SGaist suggested.