Solved multiple memory leaks.
[wxWidgets.git] / samples / image / image.cpp
1 /*
2 * Program: image
3 *
4 * Author: Robert Roebling
5 *
6 * Copyright: (C) 1998, Robert Roebling
7 *
8 */
9
10 // For compilers that support precompilation, includes "wx/wx.h".
11 #include "wx/wxprec.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/image.h"
22 #include "wx/file.h"
23
24 #include "smile.xbm"
25 #include "smile.xpm"
26
27 // derived classes
28
29 class MyFrame;
30 class MyApp;
31
32 // MyCanvas
33
34 class MyCanvas: public wxScrolledWindow
35 {
36 public:
37 MyCanvas() {};
38 MyCanvas( wxWindow *parent, wxWindowID, const wxPoint &pos, const wxSize &size );
39 ~MyCanvas();
40 void OnPaint( wxPaintEvent &event );
41 void CreateAntiAliasedBitmap();
42
43 wxBitmap *my_horse_png;
44 wxBitmap *my_horse_jpeg;
45 wxBitmap *my_horse_gif;
46 wxBitmap *my_horse_bmp;
47 wxBitmap *my_horse_pcx;
48 wxBitmap *my_horse_pnm;
49 wxBitmap *my_horse_tiff;
50 wxBitmap *my_smile_xbm;
51 wxBitmap *my_square;
52 wxBitmap *my_anti;
53
54 protected:
55 wxBitmap m_bmpSmileXpm;
56 wxIcon m_iconSmileXpm;
57
58 private:
59 DECLARE_DYNAMIC_CLASS(MyCanvas)
60 DECLARE_EVENT_TABLE()
61 };
62
63 // MyFrame
64
65 class MyFrame: public wxFrame
66 {
67 public:
68 MyFrame();
69
70 void OnAbout( wxCommandEvent &event );
71 void OnQuit( wxCommandEvent &event );
72
73 MyCanvas *m_canvas;
74
75 private:
76 DECLARE_DYNAMIC_CLASS(MyFrame)
77 DECLARE_EVENT_TABLE()
78 };
79
80 // MyApp
81
82 class MyApp: public wxApp
83 {
84 public:
85 virtual bool OnInit();
86 };
87
88 // main program
89
90 IMPLEMENT_APP(MyApp)
91
92 // MyCanvas
93
94 IMPLEMENT_DYNAMIC_CLASS(MyCanvas, wxScrolledWindow)
95
96 BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
97 EVT_PAINT(MyCanvas::OnPaint)
98 END_EVENT_TABLE()
99
100 MyCanvas::MyCanvas( wxWindow *parent, wxWindowID id,
101 const wxPoint &pos, const wxSize &size )
102 : wxScrolledWindow( parent, id, pos, size, wxSUNKEN_BORDER )
103 #if !defined(__WINDOWS__) || wxUSE_XPM_IN_MSW
104 , m_bmpSmileXpm((const char **) smile_xpm)
105 , m_iconSmileXpm((const char **) smile_xpm)
106 #endif
107 {
108 my_horse_png = (wxBitmap*) NULL;
109 my_horse_jpeg = (wxBitmap*) NULL;
110 my_horse_gif = (wxBitmap*) NULL;
111 my_horse_bmp = (wxBitmap*) NULL;
112 my_horse_pcx = (wxBitmap*) NULL;
113 my_horse_pnm = (wxBitmap*) NULL;
114 my_horse_tiff = (wxBitmap*) NULL;
115 my_smile_xbm = (wxBitmap*) NULL;
116 my_square = (wxBitmap*) NULL;
117 my_anti = (wxBitmap*) NULL;
118
119 SetBackgroundColour(* wxWHITE);
120
121 wxBitmap bitmap( 100, 100 );
122
123 wxMemoryDC dc;
124 dc.SelectObject( bitmap );
125 dc.SetBrush( wxBrush( "orange", wxSOLID ) );
126 dc.SetPen( *wxBLACK_PEN );
127 dc.DrawRectangle( 0, 0, 100, 100 );
128 dc.SetBrush( *wxWHITE_BRUSH );
129 dc.DrawRectangle( 20, 20, 60, 60 );
130 dc.SelectObject( wxNullBitmap );
131
132 // try to find the directory with our images
133 wxString dir;
134 if ( wxFile::Exists("./horse.png") )
135 dir = "./";
136 else if ( wxFile::Exists("../horse.png") )
137 dir = "../";
138 else
139 wxLogWarning("Can't find image files in either '.' or '..'!");
140
141 wxImage image( bitmap );
142
143 #if wxUSE_LIBPNG
144 if ( !image.SaveFile( dir + wxString("test.png"), wxBITMAP_TYPE_PNG ))
145 wxLogError("Can't save file");
146
147 image.Destroy();
148
149 image.LoadFile( dir + wxString("test.png") );
150 my_square = new wxBitmap( image.ConvertToBitmap() );
151
152 image.Destroy();
153
154 if ( !image.LoadFile( dir + wxString("horse.png")) )
155 wxLogError("Can't load PNG image");
156 else
157 my_horse_png = new wxBitmap( image.ConvertToBitmap() );
158 #endif // wxUSE_LIBPNG
159
160 #if wxUSE_LIBJPEG
161 image.Destroy();
162
163 if ( !image.LoadFile( dir + wxString("horse.jpg")) )
164 wxLogError("Can't load JPG image");
165 else
166 my_horse_jpeg = new wxBitmap( image.ConvertToBitmap() );
167 #endif // wxUSE_LIBJPEG
168
169 #if wxUSE_GIF
170 image.Destroy();
171
172 if ( !image.LoadFile( dir + wxString("horse.gif")) )
173 wxLogError("Can't load GIF image");
174 else
175 my_horse_gif = new wxBitmap( image.ConvertToBitmap() );
176 #endif
177
178 #if wxUSE_PCX
179 image.Destroy();
180
181 if ( !image.LoadFile( dir + wxString("horse.pcx"), wxBITMAP_TYPE_PCX ) )
182 wxLogError("Can't load PCX image");
183 else
184 my_horse_pcx = new wxBitmap( image.ConvertToBitmap() );
185 #endif
186
187 image.Destroy();
188
189 if ( !image.LoadFile( dir + wxString("horse.bmp"), wxBITMAP_TYPE_BMP ) )
190 wxLogError("Can't load BMP image");
191 else
192 my_horse_bmp = new wxBitmap( image.ConvertToBitmap() );
193
194 #if wxUSE_PNM
195 image.Destroy();
196
197 if ( !image.LoadFile( dir + wxString("horse.pnm"), wxBITMAP_TYPE_PNM ) )
198 wxLogError("Can't load PNM image");
199 else
200 my_horse_pnm = new wxBitmap( image.ConvertToBitmap() );
201 #endif
202
203 #if wxUSE_LIBTIFF
204 image.Destroy();
205
206 if ( !image.LoadFile( dir + wxString("horse.tif"), wxBITMAP_TYPE_TIF ) )
207 wxLogError("Can't load TIFF image");
208 else
209 my_horse_tiff = new wxBitmap( image.ConvertToBitmap() );
210 #endif
211
212 CreateAntiAliasedBitmap();
213
214 my_smile_xbm = new wxBitmap( (const char*)smile_bits, smile_width,
215 smile_height, 1 );
216
217 #ifndef __WXGTK__
218 #if !defined(__WINDOWS__) || wxUSE_XPM_IN_MSW
219 // demonstrates XPM automatically using the mask when saving
220 if ( m_bmpSmileXpm.Ok() )
221 m_bmpSmileXpm.SaveFile("saved.xpm", wxBITMAP_TYPE_XPM);
222 #endif
223 #endif
224 }
225
226 MyCanvas::~MyCanvas()
227 {
228 delete my_horse_pnm;
229 delete my_horse_png;
230 delete my_horse_jpeg;
231 delete my_horse_gif;
232 delete my_horse_bmp;
233 delete my_horse_pcx;
234 delete my_horse_tiff;
235 delete my_smile_xbm;
236 delete my_square;
237 delete my_anti;
238 }
239
240 void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) )
241 {
242 wxPaintDC dc( this );
243 PrepareDC( dc );
244
245 dc.DrawText( "Loaded image", 30, 10 );
246 if (my_square && my_square->Ok()) dc.DrawBitmap( *my_square, 30, 30 );
247
248 dc.DrawText( "Drawn directly", 150, 10 );
249 dc.SetBrush( wxBrush( "orange", wxSOLID ) );
250 dc.SetPen( *wxBLACK_PEN );
251 dc.DrawRectangle( 150, 30, 100, 100 );
252 dc.SetBrush( *wxWHITE_BRUSH );
253 dc.DrawRectangle( 170, 50, 60, 60 );
254
255 if (my_anti && my_anti->Ok())
256 dc.DrawBitmap( *my_anti, 280, 30 );
257
258 dc.DrawText( "PNG handler", 30, 135 );
259 if (my_horse_png && my_horse_png->Ok())
260 {
261 dc.DrawBitmap( *my_horse_png, 30, 150 );
262 wxRect rect(0,0,100,100);
263 wxBitmap sub( my_horse_png->GetSubBitmap(rect) );
264 dc.DrawText( "GetSubBitmap()", 280, 190 );
265 dc.DrawBitmap( sub, 280, 210 );
266 }
267
268 dc.DrawText( "JPEG handler", 30, 365 );
269 if (my_horse_jpeg && my_horse_jpeg->Ok())
270 dc.DrawBitmap( *my_horse_jpeg, 30, 380 );
271
272 dc.DrawText( "GIF handler", 30, 595 );
273 if (my_horse_gif && my_horse_gif->Ok())
274 dc.DrawBitmap( *my_horse_gif, 30, 610 );
275
276 dc.DrawText( "PCX handler", 30, 825 );
277 if (my_horse_pcx && my_horse_pcx->Ok())
278 dc.DrawBitmap( *my_horse_pcx, 30, 840 );
279
280 dc.DrawText( "BMP handler", 30, 1055 );
281 if (my_horse_bmp && my_horse_bmp->Ok())
282 dc.DrawBitmap( *my_horse_bmp, 30, 1070 );
283
284 dc.DrawText( "PNM handler", 30, 1285 );
285 if (my_horse_pnm && my_horse_pnm->Ok())
286 dc.DrawBitmap( *my_horse_pnm, 30, 1300 );
287
288 dc.DrawText( "TIFF handler", 30, 1515 );
289 if (my_horse_tiff && my_horse_tiff->Ok())
290 dc.DrawBitmap( *my_horse_tiff, 30, 1530 );
291
292 if (my_smile_xbm && my_smile_xbm->Ok())
293 {
294 dc.DrawText( "XBM bitmap", 30, 1745 );
295 dc.DrawText( "(green on red)", 30, 1760 );
296 dc.SetTextForeground( "GREEN" );
297 dc.SetTextBackground( "RED" );
298 dc.DrawBitmap( *my_smile_xbm, 30, 1780 );
299
300 dc.SetTextForeground( "BLACK" );
301 dc.DrawText( "After wxImage conversion", 150, 1745 );
302 dc.DrawText( "(red on white)", 150, 1760 );
303 dc.SetTextForeground( "RED" );
304 wxImage i( *my_smile_xbm );
305 i.SetMaskColour( 255, 255, 255 );
306 i.Replace( 0, 0, 0,
307 wxRED_PEN->GetColour().Red(),
308 wxRED_PEN->GetColour().Green(),
309 wxRED_PEN->GetColour().Blue() );
310 dc.DrawBitmap( i.ConvertToBitmap(), 150, 1780, TRUE );
311 dc.SetTextForeground( "BLACK" );
312 }
313
314
315 wxBitmap mono( 60,50,1 );
316 wxMemoryDC memdc;
317 memdc.SelectObject( mono );
318 memdc.SetPen( *wxBLACK_PEN );
319 memdc.SetBrush( *wxWHITE_BRUSH );
320 memdc.DrawRectangle( 0,0,60,50 );
321 memdc.SetTextForeground( *wxBLACK );
322 memdc.DrawText( "Hi!", 5, 5 );
323 memdc.SetBrush( *wxBLACK_BRUSH );
324 memdc.DrawRectangle( 33,5,20,20 );
325 memdc.SetPen( *wxRED_PEN );
326 memdc.DrawLine( 5, 42, 50, 42 );
327 memdc.SelectObject( wxNullBitmap );
328
329 if (mono.Ok())
330 {
331 dc.DrawText( "Mono bitmap", 30, 1865 );
332 dc.DrawText( "(red on green)", 30, 1880 );
333 dc.SetTextForeground( "RED" );
334 dc.SetTextBackground( "GREEN" );
335 dc.DrawBitmap( mono, 30, 1900 );
336
337 dc.SetTextForeground( "BLACK" );
338 dc.DrawText( "After wxImage conversion", 150, 1865 );
339 dc.DrawText( "(red on white)", 150, 1880 );
340 dc.SetTextForeground( "RED" );
341 wxImage i( mono );
342 i.SetMaskColour( 255,255,255 );
343 i.Replace( 0,0,0,
344 wxRED_PEN->GetColour().Red(),
345 wxRED_PEN->GetColour().Green(),
346 wxRED_PEN->GetColour().Blue() );
347 dc.DrawBitmap( i.ConvertToBitmap(), 150, 1900, TRUE );
348 dc.SetTextForeground( "BLACK" );
349 }
350
351 dc.DrawText("XPM bitmap", 30, 2000);
352 if ( m_bmpSmileXpm.Ok() )
353 {
354 dc.DrawBitmap(m_bmpSmileXpm, 30, 2020, TRUE);
355 }
356
357 dc.DrawText("XPM icon", 150, 2000);
358 if ( m_iconSmileXpm.Ok() )
359 {
360 dc.DrawIcon(m_iconSmileXpm, 150, 2020);
361 }
362 }
363
364 void MyCanvas::CreateAntiAliasedBitmap()
365 {
366 wxBitmap bitmap( 300, 300 );
367
368 wxMemoryDC dc;
369
370 dc.SelectObject( bitmap );
371
372 dc.Clear();
373
374 dc.SetFont( wxFont( 24, wxDECORATIVE, wxNORMAL, wxNORMAL) );
375 dc.SetTextForeground( "RED" );
376 dc.DrawText( "This is anti-aliased Text.", 20, 20 );
377 dc.DrawText( "And a Rectangle.", 20, 60 );
378
379 dc.SetBrush( *wxRED_BRUSH );
380 dc.SetPen( *wxTRANSPARENT_PEN );
381 dc.DrawRoundedRectangle( 20, 100, 200, 180, 20 );
382
383 wxImage original( bitmap );
384 wxImage anti( 150, 150 );
385
386 /* This is quite slow, but safe. Use wxImage::GetData() for speed instead. */
387
388 for (int y = 1; y < 149; y++)
389 for (int x = 1; x < 149; x++)
390 {
391 int red = original.GetRed( x*2, y*2 ) +
392 original.GetRed( x*2-1, y*2 ) +
393 original.GetRed( x*2, y*2+1 ) +
394 original.GetRed( x*2+1, y*2+1 );
395 red = red/4;
396
397 int green = original.GetGreen( x*2, y*2 ) +
398 original.GetGreen( x*2-1, y*2 ) +
399 original.GetGreen( x*2, y*2+1 ) +
400 original.GetGreen( x*2+1, y*2+1 );
401 green = green/4;
402
403 int blue = original.GetBlue( x*2, y*2 ) +
404 original.GetBlue( x*2-1, y*2 ) +
405 original.GetBlue( x*2, y*2+1 ) +
406 original.GetBlue( x*2+1, y*2+1 );
407 blue = blue/4;
408 anti.SetRGB( x, y, red, green, blue );
409 }
410 my_anti = new wxBitmap( anti.ConvertToBitmap() );
411 }
412
413 // MyFrame
414
415 const int ID_QUIT = 108;
416 const int ID_ABOUT = 109;
417
418 IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
419
420 BEGIN_EVENT_TABLE(MyFrame,wxFrame)
421 EVT_MENU (ID_ABOUT, MyFrame::OnAbout)
422 EVT_MENU (ID_QUIT, MyFrame::OnQuit)
423 END_EVENT_TABLE()
424
425 MyFrame::MyFrame()
426 : wxFrame( (wxFrame *)NULL, -1, "wxImage sample",
427 wxPoint(20,20), wxSize(470,360) )
428 {
429 wxMenu *file_menu = new wxMenu();
430 file_menu->Append( ID_ABOUT, "&About...");
431 file_menu->Append( ID_QUIT, "E&xit");
432
433 wxMenuBar *menu_bar = new wxMenuBar();
434 menu_bar->Append(file_menu, "&File");
435
436 SetMenuBar( menu_bar );
437
438 CreateStatusBar(2);
439 int widths[] = { -1, 100 };
440 SetStatusWidths( 2, widths );
441
442 m_canvas = new MyCanvas( this, -1, wxPoint(0,0), wxSize(10,10) );
443
444 // 500 width * 2100 height
445 m_canvas->SetScrollbars( 10, 10, 50, 220 );
446 }
447
448 void MyFrame::OnQuit( wxCommandEvent &WXUNUSED(event) )
449 {
450 Close( TRUE );
451 }
452
453 void MyFrame::OnAbout( wxCommandEvent &WXUNUSED(event) )
454 {
455 (void)wxMessageBox( "wxImage demo\n"
456 "Robert Roebling (c) 1998,2000",
457 "About wxImage Demo", wxICON_INFORMATION | wxOK );
458 }
459
460 //-----------------------------------------------------------------------------
461 // MyApp
462 //-----------------------------------------------------------------------------
463
464 bool MyApp::OnInit()
465 {
466 #if wxUSE_LIBPNG
467 wxImage::AddHandler( new wxPNGHandler );
468 #endif
469
470 #if wxUSE_LIBJPEG
471 wxImage::AddHandler( new wxJPEGHandler );
472 #endif
473
474 #if wxUSE_LIBTIFF
475 wxImage::AddHandler( new wxTIFFHandler );
476 #endif
477
478 #if wxUSE_GIF
479 wxImage::AddHandler( new wxGIFHandler );
480 #endif
481
482 #if wxUSE_PCX
483 wxImage::AddHandler( new wxPCXHandler );
484 #endif
485
486 #if wxUSE_PNM
487 wxImage::AddHandler( new wxPNMHandler );
488 #endif
489
490 wxFrame *frame = new MyFrame();
491 frame->Show( TRUE );
492
493 return TRUE;
494 }
495