Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

cannot read image that was achieved from QAbstractVideoSurface implemented class



  • I wrote the following code and want to write it into my filesystem of android (the write operation was finished correctly) after writing I tried to open that file but I couldn't open it why?

    videosurface.cpp

    bool VideoSurfacer::present ( const QVideoFrame & f )
    {
    	QVideoFrame frame ( f );
    	if ( frame.isValid ( ) && frame.map ( QAbstractVideoBuffer::MapMode::ReadOnly ) )
    		{
    						i++;
    			QString path = QStandardPaths::writableLocation ( QStandardPaths::GenericDataLocation ) + "/download/" + QString::number ( i ) + ".jpg";
    			// however you can use QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat()) but sometimes it returns invalid which make our image null
    			QImage img ( frame.bits ( ), frame.width ( ), frame.height ( ), frame.bytesPerLine ( ), QImage::Format_Grayscale8 );
                            img.isNull();//false
    			img.convertToFormat ( QImage::Format_RGB32 ).save ( path, "JPG" );
    			frame.unmap ( );
    
    		}
    	return true;
    }
    
    bool VideoSurfacer::isFormatSupported ( const QVideoSurfaceFormat & format ) const
    {
    	bool size				 = format.frameSize ( ) == QSize ( 800, 600 );
    	bool valid			 = format.isValid ( );
    	bool pixelFormat = supportedPixelFormats ( ).contains ( format.pixelFormat ( ) );
    	return valid && pixelFormat && size;
    }
    
    QVideoSurfaceFormat VideoSurfacer::nearestFormat ( const QVideoSurfaceFormat & format ) const
    {
    	QVideoSurfaceFormat newFormat ( format );
    	newFormat.setFrameRate ( 30 );
    	newFormat.setMirrored ( true );
    	newFormat.setFrameSize ( 800, 600 );
    	return newFormat;
    }
    
    QList<QVideoFrame::PixelFormat> VideoSurfacer::supportedPixelFormats ( QAbstractVideoBuffer::HandleType type ) const
    {
    	if ( type == QAbstractVideoBuffer::NoHandle )
    		{
    			// however you set the pixel format something other than first item of this list but the present method retrieve the first item of this list pixelformat but other things like view size and frame rate affect the retrieved frames
    			return QList<QVideoFrame::PixelFormat> ( ) << QVideoFrame::Format_NV21;
    		}
    	else
    		{
    			return QList<QVideoFrame::PixelFormat> ( );
    		}
    }
    

    main.cpp

    	QAbstractVideoSurface * surfacer = new VideoSurfacer;
    
    	QCamera cam ( QCameraInfo::availableCameras ( ).at ( 1 ) );
    	cam.setCaptureMode ( QCamera::CaptureMode::CaptureViewfinder );
    	cam.setViewfinder ( surfacer );
    
    	QCameraViewfinderSettings settings = cam.viewfinderSettings ( );
    	settings.setMaximumFrameRate ( 30 );
    	settings.setMinimumFrameRate ( 30 );
    	settings.setResolution ( 800, 600 );
    	settings.setPixelFormat ( QVideoFrame::PixelFormat::Format_NV21 );
    	cam.setViewfinderSettings ( settings );
    
    	cam.start ( );
    }
    

  • Lifetime Qt Champion

    No, NV21 is one YUV color space format.


  • Lifetime Qt Champion

    Hi,

    Did you check that the image is valid both before and after the conversion ?



  • both of those (before and after conversion) returns false of method isNull (code is edited please reread present method)



  • I find the problem I convert that image to rgb32 and save it however android device cannot open it but computer with imv command can open it and show my image correctly

    and that is solved too I just move the pictures and reopen them in that time images are open without any problem only show gray style

    I've tried many other formats many of those make my image invalid (isnull() = true) some other like Mono,MonoLSB,Alpha8 shows an incorrect image and some other like Indexed8 returns a same result (gray style) by grayscaled format

    How can I have my nv21 video frames colourful


  • Lifetime Qt Champion

    You likely have to do the conversion NV21 -> RGB yourself.



  • I want color in my image if nv21 is gray how can I do that



  • I think I understand you. You mean NV21 pixel format is gray and my codes don't have any problem.
    So which pixel format I have to use that is supported for all android devices. I tried entire of them no one of those call present method other than nv21


  • Lifetime Qt Champion

    No, NV21 is one YUV color space format.


Log in to reply