@@ -533,6 +533,36 @@ QImage LibCameraWorker::convertBufferToImage(
533533 image.setPixel (x + 1 , y, qRgb (r1, g1, b1));
534534 }
535535 }
536+ } else if (cfg.pixelFormat == libcamera::formats::YUV420) {
537+ // YUV420 planar format (I420)
538+ unsigned int width = cfg.size .width ;
539+ unsigned int height = cfg.size .height ;
540+ image = QImage (width, height, QImage::Format_RGB888);
541+
542+ const uint8_t *src = static_cast <const uint8_t *>(memory);
543+ const uint8_t *yPlane = src;
544+ const uint8_t *uPlane = src + width * height;
545+ const uint8_t *vPlane = uPlane + (width * height / 4 );
546+
547+ for (unsigned int y = 0 ; y < height; y++) {
548+ for (unsigned int x = 0 ; x < width; x++) {
549+ int yVal = yPlane[y * width + x];
550+ int uVal = uPlane[(y / 2 ) * (width / 2 ) + (x / 2 )];
551+ int vVal = vPlane[(y / 2 ) * (width / 2 ) + (x / 2 )];
552+
553+ auto clamp = [](int val) { return std::max (0 , std::min (255 , val)); };
554+
555+ int c = yVal - 16 ;
556+ int d = uVal - 128 ;
557+ int e = vVal - 128 ;
558+
559+ int r = clamp ((298 * c + 409 * e + 128 ) >> 8 );
560+ int g = clamp ((298 * c - 100 * d - 208 * e + 128 ) >> 8 );
561+ int b = clamp ((298 * c + 516 * d + 128 ) >> 8 );
562+
563+ image.setPixel (x, y, qRgb (r, g, b));
564+ }
565+ }
536566 } else {
537567 qDebug () << " [ERROR] Unsupported pixel format:"
538568 << QString::fromStdString (cfg.pixelFormat .toString ());
@@ -566,10 +596,14 @@ bool LibCameraWorker::configureCamera(libcamera::StreamRole role) {
566596 mCurrentWidth = cfg.size .width ;
567597 mCurrentHeight = cfg.size .height ;
568598 } else if (role == StreamRole::StillCapture) {
569- cfg.pixelFormat = formats::MJPEG;
599+ // Don't force MJPEG - use the camera's default format for still capture
600+ // Pi cameras typically use YUV420 which we'll convert
601+ // Only set buffer count, keep default format and resolution
570602 cfg.bufferCount = 1 ;
571603 mCurrentWidth = cfg.size .width ;
572604 mCurrentHeight = cfg.size .height ;
605+ qDebug () << " [INFO] Still capture default format:" << QString::fromStdString (cfg.pixelFormat .toString ());
606+ qDebug () << " [INFO] Still capture default size:" << cfg.size .width << " x" << cfg.size .height ;
573607 }
574608
575609 CameraConfiguration::Status status = mConfig ->validate ();
0 commit comments