Fix handling of PPI when loading embedded images

Fixes https://gitlab.com/kicad/code/kicad/-/issues/13884


(cherry picked from commit 473979d686)
This commit is contained in:
Jon Evans 2023-02-14 19:41:54 -05:00
parent 37091df142
commit d20f49b58b
6 changed files with 43 additions and 17 deletions

View File

@ -75,6 +75,7 @@ void BITMAP_BASE::SetImage( wxImage* aImage )
delete m_originalImage; delete m_originalImage;
m_originalImage = new wxImage( *aImage ); m_originalImage = new wxImage( *aImage );
rebuildBitmap(); rebuildBitmap();
updatePPI();
} }
@ -90,6 +91,21 @@ void BITMAP_BASE::rebuildBitmap( bool aResetID )
} }
void BITMAP_BASE::updatePPI()
{
// Todo: eventually we need to support dpi / scaling in both dimensions
int dpiX = m_originalImage->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONX );
if( dpiX > 1 )
{
if( m_originalImage->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONUNIT ) == wxIMAGE_RESOLUTION_CM )
m_ppi = KiROUND( dpiX * 2.54 );
else
m_ppi = dpiX;
}
}
void BITMAP_BASE::ImportData( BITMAP_BASE* aItem ) void BITMAP_BASE::ImportData( BITMAP_BASE* aItem )
{ {
*m_image = *aItem->m_image; *m_image = *aItem->m_image;
@ -116,6 +132,7 @@ bool BITMAP_BASE::ReadImageFile( wxInputStream& aInStream )
delete m_originalImage; delete m_originalImage;
m_originalImage = new wxImage( *m_image ); m_originalImage = new wxImage( *m_image );
rebuildBitmap(); rebuildBitmap();
updatePPI();
return true; return true;
} }
@ -136,17 +153,7 @@ bool BITMAP_BASE::ReadImageFile( const wxString& aFullFilename )
delete m_originalImage; delete m_originalImage;
m_originalImage = new wxImage( *m_image ); m_originalImage = new wxImage( *m_image );
rebuildBitmap(); rebuildBitmap();
updatePPI();
// Todo: eventually we need to support dpi / scaling in both dimensions
int dpiX = m_originalImage->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONX );
if( dpiX > 1 )
{
if( m_originalImage->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONUNIT ) == wxIMAGE_RESOLUTION_CM )
m_ppi = KiROUND( dpiX * 2.54 );
else
m_ppi = dpiX;
}
return true; return true;
} }

View File

@ -236,6 +236,8 @@ private:
*/ */
void rebuildBitmap( bool aResetID = true ); void rebuildBitmap( bool aResetID = true );
void updatePPI();
double m_scale; // The scaling factor of the bitmap double m_scale; // The scaling factor of the bitmap
// With m_pixelSizeIu, controls the actual draw size // With m_pixelSizeIu, controls the actual draw size
wxImage* m_image; // the raw image data (png format) wxImage* m_image; // the raw image data (png format)

View File

@ -37,7 +37,7 @@ DIALOG_IMAGE_PROPERTIES::DIALOG_IMAGE_PROPERTIES( PCB_BASE_FRAME* aParent, PCB_B
m_posY( aParent, m_YPosLabel, m_ModPositionY, m_YPosUnit ) m_posY( aParent, m_YPosLabel, m_ModPositionY, m_YPosUnit )
{ {
// Create the image editor page // Create the image editor page
m_imageEditor = new PANEL_IMAGE_EDITOR( m_Notebook, aBitmap->GetImage() ); m_imageEditor = new PANEL_IMAGE_EDITOR( m_Notebook, aBitmap->MutableImage() );
m_Notebook->AddPage( m_imageEditor, _( "Image" ), false ); m_Notebook->AddPage( m_imageEditor, _( "Image" ), false );
m_posX.SetCoordType( ORIGIN_TRANSFORMS::ABS_X_COORD ); m_posX.SetCoordType( ORIGIN_TRANSFORMS::ABS_X_COORD );
@ -97,7 +97,7 @@ bool DIALOG_IMAGE_PROPERTIES::TransferDataFromWindow()
m_frame->SaveCopyInUndoList( m_bitmap, UNDO_REDO::CHANGED ); m_frame->SaveCopyInUndoList( m_bitmap, UNDO_REDO::CHANGED );
// Update our bitmap from the editor // Update our bitmap from the editor
m_imageEditor->TransferToImage( m_bitmap->GetImage() ); m_imageEditor->TransferToImage( m_bitmap->MutableImage() );
// Set position, etc. // Set position, etc.
m_bitmap->SetPosition( VECTOR2I( m_posX.GetValue(), m_posY.GetValue() ) ); m_bitmap->SetPosition( VECTOR2I( m_posX.GetValue(), m_posY.GetValue() ) );

View File

@ -82,6 +82,13 @@ PCB_BITMAP& PCB_BITMAP::operator=( const BOARD_ITEM& aItem )
} }
void PCB_BITMAP::SetImage( wxImage* aImage )
{
m_image->SetImage( aImage );
m_image->SetPixelSizeIu( (float) pcbIUScale.MilsToIU( 1000 ) / m_image->GetPPI() );
}
bool PCB_BITMAP::ReadImageFile( const wxString& aFullFilename ) bool PCB_BITMAP::ReadImageFile( const wxString& aFullFilename )
{ {
if( m_image->ReadImageFile( aFullFilename ) ) if( m_image->ReadImageFile( aFullFilename ) )

View File

@ -50,12 +50,22 @@ public:
PCB_BITMAP& operator=( const BOARD_ITEM& aItem ); PCB_BITMAP& operator=( const BOARD_ITEM& aItem );
BITMAP_BASE* GetImage() const const BITMAP_BASE* GetImage() const
{ {
wxCHECK_MSG( m_image != nullptr, nullptr, "Invalid PCB_BITMAP init, m_image is NULL." ); wxCHECK_MSG( m_image != nullptr, nullptr, "Invalid PCB_BITMAP init, m_image is NULL." );
return m_image; return m_image;
} }
/**
* Only use this if you really need to modify the underlying image
*/
BITMAP_BASE* MutableImage() const
{
return m_image;
}
void SetImage( wxImage* aImage );
/** /**
* @return the image "zoom" value. * @return the image "zoom" value.
* scale = 1.0 = original size of bitmap. * scale = 1.0 = original size of bitmap.

View File

@ -2876,10 +2876,10 @@ PCB_BITMAP* PCB_PARSER::parsePCB_BITMAP( BOARD_ITEM* aParent )
break; break;
case T_scale: case T_scale:
bitmap->GetImage()->SetScale( parseDouble( "image scale factor" ) ); bitmap->SetImageScale( parseDouble( "image scale factor" ) );
if( !std::isnormal( bitmap->GetImage()->GetScale() ) ) if( !std::isnormal( bitmap->GetImage()->GetScale() ) )
bitmap->GetImage()->SetScale( 1.0 ); bitmap->SetImageScale( 1.0 );
NeedRIGHT(); NeedRIGHT();
break; break;
@ -2908,7 +2908,7 @@ PCB_BITMAP* PCB_PARSER::parsePCB_BITMAP( BOARD_ITEM* aParent )
wxImage* image = new wxImage(); wxImage* image = new wxImage();
wxMemoryInputStream istream( stream ); wxMemoryInputStream istream( stream );
image->LoadFile( istream, wxBITMAP_TYPE_PNG ); image->LoadFile( istream, wxBITMAP_TYPE_PNG );
bitmap->GetImage()->SetImage( image ); bitmap->SetImage( image );
break; break;
} }