|
| 1 | +#include <iostream> |
| 2 | +#include <QApplication> |
| 3 | +#include <QImage> |
| 4 | +#include <QLabel> |
| 5 | + |
| 6 | +// http://stackoverflow.com/a/25878225/176769 |
| 7 | +// http://mycodelog.com/2010/05/16/interpolation/ |
| 8 | +#if 0 |
| 9 | +QImage smooth_color_transition(const QImage& input, const QVector<QColor>& color_vec) |
| 10 | +{ |
| 11 | + QImage output(input.size(), input.format()); |
| 12 | + |
| 13 | + QColor color_src = color_vec.at(0); |
| 14 | + unsigned int r1 = color_src.red(); |
| 15 | + unsigned int g1 = color_src.green(); |
| 16 | + unsigned int b1 = color_src.blue(); |
| 17 | + |
| 18 | + QColor color_dst = color_vec.at(1); |
| 19 | + unsigned int r2 = color_dst.red(); |
| 20 | + unsigned int g2 = color_dst.green(); |
| 21 | + unsigned int b2 = color_dst.blue(); |
| 22 | + |
| 23 | + for (int x = 0; x < input.width(); x++) |
| 24 | + { |
| 25 | + for (int y = 0; y < input.height(); y++) |
| 26 | + { |
| 27 | + QRgb pixel = input.pixel(x, y); |
| 28 | + int gray = (qRed(pixel) + qGreen(pixel) + qBlue(pixel)) / 3; |
| 29 | + float p = gray / 255.0; |
| 30 | + |
| 31 | + //Resultant Color = RGB(A*(1-P)+X*P, B*(1-P)+Y*P, C*(1-P)+Z*P) |
| 32 | + int r = (int) r1 * (1-p) + r2 * p; |
| 33 | + int g = (int) g1 * (1-p) + g2 * p; |
| 34 | + int b = (int) b1 * (1-p) + b2 * p; |
| 35 | + output.setPixel(x, y, qRgb(r, g, b)); |
| 36 | + } |
| 37 | + } |
| 38 | + |
| 39 | + return output; |
| 40 | +} |
| 41 | +#endif |
| 42 | + |
| 43 | + |
| 44 | +QImage smooth_color_transition(const QImage& input, const QVector<QColor>& color_vec) |
| 45 | +{ |
| 46 | + if (color_vec.size() < 2) |
| 47 | + return QImage(); |
| 48 | + |
| 49 | + QImage output(input.size(), input.format()); |
| 50 | + |
| 51 | + int num_colors = color_vec.size(); |
| 52 | + std::cout << "Num colors:" << color_vec.size() << std::endl; |
| 53 | + |
| 54 | + int color_width = 256 / (color_vec.size()-1); |
| 55 | + std::cout << "Color width:" << color_width << std::endl; |
| 56 | + |
| 57 | + QVector<QColor> pallete; |
| 58 | + for (int c = 1; c < num_colors; c++) |
| 59 | + { |
| 60 | + QColor color_src = color_vec.at(c-1); |
| 61 | + unsigned int r1 = color_src.red(); |
| 62 | + unsigned int g1 = color_src.green(); |
| 63 | + unsigned int b1 = color_src.blue(); |
| 64 | + |
| 65 | + QColor color_dst = color_vec.at(c); |
| 66 | + unsigned int r2 = color_dst.red(); |
| 67 | + unsigned int g2 = color_dst.green(); |
| 68 | + unsigned int b2 = color_dst.blue(); |
| 69 | + |
| 70 | + for (int i = 0; i < color_width; i++) |
| 71 | + { |
| 72 | + float p = i / (float)color_width; // percentage |
| 73 | + |
| 74 | + //Resultant Color = RGB(A*(1-P)+X*P, B*(1-P)+Y*P, C*(1-P)+Z*P) |
| 75 | + |
| 76 | + int r = (int) r1 * (1-p) + r2 * p; |
| 77 | + int g = (int) g1 * (1-p) + g2 * p; |
| 78 | + int b = (int) b1 * (1-p) + b2 * p; |
| 79 | + pallete.push_back(qRgb(r, g, b)); |
| 80 | + } |
| 81 | + } |
| 82 | + |
| 83 | + // Color width is a REAL number, therefore pallete might end up a little bit short |
| 84 | + for (int i = pallete.size(); i < 256; i++) |
| 85 | + pallete.push_back(color_vec[color_vec.size()-1].rgb()); |
| 86 | + |
| 87 | + std::cout << "Pallete size:" << pallete.size() << std::endl; |
| 88 | + |
| 89 | + for (int x = 0; x < input.width(); x++) |
| 90 | + { |
| 91 | + for (int y = 0; y < input.height(); y++) |
| 92 | + { |
| 93 | + QRgb pixel = input.pixel(x, y); |
| 94 | + int gray = (qRed(pixel) + qGreen(pixel) + qBlue(pixel)) / 3; |
| 95 | + output.setPixel(x, y, pallete[gray].rgb()); |
| 96 | + } |
| 97 | + } |
| 98 | + |
| 99 | + return output; |
| 100 | +} |
| 101 | + |
| 102 | + |
| 103 | +int main(int argc, char* argv[]) |
| 104 | +{ |
| 105 | + QApplication app(argc, argv); |
| 106 | + |
| 107 | + QImage input("/Users/karlphillip/workspace/GraphicsProgramming/qtSmoothColorTransition/heightmap.jpg"); |
| 108 | + if (input.isNull()) |
| 109 | + return -1; |
| 110 | + |
| 111 | + QLabel input_label; |
| 112 | + input_label.setPixmap(QPixmap::fromImage(input)); |
| 113 | + input_label.resize(input.width(), input.height()); |
| 114 | + input_label.show(); |
| 115 | + |
| 116 | + QVector<QColor> colors; |
| 117 | + colors.push_back(QColor(0, 120, 200)); // dark blue |
| 118 | + colors.push_back(QColor(120, 220, 255)); // cyan |
| 119 | + colors.push_back(QColor(71, 141, 104)); // dark green |
| 120 | + colors.push_back(QColor(106, 168, 107)); // medium green |
| 121 | + colors.push_back(QColor(141, 173, 132)); // light green |
| 122 | + colors.push_back(QColor(166, 191, 151)); // super light green |
| 123 | + colors.push_back(QColor(217, 233, 188)); // sand yellow |
| 124 | + colors.push_back(QColor(185, 140, 90)); // light orange |
| 125 | + colors.push_back(QColor(162, 90, 34)); // light red |
| 126 | + colors.push_back(QColor(144, 61, 45)); // dark red |
| 127 | + colors.push_back(QColor(151, 68, 64)); // super dark red |
| 128 | + colors.push_back(QColor(156, 146, 170)); // purple-red |
| 129 | + colors.push_back(QColor(170, 170, 210)); // purple-white |
| 130 | + colors.push_back(QColor(240, 247, 243)); // white |
| 131 | + |
| 132 | + QImage output = smooth_color_transition(input, colors); |
| 133 | + |
| 134 | + QLabel output_label; |
| 135 | + output_label.setPixmap(QPixmap::fromImage(output)); |
| 136 | + output_label.resize(output.width(), output.height()); |
| 137 | + output_label.show(); |
| 138 | + |
| 139 | + output.save("colored.jpg"); |
| 140 | + |
| 141 | + return app.exec(); |
| 142 | +} |
0 commit comments