[Interest] QImage + pixel lambdas

Jason H jhihn at gmx.com
Fri Jun 1 22:13:07 CEST 2018


Incase anyone is wondering:
accumulator ARGB32 6000000 pixels 24/25/26 msec (lamda, scanline)
accumulator ARGB32 6000000 pixels 40/42/44 msec (lambda or no lambda, QImage::pixel)


> Sent: Friday, June 01, 2018 at 9:38 AM
> From: "Jason H" <jhihn at gmx.com>
> To: "interestqt-project.org" <interest at qt-project.org>
> Subject: [Interest] QImage + pixel lambdas
>
> 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
> Interest at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest
> 



More information about the Interest mailing list