X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fcolortools.cpp;h=7f513a701e2dd5ae211bdcae2ca098753878c87a;hb=c3302003093710ee247ad84c0fe2ef3c579d417f;hp=70772cb5578df173c04d59a5df129ed584444bea;hpb=c471a29fcef185bffaff48c4185588f4a8416ca4;p=kdenlive diff --git a/src/colortools.cpp b/src/colortools.cpp index 70772cb5..7f513a70 100644 --- a/src/colortools.cpp +++ b/src/colortools.cpp @@ -10,6 +10,12 @@ #include #include "colortools.h" +#include + +//#define DEBUG_CT +#ifdef DEBUG_CT +#include +#endif ColorTools::ColorTools() { @@ -24,7 +30,9 @@ QImage ColorTools::yuvColorWheel(const QSize &size, const unsigned char &Y, cons qCritical("ERROR: Size of the color wheel must not be 0!"); return wheel; } - wheel.fill(qRgba(0,0,0,0)); + if (circleOnly) { + wheel.fill(qRgba(0,0,0,0)); + } double dr, dg, db, du, dv, dmax; double ru, rv, rr; @@ -86,7 +94,7 @@ QImage ColorTools::yuvColorWheel(const QSize &size, const unsigned char &Y, cons } } - emit signalWheelCalculationFinished(); + emit signalYuvWheelCalculationFinished(); return wheel; } @@ -132,8 +140,10 @@ QImage ColorTools::yuvVerticalPlane(const QSize &size, const float &angle, const } -QImage ColorTools::rgbCurvePlane(const QSize &size, const ColorsRGB &color) +QImage ColorTools::rgbCurvePlane(const QSize &size, const ColorTools::ColorsRGB &color, float scaling, const QRgb &background) { + Q_ASSERT(scaling > 0 && scaling <= 1); + QImage plane(size, QImage::Format_ARGB32); if (size.width() == 0 || size.height() == 0) { qCritical("ERROR: Size of the color plane must not be 0!"); @@ -144,24 +154,212 @@ QImage ColorTools::rgbCurvePlane(const QSize &size, const ColorsRGB &color) const int h = size.height(); double dcol, dval; + double dx, dy; for (int x = 0; x < w; x++) { - dval = (double)255*x/w; + dval = (double)255*x/(w-1); for (int y = 0; y < h; y++) { - dcol = (double)255*y/h; + dy = (double)y/(h-1); + dx = (double)x/(w-1); + + if (1-scaling < 0.0001) { + dcol = (double)255*dy; + } else { + dcol = (double)255 * (dy - (dy-dx)*(1-scaling)); + } if (color == ColorTools::COL_R) { plane.setPixel(x, (h-y-1), qRgb(dcol, dval, dval)); } else if (color == ColorTools::COL_G) { plane.setPixel(x, (h-y-1), qRgb(dval, dcol, dval)); - } else { + } else if (color == ColorTools::COL_B){ plane.setPixel(x, (h-y-1), qRgb(dval, dval, dcol)); + } else if (color == ColorTools::COL_A) { + plane.setPixel(x, (h-y-1), qRgb(dcol / 255. * qRed(background), dcol / 255. * qGreen(background), dcol / 255. * qBlue(background))); + } else { + plane.setPixel(x, (h-y-1), qRgb(dcol, dcol, dcol)); + } + + } + } + return plane; +} + +QImage ColorTools::yPbPrColorWheel(const QSize &size, const unsigned char &Y, const float &scaling, const bool &circleOnly) +{ + + QImage wheel(size, QImage::Format_ARGB32); + if (size.width() == 0 || size.height() == 0) { + qCritical("ERROR: Size of the color wheel must not be 0!"); + return wheel; + } + if (circleOnly) { + wheel.fill(qRgba(0,0,0,0)); + } + + double dr, dg, db, dpB, dpR; + double rB, rR, rr; + const int w = size.width(); + const int h = size.height(); + const float w2 = (float)w/2; + const float h2 = (float)h/2; + + for (int b = 0; b < w; b++) { + // Transform pB from {0,...,w} to [-0.5,0.5] + dpB = (double) b/(w-1) - .5; + dpB = scaling*dpB; + + for (int r = 0; r < h; r++) { + dpR = (double) r/(h-1) - .5; + dpR = scaling*dpR; + + if (circleOnly) { + // see yuvColorWheel + rB = b - w2; + rR = r - h2; + rr = rB*rB/(w2*w2) + rR*rR/(h2*h2); + if (rr > 1) { + continue; + } + } + + // Calculate the RGB values from YPbPr + dr = Y + 357.5*dpR; + dg = Y - 87.75*dpB - 182.1*dpR; + db = Y + 451.86*dpB; + + // Avoid overflows (which would generate intersting patterns). + // Note that not all possible (y,u,v) values with u,v \in [-1,1] + // have a correct RGB representation, therefore some RGB values + // may exceed {0,...,255}. + if (dr < 0) dr = 0; + if (dg < 0) dg = 0; + if (db < 0) db = 0; + if (dr > 255) dr = 255; + if (dg > 255) dg = 255; + if (db > 255) db = 255; + + wheel.setPixel(b, (h-r-1), qRgba(dr, dg, db, 255)); + } + } + + return wheel; +} + +QImage ColorTools::hsvHueShiftPlane(const QSize &size, const uint &S, const uint &V, const int &MIN, const int &MAX) +{ + Q_ASSERT(size.width() > 0); + Q_ASSERT(size.height() > 0); + Q_ASSERT(MAX > MIN); + + QImage plane(size, QImage::Format_ARGB32); + +#ifdef DEBUG_CT + qDebug() << "Requested: Saturation " << S << ", Value " << V; + QColor colTest(-1, 256, 257); + qDebug() << "-1 mapped to " << colTest.red() << ", 256 to " << colTest.green() << ", 257 to " << colTest.blue(); +#endif + + QColor col(0, 0, 0); + + const int hueValues = MAX-MIN; + + float hue, huediff; + int newhue; + for (int x = 0; x < size.width(); x++) { + hue = x/(size.width() - 1.0) * 359; + for (int y = 0; y < size.height(); y++) { + huediff = (1.0f - y/(size.height() - 1.0)) * hueValues + MIN; +// qDebug() << "hue: " << hue << ", huediff: " << huediff; + + newhue = hue + huediff + 360; // Avoid negative numbers. Rest (>360) will be mapped correctly. + + col.setHsv(newhue, S, V); + plane.setPixel(x, y, col.rgba()); + + } + } + + return plane; + +} + +QImage ColorTools::hsvCurvePlane(const QSize &size, const QColor &baseColor, + const ComponentsHSV &xVariant, const ComponentsHSV &yVariant, const bool &shear, const float offsetY) +{ + Q_ASSERT(size.width() > 0); + Q_ASSERT(size.height() > 0); + + /*int xMax, yMax; + + switch(xVariant) { + case COM_H: + xMax = 360; + break; + case COM_S: + case COM_V: + xMax = 256; + break; + } + + switch (yVariant) { + case COM_H: + yMax = 360; + break; + case COM_S: + case COM_V: + yMax = 256; + break; + }*/ + + + QImage plane(size, QImage::Format_ARGB32); + + QColor col(0, 0, 0); + + float hue, sat, val; + hue = baseColor.hueF(); + sat = baseColor.saturationF(); + val = baseColor.valueF(); + + for (int x = 0; x < size.width(); x++) { + switch (xVariant) { + case COM_H: + hue = x / (size.width()-1.0); + break; + case COM_S: + sat = x / (size.width()-1.0); + break; + case COM_V: + val = x / (size.width()-1.0); + break; + } + for (int y = 0; y < size.height(); y++) { + switch (yVariant) { + case COM_H: + hue = 1.0 - y / (size.height()-1.0); + break; + case COM_S: + sat = 1.0 - y / (size.height()-1.0); + break; + case COM_V: + val = 1.0 - y / (size.height()-1.0); + break; } + col.setHsvF(hue, sat, val); + + if (!shear) { + plane.setPixel(x, y, col.rgba()); + } else { + plane.setPixel(x, int(2*size.height() + y - x*size.width()/size.height() - offsetY * size.height()) % size.height(), col.rgba()); + } } } + return plane; + } @@ -171,3 +369,5 @@ QImage ColorTools::rgbCurvePlane(const QSize &size, const ColorsRGB &color) + +#include "colortools.moc"