Allow multiple format image saving
- Keep original image data. When loading JPEG, this avoid recompression that changes file data and decreases image quality - Allow schematic and page layout editors to store non-PNG data as well - Move page layout editor to store base64 instead of hex-coded data
This commit is contained in:
parent
0e382669d0
commit
f9b745f3d2
|
@ -30,6 +30,10 @@
|
|||
#include <richio.h>
|
||||
#include <wx/bitmap.h> // for wxBitmap
|
||||
#include <wx/mstream.h>
|
||||
#include <wx/stream.h> // for wxInputStream, wxOutputStream
|
||||
#include <wx/string.h> // for wxString
|
||||
#include <wx/wfstream.h> // for wxFileInputStream
|
||||
|
||||
|
||||
|
||||
BITMAP_BASE::BITMAP_BASE( const VECTOR2I& pos )
|
||||
|
@ -65,22 +69,13 @@ BITMAP_BASE::BITMAP_BASE( const BITMAP_BASE& aSchBitmap )
|
|||
m_image = new wxImage( *aSchBitmap.m_image );
|
||||
m_bitmap = new wxBitmap( *m_image );
|
||||
m_originalImage = new wxImage( *aSchBitmap.m_originalImage );
|
||||
m_imageType = aSchBitmap.m_imageType;
|
||||
m_imageData = aSchBitmap.m_imageData;
|
||||
m_imageId = aSchBitmap.m_imageId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BITMAP_BASE::SetImage( wxImage* aImage )
|
||||
{
|
||||
delete m_image;
|
||||
m_image = aImage;
|
||||
delete m_originalImage;
|
||||
m_originalImage = new wxImage( *aImage );
|
||||
rebuildBitmap();
|
||||
updatePPI();
|
||||
}
|
||||
|
||||
|
||||
void BITMAP_BASE::rebuildBitmap( bool aResetID )
|
||||
{
|
||||
if( m_bitmap )
|
||||
|
@ -90,6 +85,7 @@ void BITMAP_BASE::rebuildBitmap( bool aResetID )
|
|||
|
||||
if( aResetID )
|
||||
m_imageId = KIID();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -120,42 +116,34 @@ void BITMAP_BASE::ImportData( BITMAP_BASE* aItem )
|
|||
m_isMirroredX = aItem->m_isMirroredX;
|
||||
m_isMirroredY = aItem->m_isMirroredY;
|
||||
m_rotation = aItem->m_rotation;
|
||||
m_imageType = aItem->m_imageType;
|
||||
m_imageData = aItem->m_imageData;
|
||||
}
|
||||
|
||||
|
||||
bool BITMAP_BASE::ReadImageFile( wxInputStream& aInStream )
|
||||
{
|
||||
// Store the original image data in m_imageData
|
||||
size_t dataSize = aInStream.GetLength();
|
||||
m_imageData.SetBufSize( dataSize );
|
||||
aInStream.Read( m_imageData.GetData(), dataSize );
|
||||
m_imageData.SetDataLen( dataSize );
|
||||
|
||||
std::unique_ptr<wxImage> new_image = std::make_unique<wxImage>();
|
||||
|
||||
if( !new_image->LoadFile( aInStream ) )
|
||||
// Load the image from the stream into new_image
|
||||
wxMemoryInputStream mem_stream( m_imageData.GetData(), dataSize );
|
||||
if( !new_image->LoadFile( mem_stream ) )
|
||||
return false;
|
||||
|
||||
delete m_image;
|
||||
m_image = new_image.release();
|
||||
delete m_originalImage;
|
||||
m_originalImage = new wxImage( *m_image );
|
||||
rebuildBitmap();
|
||||
updatePPI();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool BITMAP_BASE::ReadImageFile( const wxString& aFullFilename )
|
||||
{
|
||||
wxImage* new_image = new wxImage();
|
||||
|
||||
if( !new_image->LoadFile( aFullFilename ) )
|
||||
{
|
||||
delete new_image;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_imageType = new_image->GetType();
|
||||
delete m_image;
|
||||
m_image = new_image;
|
||||
m_image = new_image.release();
|
||||
|
||||
// Create a new wxImage object from m_image
|
||||
delete m_originalImage;
|
||||
m_originalImage = new wxImage( *m_image );
|
||||
|
||||
rebuildBitmap();
|
||||
updatePPI();
|
||||
|
||||
|
@ -163,78 +151,69 @@ bool BITMAP_BASE::ReadImageFile( const wxString& aFullFilename )
|
|||
}
|
||||
|
||||
|
||||
bool BITMAP_BASE::SaveData( FILE* aFile ) const
|
||||
bool BITMAP_BASE::ReadImageFile( wxMemoryBuffer& aBuf )
|
||||
{
|
||||
if( m_image )
|
||||
// Store the original image data in m_imageData
|
||||
m_imageData = aBuf;
|
||||
|
||||
std::unique_ptr<wxImage> new_image = std::make_unique<wxImage>();
|
||||
|
||||
// Load the image from the buffer into new_image
|
||||
wxMemoryInputStream mem_stream( m_imageData.GetData(), m_imageData.GetBufSize() );
|
||||
|
||||
if( !new_image->LoadFile( mem_stream ) )
|
||||
return false;
|
||||
|
||||
delete m_image;
|
||||
m_imageType = new_image->GetType();
|
||||
m_image = new_image.release();
|
||||
|
||||
// Create a new wxImage object from m_image
|
||||
delete m_originalImage;
|
||||
m_originalImage = new wxImage( *m_image );
|
||||
|
||||
rebuildBitmap();
|
||||
updatePPI();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool BITMAP_BASE::ReadImageFile(const wxString& aFullFilename)
|
||||
{
|
||||
wxFileInputStream file_stream(aFullFilename);
|
||||
|
||||
// Check if the file could be opened successfully
|
||||
if (!file_stream.IsOk())
|
||||
return false;
|
||||
|
||||
return ReadImageFile(file_stream);
|
||||
}
|
||||
|
||||
|
||||
bool BITMAP_BASE::SaveImageData( wxOutputStream& aOutStream ) const
|
||||
{
|
||||
if( m_imageData.IsEmpty() )
|
||||
{
|
||||
wxMemoryOutputStream stream;
|
||||
// If m_imageData is empty, use wxImage::Save() method to write m_image contents to the stream.
|
||||
wxBitmapType type = m_imageType == wxBITMAP_TYPE_JPEG ? wxBITMAP_TYPE_JPEG : wxBITMAP_TYPE_PNG;
|
||||
|
||||
if( m_imageType == wxBITMAP_TYPE_JPEG )
|
||||
m_image->SaveFile( stream, wxBITMAP_TYPE_JPEG );
|
||||
else
|
||||
// Save as PNG (default
|
||||
m_image->SaveFile( stream, wxBITMAP_TYPE_PNG );
|
||||
|
||||
// Write binary data in hexadecimal form (ASCII)
|
||||
wxStreamBuffer* buffer = stream.GetOutputStreamBuffer();
|
||||
char* begin = (char*) buffer->GetBufferStart();
|
||||
|
||||
for( int ii = 0; begin < buffer->GetBufferEnd(); begin++, ii++ )
|
||||
if( !m_image->SaveFile( aOutStream, type ) )
|
||||
{
|
||||
if( ii >= 32 )
|
||||
{
|
||||
ii = 0;
|
||||
|
||||
if( fprintf( aFile, "\n" ) == EOF )
|
||||
return false;
|
||||
}
|
||||
|
||||
if( fprintf( aFile, "%2.2X ", *begin & 0xFF ) == EOF )
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write the contents of m_imageData to the stream.
|
||||
aOutStream.Write( m_imageData.GetData(), m_imageData.GetBufSize() );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void BITMAP_BASE::SaveData( wxArrayString& aPngStrings ) const
|
||||
{
|
||||
if( m_image )
|
||||
{
|
||||
wxMemoryOutputStream stream;
|
||||
|
||||
if( m_imageType == wxBITMAP_TYPE_JPEG )
|
||||
m_image->SaveFile( stream, wxBITMAP_TYPE_JPEG );
|
||||
else
|
||||
// Save as PNG (default
|
||||
m_image->SaveFile( stream, wxBITMAP_TYPE_PNG );
|
||||
|
||||
// Write binary data in hexadecimal form (ASCII)
|
||||
wxStreamBuffer* buffer = stream.GetOutputStreamBuffer();
|
||||
char* begin = (char*) buffer->GetBufferStart();
|
||||
wxString line;
|
||||
|
||||
for( int ii = 0; begin < buffer->GetBufferEnd(); begin++, ii++ )
|
||||
{
|
||||
if( ii >= 32 )
|
||||
{
|
||||
ii = 0;
|
||||
aPngStrings.Add( line );
|
||||
line.Empty();
|
||||
}
|
||||
|
||||
line << wxString::Format( wxT( "%2.2X " ), *begin & 0xFF );
|
||||
}
|
||||
|
||||
// Add last line:
|
||||
if( !line.IsEmpty() )
|
||||
aPngStrings.Add( line );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool BITMAP_BASE::LoadData( LINE_READER& aLine, wxString& aErrorMsg )
|
||||
bool BITMAP_BASE::LoadLegacyData( LINE_READER& aLine, wxString& aErrorMsg )
|
||||
{
|
||||
wxMemoryOutputStream stream;
|
||||
char* line;
|
||||
|
@ -258,6 +237,7 @@ bool BITMAP_BASE::LoadData( LINE_READER& aLine, wxString& aErrorMsg )
|
|||
m_image->LoadFile( istream, wxBITMAP_TYPE_ANY );
|
||||
m_bitmap = new wxBitmap( *m_image );
|
||||
m_originalImage = new wxImage( *m_image );
|
||||
UpdateImageDataBuffer();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -450,6 +430,7 @@ void BITMAP_BASE::Mirror( bool aVertically )
|
|||
m_isMirroredX = !m_isMirroredX;
|
||||
|
||||
rebuildBitmap( false );
|
||||
UpdateImageDataBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -474,6 +455,7 @@ void BITMAP_BASE::Rotate( bool aRotateCCW )
|
|||
|
||||
m_rotation += ( aRotateCCW ? -ANGLE_90 : ANGLE_90 );
|
||||
rebuildBitmap( false );
|
||||
UpdateImageDataBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -485,6 +467,7 @@ void BITMAP_BASE::ConvertToGreyscale()
|
|||
*m_image = m_image->ConvertToGreyscale();
|
||||
*m_originalImage = m_originalImage->ConvertToGreyscale();
|
||||
rebuildBitmap();
|
||||
UpdateImageDataBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -502,3 +485,20 @@ void BITMAP_BASE::PlotImage( PLOTTER* aPlotter, const VECTOR2I& aPos,
|
|||
aPlotter->SetCurrentLineWidth( aDefaultPensize );
|
||||
aPlotter->PlotImage( *m_image, aPos, GetScalingFactor() );
|
||||
}
|
||||
|
||||
|
||||
void BITMAP_BASE::UpdateImageDataBuffer()
|
||||
{
|
||||
if( m_image )
|
||||
{
|
||||
wxMemoryOutputStream stream;
|
||||
wxBitmapType type = m_imageType == wxBITMAP_TYPE_JPEG ? wxBITMAP_TYPE_JPEG : wxBITMAP_TYPE_PNG;
|
||||
|
||||
if( !m_image->SaveFile( stream, type ) )
|
||||
return;
|
||||
|
||||
m_imageData.GetWriteBuf( stream.GetLength() );
|
||||
stream.CopyTo( m_imageData.GetData(), stream.GetLength() );
|
||||
m_imageData.SetDataLen( stream.GetLength() );
|
||||
}
|
||||
}
|
|
@ -24,8 +24,10 @@
|
|||
*/
|
||||
|
||||
#include <charconv>
|
||||
#include <wx/base64.h>
|
||||
#include <wx/ffile.h>
|
||||
#include <wx/log.h>
|
||||
|
||||
#include <eda_item.h>
|
||||
#include <locale_io.h>
|
||||
#include <string_utils.h>
|
||||
|
@ -512,6 +514,33 @@ void DRAWING_SHEET_PARSER::parseBitmap( DS_DATA_ITEM_BITMAP * aItem )
|
|||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_data:
|
||||
{
|
||||
token = NextTok();
|
||||
|
||||
wxString data;
|
||||
|
||||
// Reserve 512K because most image files are going to be larger than the default
|
||||
// 1K that wxString reserves.
|
||||
data.reserve( 1 << 19 );
|
||||
|
||||
while( token != T_RIGHT )
|
||||
{
|
||||
if( !IsSymbol( token ) )
|
||||
Expecting( "base64 image data" );
|
||||
|
||||
data += FromUTF8();
|
||||
token = NextTok();
|
||||
}
|
||||
|
||||
wxMemoryBuffer buffer = wxBase64Decode( data );
|
||||
|
||||
if( !aItem->m_ImageBitmap->ReadImageFile( buffer ) )
|
||||
THROW_IO_ERROR( _( "Failed to read image data." ) );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case T_pngdata:
|
||||
readPngdata( aItem );
|
||||
break;
|
||||
|
@ -556,7 +585,7 @@ void DRAWING_SHEET_PARSER::readPngdata( DS_DATA_ITEM_BITMAP * aItem )
|
|||
wxString msg;
|
||||
STRING_LINE_READER str_reader( tmp, wxT("Png kicad_wks data") );
|
||||
|
||||
if( ! aItem->m_ImageBitmap->LoadData( str_reader, msg ) )
|
||||
if( ! aItem->m_ImageBitmap->LoadLegacyData( str_reader, msg ) )
|
||||
wxLogMessage(msg);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <drawing_sheet/ds_file_versions.h>
|
||||
#include <font/font.h>
|
||||
|
||||
#include <wx/base64.h>
|
||||
#include <wx/msgdlg.h>
|
||||
|
||||
using namespace DRAWINGSHEET_T;
|
||||
|
@ -417,16 +418,26 @@ void DS_DATA_MODEL_IO::format( DS_DATA_ITEM_BITMAP* aItem, int aNestLevel ) cons
|
|||
m_out->Print( 0, " (comment %s)\n", m_out->Quotew( aItem->m_Info ).c_str() );
|
||||
|
||||
// Write image in png readable format
|
||||
m_out->Print( aNestLevel, "(pngdata\n" );
|
||||
wxArrayString pngStrings;
|
||||
aItem->m_ImageBitmap->SaveData( pngStrings );
|
||||
m_out->Print( aNestLevel, "(data" );
|
||||
|
||||
for( unsigned ii = 0; ii < pngStrings.GetCount(); ii++ )
|
||||
m_out->Print( aNestLevel+1, "(data \"%s\")\n", TO_UTF8(pngStrings[ii]) );
|
||||
wxString out = wxBase64Encode( aItem->m_ImageBitmap->GetImageDataBuffer() );
|
||||
|
||||
m_out->Print( aNestLevel+1, ")\n" );
|
||||
// Apparently the MIME standard character width for base64 encoding is 76 (unconfirmed)
|
||||
// so use it in a vain attempt to be standard like.
|
||||
#define MIME_BASE64_LENGTH 76
|
||||
|
||||
m_out->Print( aNestLevel, ")\n" );
|
||||
size_t first = 0;
|
||||
|
||||
while( first < out.Length() )
|
||||
{
|
||||
m_out->Print( 0, "\n" );
|
||||
m_out->Print( aNestLevel + 1, "%s", TO_UTF8( out( first, MIME_BASE64_LENGTH ) ) );
|
||||
first += MIME_BASE64_LENGTH;
|
||||
}
|
||||
|
||||
m_out->Print( 0, "\n" );
|
||||
m_out->Print( aNestLevel, ")\n" ); // Closes data token.
|
||||
m_out->Print( aNestLevel, ")\n" ); // Closes bitmap token.
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -92,13 +92,6 @@ bool SCH_BITMAP::ReadImageFile( const wxString& aFullFilename )
|
|||
}
|
||||
|
||||
|
||||
void SCH_BITMAP::SetImage( wxImage* aImage )
|
||||
{
|
||||
m_bitmapBase->SetImage( aImage );
|
||||
m_bitmapBase->SetPixelSizeIu( 254000.0 / m_bitmapBase->GetPPI() );
|
||||
}
|
||||
|
||||
|
||||
EDA_ITEM* SCH_BITMAP::Clone() const
|
||||
{
|
||||
return new SCH_BITMAP( *this );
|
||||
|
|
|
@ -58,8 +58,6 @@ public:
|
|||
return m_bitmapBase;
|
||||
}
|
||||
|
||||
void SetImage( wxImage* aImage );
|
||||
|
||||
/**
|
||||
* @return the image "zoom" value.
|
||||
* scale = 1.0 = original size of bitmap.
|
||||
|
|
|
@ -3056,11 +3056,10 @@ SCH_BITMAP* SCH_SEXPR_PARSER::parseImage()
|
|||
}
|
||||
|
||||
wxMemoryBuffer buffer = wxBase64Decode( data );
|
||||
wxMemoryOutputStream stream( buffer.GetData(), buffer.GetBufSize() );
|
||||
wxImage* image = new wxImage();
|
||||
wxMemoryInputStream istream( stream );
|
||||
image->LoadFile( istream, wxBITMAP_TYPE_PNG );
|
||||
bitmap->SetImage( image );
|
||||
|
||||
if( !bitmap->GetImage()->ReadImageFile( buffer ) )
|
||||
THROW_IO_ERROR( _( "Failed to read image data." ) );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -952,13 +952,7 @@ void SCH_SEXPR_PLUGIN::saveBitmap( SCH_BITMAP* aBitmap, int aNestLevel )
|
|||
|
||||
m_out->Print( aNestLevel + 1, "(data" );
|
||||
|
||||
wxMemoryOutputStream stream;
|
||||
|
||||
image->SaveFile( stream, wxBITMAP_TYPE_PNG );
|
||||
|
||||
// Write binary data in hexadecimal form (ASCII)
|
||||
wxStreamBuffer* buffer = stream.GetOutputStreamBuffer();
|
||||
wxString out = wxBase64Encode( buffer->GetBufferStart(), buffer->GetBufferSize() );
|
||||
wxString out = wxBase64Encode( aBitmap->GetImage()->GetImageDataBuffer() );
|
||||
|
||||
// Apparently the MIME standard character width for base64 encoding is 76 (unconfirmed)
|
||||
// so use it in a vein attempt to be standard like.
|
||||
|
|
|
@ -676,7 +676,7 @@ SCH_BITMAP* SCH_LEGACY_PLUGIN::loadBitmap( LINE_READER& aReader )
|
|||
}
|
||||
else if( strCompare( "Data", line, &line ) )
|
||||
{
|
||||
wxMemoryOutputStream stream;
|
||||
wxMemoryBuffer buffer;
|
||||
|
||||
while( line )
|
||||
{
|
||||
|
@ -688,12 +688,7 @@ SCH_BITMAP* SCH_LEGACY_PLUGIN::loadBitmap( LINE_READER& aReader )
|
|||
if( strCompare( "EndData", line ) )
|
||||
{
|
||||
// all the PNG date is read.
|
||||
// We expect here m_image and m_bitmap are void
|
||||
wxImage* image = new wxImage();
|
||||
wxMemoryInputStream istream( stream );
|
||||
image->LoadFile( istream, wxBITMAP_TYPE_PNG );
|
||||
|
||||
bitmap->SetImage( image );
|
||||
bitmap->GetImage()->ReadImageFile( buffer );
|
||||
|
||||
// Legacy file formats assumed 300 image PPI at load.
|
||||
BITMAP_BASE* bitmapImage = bitmap->GetImage();
|
||||
|
@ -716,7 +711,7 @@ SCH_BITMAP* SCH_LEGACY_PLUGIN::loadBitmap( LINE_READER& aReader )
|
|||
int value = 0;
|
||||
|
||||
if( sscanf( line, "%X", &value ) == 1 )
|
||||
stream.PutC( (char) value );
|
||||
buffer.AppendByte( (char) value );
|
||||
else
|
||||
THROW_IO_ERROR( "invalid PNG data" );
|
||||
}
|
||||
|
|
|
@ -69,8 +69,6 @@ public:
|
|||
|
||||
const wxImage* GetOriginalImageData() const { return m_originalImage; }
|
||||
|
||||
void SetImage( wxImage* aImage );
|
||||
|
||||
double GetScale() const { return m_scale; }
|
||||
void SetScale( double aScale ) { m_scale = aScale; }
|
||||
|
||||
|
@ -159,25 +157,27 @@ public:
|
|||
bool ReadImageFile( wxInputStream& aInStream );
|
||||
|
||||
/**
|
||||
* Write the bitmap data to \a aFile.
|
||||
* Reads and stores in memory an image file.
|
||||
*
|
||||
* The file format is png, in hexadecimal form. If the hexadecimal data is converted to
|
||||
* binary it gives exactly a .png image data.
|
||||
* Initialize the bitmap format used to draw this item.
|
||||
*
|
||||
* @param aFile The FILE to write to.
|
||||
* @return true if success writing else false.
|
||||
* Supported images formats are format supported by wxImage if all handlers are loaded.
|
||||
* By default, .png, .jpeg are always loaded.
|
||||
*
|
||||
* @param aBuf a memory buffer containing the file data.
|
||||
* @return true if success reading else false.
|
||||
*/
|
||||
bool SaveData( FILE* aFile ) const;
|
||||
bool ReadImageFile( wxMemoryBuffer& aBuf );
|
||||
|
||||
/**
|
||||
* Write the bitmap data to an array string.
|
||||
*
|
||||
* The format is png, in Hexadecimal form. If the hexadecimal data is converted to binary
|
||||
* it gives exactly a .png image data.
|
||||
*
|
||||
* @param aPngStrings The wxArrayString to write to.
|
||||
*/
|
||||
void SaveData( wxArrayString& aPngStrings ) const;
|
||||
* Write the bitmap data to \a aOutStream.
|
||||
*
|
||||
* This writes binary data, not hexadecimal strings
|
||||
*
|
||||
* @param aOutStream The output stream to write to.
|
||||
* @return true if success writing else false.
|
||||
*/
|
||||
bool SaveImageData( wxOutputStream& aOutStream ) const;
|
||||
|
||||
/**
|
||||
* Load an image data saved by #SaveData.
|
||||
|
@ -189,7 +189,7 @@ public:
|
|||
* png bitmap data.
|
||||
* @return true if the bitmap loaded successfully.
|
||||
*/
|
||||
bool LoadData( LINE_READER& aLine, wxString& aErrorMsg );
|
||||
bool LoadLegacyData( LINE_READER& aLine, wxString& aErrorMsg );
|
||||
|
||||
/**
|
||||
* Mirror image vertically (i.e. relative to its horizontal X axis ) or horizontally (i.e
|
||||
|
@ -234,6 +234,16 @@ public:
|
|||
*/
|
||||
void SetImageType( wxBitmapType aType ) { m_imageType = aType; }
|
||||
|
||||
/**
|
||||
* @return the image data buffer.
|
||||
*/
|
||||
const wxMemoryBuffer& GetImageDataBuffer() const { return m_imageData; }
|
||||
|
||||
/**
|
||||
* Resets the image data buffer using the current image data.
|
||||
*/
|
||||
void UpdateImageDataBuffer();
|
||||
|
||||
private:
|
||||
/*
|
||||
* Rebuild the internal bitmap used to draw/plot image.
|
||||
|
@ -248,8 +258,10 @@ private:
|
|||
|
||||
double m_scale; // The scaling factor of the bitmap
|
||||
// With m_pixelSizeIu, controls the actual draw size
|
||||
wxImage* m_image; // the raw image data
|
||||
wxBitmapType m_imageType; // the image type (png, jpeg, etc.)
|
||||
wxMemoryBuffer m_imageData; // The original image data, in its original format
|
||||
wxBitmapType m_imageType; // the image type (png, jpeg, etc.)
|
||||
|
||||
wxImage* m_image; // the raw, uncompressed image data
|
||||
wxImage* m_originalImage; // Raw image data, not transformed by rotate/mirror
|
||||
wxBitmap* m_bitmap; // the bitmap used to draw/plot image
|
||||
double m_pixelSizeIu; // The scaling factor of the bitmap
|
||||
|
|
|
@ -31,4 +31,5 @@
|
|||
*/
|
||||
|
||||
//#define SEXPR_WORKSHEET_FILE_VERSION 20210606 // Initial version.
|
||||
#define SEXPR_WORKSHEET_FILE_VERSION 20220228 // Font support.
|
||||
//#define SEXPR_WORKSHEET_FILE_VERSION 20220228 // Font support.
|
||||
#define SEXPR_WORKSHEET_FILE_VERSION 20230607 // Save images as base64.
|
||||
|
|
|
@ -82,13 +82,6 @@ PCB_BITMAP& PCB_BITMAP::operator=( const BOARD_ITEM& aItem )
|
|||
}
|
||||
|
||||
|
||||
void PCB_BITMAP::SetImage( wxImage* aImage )
|
||||
{
|
||||
m_bitmapBase->SetImage( aImage );
|
||||
m_bitmapBase->SetPixelSizeIu( (float) pcbIUScale.MilsToIU( 1000 ) / m_bitmapBase->GetPPI() );
|
||||
}
|
||||
|
||||
|
||||
bool PCB_BITMAP::ReadImageFile( const wxString& aFullFilename )
|
||||
{
|
||||
if( m_bitmapBase->ReadImageFile( aFullFilename ) )
|
||||
|
@ -101,6 +94,18 @@ bool PCB_BITMAP::ReadImageFile( const wxString& aFullFilename )
|
|||
}
|
||||
|
||||
|
||||
bool PCB_BITMAP::ReadImageFile( wxMemoryBuffer& aBuffer )
|
||||
{
|
||||
if( m_bitmapBase->ReadImageFile( aBuffer ) )
|
||||
{
|
||||
m_bitmapBase->SetPixelSizeIu( (float) pcbIUScale.MilsToIU( 1000 ) / m_bitmapBase->GetPPI() );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
EDA_ITEM* PCB_BITMAP::Clone() const
|
||||
{
|
||||
return new PCB_BITMAP( *this );
|
||||
|
|
|
@ -65,8 +65,6 @@ public:
|
|||
return m_bitmapBase;
|
||||
}
|
||||
|
||||
void SetImage( wxImage* aImage );
|
||||
|
||||
/**
|
||||
* @return the image "zoom" value.
|
||||
* scale = 1.0 = original size of bitmap.
|
||||
|
@ -111,6 +109,16 @@ public:
|
|||
*/
|
||||
bool ReadImageFile( const wxString& aFullFilename );
|
||||
|
||||
/**
|
||||
* Read and store an image file.
|
||||
*
|
||||
* Initialize the bitmap used to draw this item format.
|
||||
*
|
||||
* @param aBuf is the memory buffer containing the image file to read.
|
||||
* @return true if success reading else false.
|
||||
*/
|
||||
bool ReadImageFile( wxMemoryBuffer& aBuf );
|
||||
|
||||
void Move( const VECTOR2I& aMoveVector ) override { m_pos += aMoveVector; }
|
||||
|
||||
void Flip( const VECTOR2I& aCentre, bool aFlipLeftRight ) override;
|
||||
|
|
|
@ -2967,9 +2967,9 @@ PCB_BITMAP* PCB_PARSER::parsePCB_BITMAP( BOARD_ITEM* aParent )
|
|||
|
||||
wxString data;
|
||||
|
||||
// Reserve 128K because most image files are going to be larger than the default
|
||||
// Reserve 512K because most image files are going to be larger than the default
|
||||
// 1K that wxString reserves.
|
||||
data.reserve( 1 << 17 );
|
||||
data.reserve( 1 << 19 );
|
||||
|
||||
while( token != T_RIGHT )
|
||||
{
|
||||
|
@ -2981,12 +2981,10 @@ PCB_BITMAP* PCB_PARSER::parsePCB_BITMAP( BOARD_ITEM* aParent )
|
|||
}
|
||||
|
||||
wxMemoryBuffer buffer = wxBase64Decode( data );
|
||||
wxMemoryOutputStream stream( buffer.GetData(), buffer.GetBufSize() );
|
||||
wxImage* image = new wxImage();
|
||||
wxMemoryInputStream istream( stream );
|
||||
image->LoadFile( istream );
|
||||
bitmap->SetImage( image );
|
||||
bitmap->MutableImage()->SetImageType( image->GetType() );
|
||||
|
||||
if( !bitmap->ReadImageFile( buffer ) )
|
||||
THROW_IO_ERROR( _( "Failed to read image data." ) );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1040,19 +1040,7 @@ void PCB_PLUGIN::format( const PCB_BITMAP* aBitmap, int aNestLevel ) const
|
|||
|
||||
m_out->Print( aNestLevel + 1, "(data" );
|
||||
|
||||
wxMemoryOutputStream stream;
|
||||
wxBitmapType type = wxBITMAP_TYPE_PNG;
|
||||
|
||||
// Save the image in the same format as the original file
|
||||
// if it was a JPEG. Otherwise, save it as a PNG.
|
||||
if( aBitmap->GetImage()->GetImageType() == wxBITMAP_TYPE_JPEG )
|
||||
type = wxBITMAP_TYPE_JPEG;
|
||||
|
||||
image->SaveFile( stream, type );
|
||||
|
||||
// Write binary data in hexadecimal form (ASCII)
|
||||
wxStreamBuffer* buffer = stream.GetOutputStreamBuffer();
|
||||
wxString out = wxBase64Encode( buffer->GetBufferStart(), buffer->GetBufferSize() );
|
||||
wxString out = wxBase64Encode( aBitmap->GetImage()->GetImageDataBuffer() );
|
||||
|
||||
// Apparently the MIME standard character width for base64 encoding is 76 (unconfirmed)
|
||||
// so use it in a vain attempt to be standard like.
|
||||
|
|
Loading…
Reference in New Issue