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;

}
_______________________________________________
Interest mailing list
[email protected]
http://lists.qt-project.org/mailman/listinfo/interest

Reply via email to