wxArt2D
imageioh.cpp
Go to the documentation of this file.
1 /*! \file canextobj/src/imageioh.cpp
2  \author Klaas Holwerda
3 
4  Copyright: 2001-2004 (c) Klaas Holwerda
5 
6  Licence: wxWidgets Licence
7 
8  RCS-ID: $Id: imageioh.cpp,v 1.27 2009/10/01 19:22:35 titato Exp $
9 */
10 
11 #include "a2dprec.h"
12 
13 #ifdef __BORLANDC__
14 #pragma hdrstop
15 #endif
16 
17 #ifndef WX_PRECOMP
18 #include "wx/wx.h"
19 #endif
20 
21 #include "wx/canextobj/imageioh.h"
22 #include "wx/editor/candoc.h"
23 
24 
25 //----------------------------------------------------------------------------
26 // a2dCanvasDocumentIOHandlerImageIn
27 //----------------------------------------------------------------------------
28 
30 {
31  m_type = type;
32  m_scale = 1;
33  m_docClassInfo = &a2dCanvasDocument::ms_classInfo;
34  m_showObject = NULL;
35  m_doc = NULL;
36 }
37 
39 {
40 }
41 
43 {
44  wxASSERT_MSG( m_streami , wxT( "m_stream not set" ) );
45 
46  wxImageHandler* handlerfound = NULL;
47  wxList::compatibility_iterator node = wxImage::GetHandlers().GetFirst();
48  while ( node )
49  {
50  SeekI( 0 );
51  wxImageHandler* handler = ( wxImageHandler* )node->GetData();
52 #if wxUSE_STD_IOSTREAM
53 
54  wxMemoryBuffer mem;
55  const int BUFFSIZE = 3000080;
56  char buf[BUFFSIZE]; // a buffer to temporarily park the data
57  size_t len = 0;
58  while( len = Read( buf, BUFFSIZE ) )
59  mem.AppendData( buf, len );
60 
61  wxMemoryInputStream localStream( mem.GetData(), mem.GetDataLen() );
62 
63  if ( handler->CanRead( localStream ) )
64 #else
65  if ( handler->CanRead( *m_streami ) )
66 #endif
67  {
68  handlerfound = handler;
69  break;
70  }
71  node = node->GetNext();
72  }
73  SeekI( 0 );
74  if ( handlerfound )
75  return ( wxBitmapType ) handlerfound->GetType();
76  return wxBITMAP_TYPE_ANY;
77 }
78 
79 bool a2dCanvasDocumentIOHandlerImageIn::CanLoad( a2dDocumentInputStream& stream, const wxObject* obj, wxClassInfo* docClassInfo )
80 {
81  if ( obj && !wxDynamicCast( obj, a2dCanvasDocument ) )
82  return false;
83 
84  if ( docClassInfo && m_docClassInfo && !docClassInfo->IsKindOf( m_docClassInfo ) )
85  return false;
86 
87  m_streami = &stream;
88 
89  wxImageHandler* handlerfound = NULL;
90  if ( m_type == wxBITMAP_TYPE_ANY )
91  {
92  long type = DetectImageType();
93  m_streami = NULL;
94  if ( type == wxBITMAP_TYPE_ANY )
95  return false;
96  }
97  else
98  {
99  long type = DetectImageType();
100  m_streami = NULL;
101  if ( m_type != type )
102  return false;
103  if ( !wxImage::FindHandler( m_type ) )
104  return false;
105  }
106 
107  m_streami = NULL;
108  return true;
109 }
110 
112 {
113  m_streami = &stream;
115 
116  bool oke = true;
117 
118  wxImageHandler* handler = NULL;
119  if ( m_type == wxBITMAP_TYPE_ANY )
120  {
121  wxBitmapType type = DetectImageType();
122  if ( type == wxBITMAP_TYPE_ANY )
123  return false;
124  handler = wxImage::FindHandler( type );
125  }
126  else
127  handler = wxImage::FindHandler( m_type );
128 
129  if ( !handler )
130  return false;
131 
132  try
133  {
134  InitializeLoad();
135 
136  wxImage image;
137 
138 #if !wxUSE_STD_IOSTREAM
139  if ( handler->LoadFile( &image, stream ) )
140  {
141  a2dImage* canvas_image = new a2dImage( image, 0, 0, image.GetWidth() * m_scale, image.GetHeight() * m_scale );
142  canvas_image->SetFill( *a2dTRANSPARENT_FILL );
143  canvas_image->SetStroke( *a2dTRANSPARENT_STROKE );
144  if ( !m_showObject )
145  m_doc->GetDrawing()->GetRootObject()->Append( canvas_image );
146  else
147  m_showObject->Append( canvas_image );
148  return true;
149  }
150 #else
151 
152 
153  wxMemoryBuffer mem;
154  const int BUFFSIZE = 3000080;
155  char buf[BUFFSIZE]; // a buffer to temporarily park the data
156  size_t len = 0;
157  while( len = Read( buf, BUFFSIZE ) )
158  mem.AppendData( buf, len );
159 
160  wxMemoryInputStream localStream( mem.GetData(), mem.GetDataLen() );
161  if ( handler->LoadFile( &image, localStream ) )
162  {
163  a2dImage* canvas_image = new a2dImage( image, 0, 0, image.GetWidth() * m_scale, image.GetHeight() * m_scale );
164  canvas_image->SetFill( *a2dTRANSPARENT_FILL );
165  canvas_image->SetStroke( *a2dTRANSPARENT_STROKE );
166  if ( !m_showObject )
167  m_doc->GetDrawing()->GetRootObject()->Append( canvas_image );
168  else
169  m_showObject->Append( canvas_image );
170  return true;
171  }
172 #endif
173 
174  }
175  catch ( ... )
176  {
177  oke = false;
178  a2dGeneralGlobals->ReportErrorF( a2dError_NotSpecified, _( "error in Image file reading\n %s \n" ), _( "" ) );
179  }
180 
181  ResetLoad();
182 
183  return oke;
184 }
185 
186 //----------------------------------------------------------------------------
187 // a2dCanvasDocumentIOHandlerImageOut
188 //----------------------------------------------------------------------------
189 
190 void a2dCanvasDocumentIOHandlerImageOut::SetViewRectangle( double minx, double miny, double maxx, double maxy )
191 {
192  m_viewBox = a2dBoundingBox( minx, miny, maxx, maxy );
193 }
194 
195 void a2dCanvasDocumentIOHandlerImageOut::SetBorder( wxUint16 border, bool percentual )
196 {
197  m_border = border;
198  m_borderpercentual = percentual;
199  if ( m_borderpercentual )
200  {
201  wxASSERT_MSG( m_border >= 0 && m_border <= 100 , wxT( "percentage must be >=0 and <= 100" ) );
202  }
203 }
204 
206 {
207  m_border = 0;
208  m_borderpercentual = true;
210  m_imageSize = wxSize( 0, 0 );
211  m_showObject = NULL;
212  m_yaxis = true;
213  m_drawer2D = NULL;
214  m_maxWidthHeight = 1000;
215 }
216 
218 {
219  if ( m_drawer2D )
220  delete m_drawer2D;
221 }
222 
224 {
225  if ( m_drawer2D )
226  delete m_drawer2D;
227 
228  m_drawer2D = drawer2d;
229  if ( m_drawer2D )
230  {
231  m_drawer2D->SetBufferSize( m_imageSize.GetWidth(), m_imageSize.GetHeight() );
232  }
233 }
234 
236 {
237  // if type is ANY, it will find the one liking the extension
238  wxImageHandler* handler = NULL;
239  handler = wxImage::FindHandler( m_type );
240  if ( !handler )
241  return false;
242 
244  return true;
245 }
246 
248 {
250  m_streamo = &stream;
251  //int isOK = stream.IsOk ();
252 
253  InitializeSave();
254 
255  bool res = false;
256 
257  wxImage image = RenderImage( m_doc );
258  //image.SaveFile( "c:/soft/aaaaaaaaaaap.png", wxBITMAP_TYPE_PNG );
259 
260  wxImageHandler* handler = wxImage::FindHandler( wxBITMAP_TYPE_ANY == m_type ? m_typeDetectedFromFilename : m_type );
261  if ( handler )
262  {
263 #if wxUSE_STD_IOSTREAM
264  wxMemoryOutputStream streamimage;
265  if (!image.SaveFile( streamimage, wxBITMAP_TYPE_ANY == m_type ? m_typeDetectedFromFilename : m_type))
266  return false;
267 
268  const int BUFFSIZE = 100;
269  char buf[BUFFSIZE]; // a buffer to temporarily park the data
270 
271  streamimage.SeekO(0);
272  wxStreamBuffer* theBuffer = streamimage.GetOutputStreamBuffer();
273  while ( theBuffer->Read( (void*) buf, BUFFSIZE ) > 0 )
274  m_streamo->write( buf, BUFFSIZE );
275 
276  res = true;
277 
278 #else //wxUSE_STD_IOSTREAM
279  res = image.SaveFile( *m_streamo, m_type );
280 #endif //wxUSE_STD_IOSTREAM
281  }
282  ResetSave();
283 
284  return res;
285 }
286 
288 {
289  m_doc = document;
290 
291  if ( !m_showObject )
292  {
294  }
295 
296  if ( !m_viewBox.GetValid() )
297  {
298  // view will be based on showobject its boundingbox
301  cworld.Invert();
302  m_viewBox.MapBbox( cworld );
303  }
304 
305  double w = m_viewBox.GetWidth();
306  double h = m_viewBox.GetHeight();
307 
308  if ( w == 0 )
309  w = 1000;
310  if ( h == 0 )
311  h = 1000;
312 
313  //virtual coordinates box its miminum X ( calculated to
314  double virt_minX;
315  //virtual coordinates box its miminum Y
316  double virt_minY;
317  //user units per pixel in x
318  double xpp;
319  //user units per pixel in y
320  double ypp;
321 
322 
323  if ( m_imageSize.GetWidth() == 0 || m_imageSize.GetHeight() == 0 )
324  {
325  m_maxWidthHeight = wxGetNumberFromUser( _( "Give Maximum pixel size in width and height:" ), _( "Pixels:" ), _( "Pixel" ), m_maxWidthHeight, 0, 50000 );
326  m_imageSizeCalc = wxSize( m_maxWidthHeight, m_maxWidthHeight );
327 
328  //first calculate an image size that fits the maximum size.
329  xpp = w / m_maxWidthHeight;
330  ypp = h / m_maxWidthHeight;
331  if ( xpp > ypp )
332  m_imageSizeCalc = wxSize( m_maxWidthHeight, ( int ) ( h / xpp ) );
333  else
334  m_imageSizeCalc = wxSize( ( int ) ( w / ypp ), m_maxWidthHeight );
335  }
336  else
338 
339  // the rect to show in world coordinates is calculated,
340  // such that it fits within the image.
341  double uppx;
342  double uppy;
343  int clientw = m_imageSizeCalc.GetWidth();
344  int clienth = m_imageSizeCalc.GetHeight();
345 
346  int border = m_border;
347  if ( m_borderpercentual )
348  border = ( int ) ( wxMin( clientw, clienth ) * m_border / 100.0 ) ;
349 
350  if ( clientw - border > 0 )
351  clientw = clientw - border;
352 
353  if ( clienth - border > 0 )
354  clienth = clienth - border;
355 
356  uppx = w / clientw;
357  uppy = h / clienth;
358  if ( uppx < uppy )
359  uppx = uppy;
360 
361  double middlexworld = m_viewBox.GetMinX() + w / 2.0;
362  double middleyworld = m_viewBox.GetMinY() + h / 2.0;
363  virt_minX = middlexworld - ( clientw + border ) / 2.0 * uppx;
364  virt_minY = middleyworld - ( clienth + border ) / 2.0 * uppx;
365  xpp = uppx;
366  ypp = uppx;
367 
368  if ( !m_drawer2D )
369  m_drawer2D = new a2dMemDcDrawer( m_imageSizeCalc.GetWidth(), m_imageSizeCalc.GetHeight() );
370  else
371  m_drawer2D->SetBufferSize( m_imageSizeCalc.GetWidth(), m_imageSizeCalc.GetHeight() );
372  m_drawer2D->SetMappingDeviceRect( 0, 0, m_imageSizeCalc.GetWidth(), m_imageSizeCalc.GetHeight() );
373 
374  a2dSmrtPtr<a2dDrawingPart> bitmapview = new a2dDrawingPart( m_imageSizeCalc.GetWidth(), m_imageSizeCalc.GetHeight(), m_drawer2D );
375  bitmapview->SetShowObjectAndRender( m_showObject );
376  bitmapview->GetDrawer2D()->SetYaxis( m_yaxis );
377 
378  // ensure all pending objects are reported
379  bitmapview->Update( a2dCANVIEW_UPDATE_OLDNEW );
380  bitmapview->GetDrawer2D()->SetMappingUpp( virt_minX , virt_minY, xpp, ypp );
382 
383  wxImage image = bitmapview->GetDrawer2D()->GetBuffer().ConvertToImage();
384 
385  bitmapview->SetDrawer2D( NULL, true );
386 
387  return image;
388 }
389 
390 
void SetMappingUpp(double vx1, double vy1, double xpp, double ypp)
Give the virtual size to be displayed, the mapping matrix will be calculated.
Definition: drawer2d.cpp:250
virtual void SetYaxis(bool up)
set if the Yaxis goes up or down
Definition: drawer2d.cpp:438
Display Part of a a2dDrawing, in which a2dCanvasObjects are shown.
Definition: drawer.h:470
double GetHeight() const
returns height of the boundingbox
Definition: bbox.cpp:334
wxBitmapType m_type
image type
Definition: imageioh.h:198
#define wxDynamicCast(obj, className)
Define wxDynamicCast so that it will give a compiler error for unrelated types.
Definition: gen.h:75
wxSize m_imageSizeCalc
calculate image size as set by user when m_imageSize = (0,0) else eqauls m_imageSize ...
Definition: imageioh.h:186
virtual void InitializeLoad()
Inits the handler for reading.
Definition: gen.cpp:4971
const a2dAffineMatrix & GetTransformMatrix() const
get the matrix used to position the object
Definition: canobj.h:500
virtual void InitializeSave()
Inits the handler for writing.
Definition: gen.cpp:5095
virtual void ResetSave()
Reset the object after saving.
Definition: gen.cpp:5101
a2dCanvasObject * GetRootObject() const
get the root object, which holds the objects in the document
Definition: drawing.h:521
wxBitmapType DetectImageType()
for the stream, detect what image type it contains
Definition: imageioh.cpp:42
bool CanSave(const wxObject *obj=NULL)
this handler can also save as CVG
Definition: imageioh.cpp:235
wxSize m_imageSize
image size that will be created.
Definition: imageioh.h:183
void SetMappingDeviceRect(int mapx, int mapy, int mapWidth, int mapHeight, bool remap=false)
to change the default mapping (to the complete buffer).
Definition: drawer2d.cpp:216
wxOutputStream a2dDocumentOutputStream
output stream based wxStreams
Definition: gen.h:3458
a2dDocumentInputStream * m_streami
file or other string stream containing the format to parse.
Definition: gen.h:3734
a2dCanvasDocumentIOHandlerImageOut(wxBitmapType type=wxBITMAP_TYPE_ANY)
Constructor.
Definition: imageioh.cpp:205
void Update(unsigned int how=(a2dCANVIEW_UPDATE_ALL|a2dCANVIEW_UPDATE_BLIT), wxObject *hintObject=NULL)
see OnUpdate
Definition: drawer.cpp:1744
This class implements drawing functions for wxDC based drawing.
Definition: dcdrawer.h:203
a2dDrawing * GetDrawing() const
get the root object, which holds the objects in the document.
Definition: candoc.h:418
void SetBorder(wxUint16 border, bool percentual=true)
leafs a border of this amount of pixels around the drawing
Definition: imageioh.cpp:195
a2dBoundingBox m_viewBox
viewing area in world coordinates to display on bitmap
Definition: imageioh.h:207
a2dIOHandlerStrIn & SeekI(wxFileOffset pos)
set stream at a position
Definition: gen.cpp:5021
a2dDrawer2D * m_drawer2D
the drawing engine to use
Definition: imageioh.h:177
a2dCanvasDocument * m_doc
the document to store/load the data found into
Definition: imageioh.h:180
virtual bool Load(a2dDocumentInputStream &stream, wxObject *doc)
load a complete document which contains an image
Definition: imageioh.cpp:111
bool GetValid() const
returns true if boundingbox is calculated properly and therefore its valid flag is set...
Definition: bbox.cpp:299
double GetMinX() const
get minimum X of the boundingbox
Definition: bbox.cpp:304
a2dCanvasDocument * m_doc
the document to store/load the data found into
Definition: imageioh.h:71
virtual bool Save(a2dDocumentOutputStream &stream, const wxObject *obj)
save a2dCanvasDocument as image
Definition: imageioh.cpp:247
wxBitmapType m_type
image type
Definition: imageioh.h:76
#define wxStaticCast(obj, className)
The wxWindows 2.4.2 wxStaticCast is buggy. It evaluates its argument twice.
Definition: gen.h:123
Drawing context abstraction.
Definition: drawer2d.h:177
a2dImage (will scale/rotate image when needed)
Definition: canimage.h:33
~a2dCanvasDocumentIOHandlerImageIn()
Destructor.
Definition: imageioh.cpp:38
A2DGENERALDLLEXP a2dSmrtPtr< a2dGeneralGlobal > a2dGeneralGlobals
a global pointer to get to global instance of important classes.
Definition: comevt.cpp:1148
void SetShowObjectAndRender(a2dCanvasObject *obj)
Used temporarely in rendering bitmas or in printing, to Set the show object and redraw the whole part...
Definition: drawer.cpp:3069
virtual bool CanLoad(a2dDocumentInputStream &stream, const wxObject *obj=NULL, wxClassInfo *docClassInfo=NULL)
test header of the file to see if it can be loaded
Definition: imageioh.cpp:79
a2dDrawer2D * GetDrawer2D()
get the internal m_drawer2D that is used for rendering the document
Definition: drawer.h:1125
void SetDrawer2D(a2dDrawer2D *drawer2d)
set the internal m_drawer2D to be used for rendering the document
Definition: imageioh.cpp:223
A 2x3 affine matrix class for 2D transformations.
Definition: afmatrix.h:53
wxClassInfo * m_docClassInfo
Run-time class information that allows document instances to be constructed dynamically.
Definition: gen.h:3737
wxInputStream a2dDocumentInputStream
input stream based wxStreams
Definition: gen.h:3456
a2dCanvasDocumentIOHandlerImageIn(wxBitmapType type=wxBITMAP_TYPE_ANY)
Constructor.
Definition: imageioh.cpp:29
void MapBbox(const a2dAffineMatrix &matrix)
Definition: bbox.cpp:445
void SetStroke(const wxColour &strokecolor, double width=0, a2dStrokeStyle style=a2dSTROKE_SOLID)
Set a stroke for the object which will be used instead of the layer stroke.
Definition: canobj.cpp:2924
virtual wxBitmap GetBuffer() const =0
Return the buffer as a bitmap.
Each a2dCanvasView needs to have a a2dCanvasDocument set in order to render data. ...
Definition: candoc.h:374
double GetWidth() const
returns width of the boundingbox
Definition: bbox.cpp:328
const a2dStroke * a2dTRANSPARENT_STROKE
global a2dStroke stock object for TRANSPARENT stroking
wxImage RenderImage(a2dCanvasDocument *document)
render the document into an image.
Definition: imageioh.cpp:287
const a2dError a2dError_NotSpecified
bool m_borderpercentual
border is not in pixel but a percentage of the smallest height/width
Definition: imageioh.h:195
The a2dBoundingBox class stores one a2dBoundingBox of a a2dCanvasObject.
Definition: bbox.h:39
bool Invert(void)
Invert matrix.
Definition: afmatrix.cpp:197
double GetMinY() const
get minimum Y of the boundingbox
Definition: bbox.cpp:310
virtual void SetBufferSize(int w, int h)=0
Change the buffer size.
void SetDrawer2D(a2dDrawer2D *drawer2d, bool noDelete=false)
set the internal m_drawer2D to be used for rendering the document
Definition: drawer.cpp:765
void Append(a2dCanvasObject *obj)
append a a2dCanvasObject to the childobjects
Definition: canobj.cpp:6224
int m_border
create a border in this ammount of pixels.
Definition: imageioh.h:192
a2dCanvasObject * m_showObject
render the document using this object as ShowObject.
Definition: imageioh.h:189
wxBitmapType m_typeDetectedFromFilename
image type as detected in CanSave(), wil be used in Save() if m_type is wxBITMAP_TYPE_ANY ...
Definition: imageioh.h:201
~a2dCanvasDocumentIOHandlerImageOut()
Destructor.
Definition: imageioh.cpp:217
a2dDocumentOutputStream * m_streamo
file or other string stream containing the format to output to.
Definition: gen.h:3825
virtual void ResetLoad()
Reset the handler after loading.
Definition: gen.cpp:4977
a2dBoundingBox & GetBbox()
get boundingbox in world coordinates exclusive stroke width relative to its parent ...
Definition: canobj.cpp:3175
void SetFill(const a2dFill &fill)
Set a fill for the object which will be used instead of the layer fill.
Definition: canobj.cpp:2874
bool m_yaxis
axis is up or down
Definition: imageioh.h:204
const a2dFill * a2dTRANSPARENT_FILL
global a2dFill stock object for TRANSPARENT filling
void SetViewRectangle(double minx, double miny, double maxx, double maxy)
Give the virtual size to be rendered to an image.
Definition: imageioh.cpp:190
imageioh.cpp Source File -- Sun Oct 12 2014 17:04:21 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation