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