KiCad PCB EDA Suite
Loading...
Searching...
No Matches
bitmap_import_plugin.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
21
22#include <eda_item.h>
23#include "graphics_importer.h"
24
25#include <bitmap_tracing.h>
26#include <math/util.h>
27#include <reporter.h>
28#include <wx/log.h>
29#include <wx/mstream.h>
30
31
32static const double MM_PER_INCH = 25.4;
33
35static const double TRACE_SUBUNITS = 1000.0;
36
37
38void BITMAP_IMPORT_PLUGIN::ReportMsg( const wxString& aMessage )
39{
40 m_messages += aMessage;
41 m_messages += '\n';
42}
43
44
45bool BITMAP_IMPORT_PLUGIN::Load( const wxString& aFileName )
46{
47 wxLogNull doNotLog;
48
49 m_image.Destroy();
50
51 return m_image.LoadFile( aFileName );
52}
53
54
55bool BITMAP_IMPORT_PLUGIN::LoadFromMemory( const wxMemoryBuffer& aMemBuffer )
56{
57 wxLogNull doNotLog;
58
59 wxMemoryInputStream stream( aMemBuffer.GetData(), aMemBuffer.GetDataLen() );
60
61 m_image.Destroy();
62
63 return m_image.LoadFile( stream );
64}
65
66
67static int imageResolution( const wxImage& aImage, const wxString& aOption, int aDefault )
68{
69 // Read as a string because GetOptionInt truncates a fractional pixels per cm value.
70 double dpi = 0.0;
71 wxString resolution = aImage.GetOption( aOption );
72
73 resolution.ToCDouble( &dpi );
74
75 if( dpi <= 1.0 )
76 return aDefault;
77
78 if( aImage.GetOptionInt( wxIMAGE_OPTION_RESOLUTIONUNIT ) == wxIMAGE_RESOLUTION_CM )
79 return KiROUND( dpi * 2.54 );
80
81 return KiROUND( dpi );
82}
83
84
86{
87 return MM_PER_INCH / imageResolution( m_image, wxIMAGE_OPTION_RESOLUTIONX, DEFAULT_DPI );
88}
89
90
92{
93 return MM_PER_INCH / imageResolution( m_image, wxIMAGE_OPTION_RESOLUTIONY, DEFAULT_DPI );
94}
95
96
98{
99 return m_image.GetWidth() * pixelSizeXmm();
100}
101
102
104{
105 return m_image.GetHeight() * pixelSizeYmm();
106}
107
108
113
114
116{
117 wxCHECK( m_importer, false );
118
119 // A traced area is filled, so it has no outline. The importer spells that -1.
120 static const IMPORTED_STROKE noStroke( -1, LINE_STYLE::SOLID, COLOR4D::UNSPECIFIED );
121
122 if( !m_image.IsOk() )
123 return false;
124
125 wxImage bilevel = ConvertImageToBilevel( m_image, m_threshold, m_invert );
126
129
130 if( reporter.HasMessage() )
131 ReportMsg( reporter.GetMessages() );
132
133 for( int ii = 0; ii < polygons.OutlineCount(); ii++ )
134 {
135 const SHAPE_LINE_CHAIN& outline = polygons.COutline( ii );
136 std::vector<VECTOR2D> vertices;
137
138 vertices.reserve( outline.PointCount() );
139
140 for( int jj = 0; jj < outline.PointCount(); jj++ )
141 {
142 vertices.emplace_back( outline.CPoint( jj ).x / TRACE_SUBUNITS * pixelSizeXmm(),
143 outline.CPoint( jj ).y / TRACE_SUBUNITS * pixelSizeYmm() );
144 }
145
146 m_importer->AddPolygon( vertices, noStroke, true, COLOR4D::UNSPECIFIED );
147 }
148
149 return true;
150}
static int imageResolution(const wxImage &aImage, const wxString &aOption, int aDefault)
static const double TRACE_SUBUNITS
Sub units per pixel while tracing. A whole pixel is too coarse a step for the integer tracer.
static const double MM_PER_INCH
wxImage ConvertImageToBilevel(const wxImage &aImage, double aThreshold, bool aInvert)
Reduce an image to pure black and white.
SHAPE_POLY_SET TraceBilevelImage(const wxImage &aBilevelImage, double aScaleX, double aScaleY, REPORTER &aReporter)
Trace the black regions of a black and white image into filled polygons.
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:982
BOX2< VECTOR2D > BOX2D
Definition box2.h:915
bool Load(const wxString &aFileName) override
Load file for import.
double GetImageWidth() const override
Return image width from original imported file.
void ReportMsg(const wxString &aMessage) override
bool LoadFromMemory(const wxMemoryBuffer &aMemBuffer) override
Set memory buffer with content for import.
bool Import() override
Actually imports the file.
BOX2D GetImageBBox() const override
Return image bounding box from original imported file.
static constexpr int DEFAULT_DPI
Resolution assumed for images that do not carry one.
double GetImageHeight() const override
Return image height from original imported file.
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:400
GRAPHICS_IMPORTER * m_importer
Importer used to create objects representing the imported shapes.
A clone of IMPORTED_STROKE, but with floating-point width.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
int PointCount() const
Return the number of points (vertices) in this line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
Represent a set of closed polygons.
int OutlineCount() const
Return the number of outlines in the set.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
A wrapper for reporting to a wxString object.
Definition reporter.h:242
IbisParser parser & reporter
VECTOR2< double > VECTOR2D
Definition vector2d.h:707