[Interest] QImage + pixel lambdas
Jason H
jhihn at gmx.com
Fri Jun 1 15:38:03 CEST 2018
So I'm doing some qimage analysis/manipulation. I think it would be really good if QImage came with a per-pixel function. (Examples below)
I'm tired of writing the x/y for loops. The really neat thing (not in the examples) is using QImage::scanLine(int y) for faster access, and automatically choosing the value of p in the lambda based on bit depth.
Anyone else think this is a good idea?
//Really sorry about this SFINAE
template <typename T, typename std::enable_if<std::is_same<void, decltype(std::declval<T>()(1))>::value, int>::type = 0>
void eachPixel(const QImage &image, T pixelFunc, const QRect &bounds=QRect()) {
QRect imageRect(QRect(0,0, image.width(), image.height()));
QRect region = bounds.isNull() ? imageRect : bounds.intersected(imageRect);
for (int y=region.y(); y<=region.bottom(); y++) {
for (int x=region.x(); x<=region.right(); x++) {
pixelFunc(image.pixel(x,y));
}
}
}
//Really sorry about this SFINAE too.
template <typename T, typename std::enable_if<std::is_same<uint, decltype(std::declval<T>()(1))>::value, int>::type = 0>
QImage eachPixel(const QImage &image, T pixelFunc, const QRect &bounds=QRect()) {
QRect imageRect(QRect(0,0, image.width(), image.height()));
QRect region = bounds.isNull() ? imageRect : bounds.intersected(imageRect);
QImage out(image.size(), image.format());
for (int y=region.y(); y<=region.bottom(); y++) {
for (int x=region.x(); x<=region.right(); x++) {
out.setPixel(x,y, pixelFunc(image.pixel(x,y)));
}
}
return out;
}
void test_pixelFunc() {
QImage image(300,200, QImage::Format_ARGB32);
image.fill(Qt::blue);
QImage out = eachPixel(image, [] (uint p) {
return qRgb(qRed(p), qBlue(p), qGreen(p)); // swap green and blue channels
}, QRect (5,5, 300, 200)); // for a portion of the image
out.save("test_pixelfunc.png");
int accumulator=0;
int min = 255;
int max = 0
eachPixel(image, [&accumulator, &min, &max](uint p) { // This one can be used for statistics,
accumulator +=p; // if you're not making a new image
if (p < min) min = p;
if (p > max) max = p;
}, QRect (5,5, 300, 200));
qDebug() << "accumulator" << accumulator << "min" << min << "max" << max;
}
More information about the Interest
mailing list