Camera Rotation Settings Applied to Photo Display - Code Analysis¶
Summary¶
Camera rotation settings are NOT automatically applied when loading photos via AppletPlayerPhoto or AssetPhotoWidget. The rotation is only applied to camera capture streams and manually in photo viewers.
File Locations & Functions¶
1. AppletPlayerPhoto.cpp - Photo Loading Entry Point¶
File: nolimitgui/src/AppletPlayerPhoto.cpp
Function: bool AppletPlayerPhoto::playMedia( AssetPlaySession& assetPlaySession, bool useExternalPlayer)
bool AppletPlayerPhoto::playMedia( AssetPlaySession& assetPlaySession, bool useExternalPlayer)
{
std::string fullFileName = assetPlaySession.getFileNameAndPath();
QPixmap pixmap;
pixmap.load( fullFileName.c_str() );
if( pixmap.isNull() )
{
close();
return false;
}
if( ui.m_VidWidget->setImageFromFile( fullFileName.c_str() ) )
{
return true;
}
close();
return false;
}
setImageFromFile()
- NO camera rotation applied here
2. AssetPhotoWidget.cpp - Photo Asset Display¶
File: nolimitgui/src/AssetPhotoWidget.cpp
Function: void AssetPhotoWidget::setAssetInfo( AssetBaseInfo& assetInfo )
void AssetPhotoWidget::setAssetInfo( AssetBaseInfo& assetInfo )
{
AssetBaseWidget::setAssetInfo( assetInfo );
this->setSizeHint( QSize( 100, 224 - 16 ) );
ui.m_VidWidget->setImageFromFile( assetInfo.getAssetNameAndPath().c_str() );
// ... rest of function
}
VidWidget::setImageFromFile() with the photo path
- NO camera rotation is applied
3. VidWidget.cpp - Video Display Widget¶
3a. setImageFromFile() Function¶
File: nolimitgui/src/VidWidget.cpp
bool VidWidget::setImageFromFile( QString fileName )
{
bool result = ui.m_VideoScreen->setImageFromFile( fileName );
if( result )
{
m_StillImageFileName = fileName;
m_StillImage.load( fileName );
}
return result;
}
VxLabel::setImageFromFile()
- NO rotation applied
3b. Rotation Control Functions¶
File: nolimitgui/src/VidWidget.cpp
void VidWidget::setVidImageRotation( int imageRotation )
{
ui.m_VideoScreen->setVidImageRotation( imageRotation );
}
3c. Manual Photo Rotation Handler¶
File: nolimitgui/src/VidWidget.cpp
void VidWidget::slotFeedRotateButtonClicked( void )
{
if( eVideoUiModePhoto == m_VideoUiMode )
{
int imageRotation = ui.m_VideoScreen->getVidImageRotation();
imageRotation += 90;
if( imageRotation >= 360 )
{
imageRotation = 0;
}
setVidImageRotation( imageRotation );
QImage curImage = ui.m_VideoScreen->getLastVideoImage();
if( curImage.isNull() )
{
curImage = m_StillImage;
}
if( curImage.isNull() && !m_StillImageFileName.isEmpty() )
{
curImage.load( m_StillImageFileName );
}
if( !curImage.isNull() )
{
ui.m_VideoScreen->playVideoFrame( curImage );
}
m_MyApp.toGuiUserMessage( "Photo Rotation %d", imageRotation );
return;
}
// ... Video feed rotation code
}
m_VidImageRotation and calls playVideoFrame() to apply rotation
3d. Camera Rotation Button Handler¶
File: nolimitgui/src/VidWidget.cpp
void VidWidget::slotCamRotateButtonClicked( void )
{
std::string camId = m_AppSettings.getCamSourceId();
int camRotation = m_AppSettings.getCamRotation( camId );
camRotation += 90;
if( camRotation >= 360 )
{
camRotation = 0;
}
m_AppSettings.setCamRotation( camId, camRotation );
m_MyApp.setCamCaptureRotation( camRotation );
m_MyApp.toGuiUserMessage( "My Cam Rotation %d", camRotation );
emit signalCamRotationChanged( camRotation );
}
AppSettings
- Sets m_CamCaptureRotation in AppCommon
- Does NOT apply to existing photos
4. VxLabel.cpp - Actual Image Rendering¶
4a. Load Image from File¶
File: nolimitgui/src/VxLabel.cpp
bool VxLabel::setImageFromFile( QString fileName )
{
m_ImageFileName = fileName;
return loadImageFromFile( m_ImageFileName );
}
bool VxLabel::loadImageFromFile( QString fileName )
{
QImage picBitmap;
if( picBitmap.load( fileName ) && !picBitmap.isNull() )
{
playMotionVideoFrame( picBitmap, 0 );
return true;
}
else
{
LogMsg( LOG_DEBUG, "ERROR VxLabel::loadImageFromFile failed %s", fileName.toUtf8().constData() );
return false;
}
}
playMotionVideoFrame() with rotation 0
4b. Motion Frame Playing (With Rotation)¶
File: nolimitgui/src/VxLabel.cpp
void VxLabel::playMotionVideoFrame( QImage& vidFrame, int motion0To100000 )
{
playRotatedVideoFrame( vidFrame, m_VidImageRotation );
}
void VxLabel::playVideoFrame( QImage& vidFrame )
{
playRotatedVideoFrame( vidFrame, m_VidImageRotation );
}
m_VidImageRotation member variable (set via setVidImageRotation())
4c. Rotated Frame Display¶
File: nolimitgui/src/VxLabel.cpp
void VxLabel::playRotatedVideoFrame( QImage& vidFrame, int iRotate )
{
if( !vidFrame.isNull() && isVisible() )
{
m_PreResizeImage = vidFrame; // for camera snapshot
QSize screenSize( this->width(), this->height() );
QImage resizedPicmap = m_PreResizeImage.scaled( screenSize, Qt::KeepAspectRatio );
if( iRotate )
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QTransform rm;
#else
QMatrix rm;
#endif
rm.rotate( iRotate );
QPixmap pixmap = QPixmap::fromImage( resizedPicmap ).transformed( rm );
if( !pixmap.isNull() )
{
setPixmap( pixmap );
update();
}
else
{
LogMsg( LOG_DEBUG, " VxLabel::slotPlayVideoFrame NULL pixmap" );
}
}
else
{
QPixmap pixmap = QPixmap::fromImage( resizedPicmap );
if( !pixmap.isNull() )
{
setPixmap( pixmap );
update();
}
else
{
LogMsg( LOG_DEBUG, " VxLabel::slotPlayVideoFrame NULL pixmap" );
}
}
}
else if( vidFrame.isNull() )
{
LogMsg( LOG_ERROR, " VxLabel::slotPlayVideoFrame NULL picBitmap" );
}
}
QTransform::rotate() or QMatrix::rotate()
- Only applies rotation if iRotate != 0
- Rotation value comes from m_VidImageRotation, NOT from camera settings
5. InputPhotoWidget.cpp - Camera Photo Capture¶
File: nolimitgui/src/InputPhotoWidget.cpp
Function: void InputPhotoWidget::slotSnapShotButtonClicked( void )
void InputPhotoWidget::slotSnapShotButtonClicked( void )
{
m_PicImage = ui.m_VidWidget->getVideoScreen()->getLastVideoImage();
if( m_PicImage.isNull() )
{
QMessageBox::warning(this, QObject::tr("Photo Snapshot Error"), QObject::tr("Photo Unavailable" ) );
}
else
{
// ... saves image to file
if( false == m_PicImage.save( m_FileName.c_str() ) )
{
// ... error handling
}
}
}
File: nolimitgui/src/InputPhotoWidget.cpp
Function: void InputPhotoWidget::slotRotateCamButtonClicked( void )
void InputPhotoWidget::slotRotateCamButtonClicked( void )
{
std::string camId = m_MyApp.getAppSettings().getCamSourceId();
int camRotation = m_MyApp.getAppSettings().getCamRotation( camId );
camRotation += 90;
if( camRotation >= 360 )
{
camRotation = 0;
}
m_MyApp.getAppSettings().setCamRotation( camId, camRotation );
m_MyApp.setCamCaptureRotation( camRotation );
}
6. AppCommon.h - Camera Rotation Member¶
File: nolimitgui/src/AppCommon.h
void setCamCaptureRotation( uint32_t rot ) { m_CamCaptureRotation = rot; }
int getCamCaptureRotation( void ) { return m_CamCaptureRotation; }
File: nolimitgui/src/AppCommon.h
uint32_t m_CamCaptureRotation;
File: nolimitgui/src/AppCommon.cpp
, m_CamCaptureRotation( 0 )
7. CamLogic.cpp - Camera Source Selection¶
File: nolimitgui/src/CamLogic.cpp
m_MyApp.setCamCaptureRotation( m_MyApp.getAppSettings().getCamRotation( camId ) );
m_CamCaptureRotation when camera source is selected
- Used for live camera feed rotation
8. AppSettings.cpp - Camera Rotation Settings¶
File: nolimitgui/src/AppSettings.cpp
void AppSettings::setCamRotation( std::string camId, uint32_t camRotation )
{
// Implementation stores camera rotation by camera ID
}
uint32_t AppSettings::getCamRotation( std::string camId )
{
// Implementation retrieves camera rotation by camera ID
}
Data Flow Analysis¶
Flow 1: Loading Photo via AppletPlayerPhoto¶
AppletPlayerPhoto::playMedia()
└─> VidWidget::setImageFromFile()
└─> VxLabel::setImageFromFile()
└─> VxLabel::loadImageFromFile()
└─> QImage::load()
└─> VxLabel::playMotionVideoFrame(... rotation=0)
└─> VxLabel::playRotatedVideoFrame(... iRotate=m_VidImageRotation)
└─> QTransform::rotate(iRotate) [only if iRotate != 0]
m_VidImageRotation (which is 0 initially)
Flow 2: Loading Photo via AssetPhotoWidget¶
AssetPhotoWidget::setAssetInfo()
└─> VidWidget::setImageFromFile()
└─> VxLabel::setImageFromFile()
└─> VxLabel::loadImageFromFile()
└─> VxLabel::playMotionVideoFrame(... rotation=0)
└─> VxLabel::playRotatedVideoFrame(... iRotate=m_VidImageRotation)
Flow 3: User Rotates Photo (Manual)¶
VidWidget::slotFeedRotateButtonClicked()
└─> VidWidget::setVidImageRotation(newRotation)
└─> VxLabel::setVidImageRotation()
└─> VidWidget::playVideoFrame()
└─> VxLabel::playRotatedVideoFrame(... iRotate=m_VidImageRotation)
└─> QTransform::rotate(iRotate)
Flow 4: User Changes Camera Rotation¶
InputPhotoWidget::slotRotateCamButtonClicked() OR VidWidget::slotCamRotateButtonClicked()
└─> AppSettings::setCamRotation(camId, newRotation)
└─> AppCommon::setCamCaptureRotation(newRotation)
Key Findings¶
What Gets Applied Camera Rotation:¶
- Live Camera Preview - Camera feed from capture device (backend handles rotation)
- Camera Snapshots - When saved, contain the live feed (which may have rotation applied by camera hardware/driver)
- New Photos Taken - Future captures will use the updated camera rotation setting
What Does NOT Apply Camera Rotation:¶
- Photos loaded via AppletPlayerPhoto - No automatic camera rotation
- Photos in AssetPhotoWidget - No automatic camera rotation
- Already-saved photo files - Camera rotation is only for NEW captures
- Historical photos - No retroactive rotation
Where Rotation IS Applied:¶
- Manual rotation button in photo viewer - User clicks rotate button to turn the displayed photo
- VxLabel::playRotatedVideoFrame() - Uses
m_VidImageRotationwhich is set manually, not from camera settings - Camera preview during photo capture - Before user clicks snapshot
Important Classes and Members¶
| Class | Member | Purpose |
|---|---|---|
AppCommon |
m_CamCaptureRotation |
Currently set camera rotation for new captures |
VxLabel |
m_VidImageRotation |
Current rotation applied to displayed image (manual) |
AppSettings |
Camera rotation per camId | Persistent settings for each camera |
VidWidget |
Rotation handling | Delegates to VxLabel |
Conclusion¶
The m_CamCaptureRotation and getCamRotation() settings are NOT automatically applied when displaying loaded photos. They are:
1. Only applied to FUTURE camera captures
2. Used by the camera capture hardware/driver to rotate live preview
3. NOT used anywhere in the photo display pipeline (AppletPlayerPhoto → VidWidget → VxLabel)
If you want to apply camera rotation to loaded photos, you would need to either:
- Apply the rotation manually when loading the photo
- Modify setImageFromFile() to check for and apply camera rotation settings
- Store rotation metadata with the photo at capture time