Fix handling of PPI when loading embedded images

Fixes https://gitlab.com/kicad/code/kicad/-/issues/13884
This commit is contained in:
Jon Evans 2023-02-14 19:41:54 -05:00
parent 64f1808d60
commit 473979d686
6 changed files with 43 additions and 17 deletions

View File

@ -75,6 +75,7 @@ void BITMAP_BASE::SetImage( wxImage* aImage )
delete m_originalImage;
m_originalImage = new wxImage( *aImage );
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 )
{
*m_image = *aItem->m_image;
@ -116,6 +132,7 @@ bool BITMAP_BASE::ReadImageFile( wxInputStream& aInStream )
delete m_originalImage;
m_originalImage = new wxImage( *m_image );
rebuildBitmap();
updatePPI();
return true;
}
@ -136,17 +153,7 @@ bool BITMAP_BASE::ReadImageFile( const wxString& aFullFilename )
delete m_originalImage;
m_originalImage = new wxImage( *m_image );
rebuildBitmap();
// 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;
}
updatePPI();
return true;
}

View File

@ -236,6 +236,8 @@ private:
*/
void rebuildBitmap( bool aResetID = true );
void updatePPI();
double m_scale; // The scaling factor of the bitmap
// With m_pixelSizeIu, controls the actual draw size
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 )
{
// 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_posX.SetCoordType( ORIGIN_TRANSFORMS::ABS_X_COORD );
@ -97,7 +97,7 @@ bool DIALOG_IMAGE_PROPERTIES::TransferDataFromWindow()
m_frame->SaveCopyInUndoList( m_bitmap, UNDO_REDO::CHANGED );
// Update our bitmap from the editor
m_imageEditor->TransferToImage( m_bitmap->GetImage() );
m_imageEditor->TransferToImage( m_bitmap->MutableImage() );
// Set position, etc.
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 )
{
if( m_image->ReadImageFile( aFullFilename ) )

View File

@ -50,12 +50,22 @@ public:
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." );
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.
* scale = 1.0 = original size of bitmap.

View File

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