]> git.saurik.com Git - wxWidgets.git/blob - samples/image/image.cpp
GetPendingEditedValue() -> GetUncommittedPropertyValue() (more consistent API naming...
[wxWidgets.git] / samples / image / image.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: samples/image/image.cpp
3 // Purpose: sample showing operations with wxImage
4 // Author: Robert Roebling
5 // Modified by:
6 // Created: 1998
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998-2005 Robert Roebling
9 // License: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx/wx.h".
13 #include "wx/wxprec.h"
14
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18
19 #ifndef WX_PRECOMP
20 #include "wx/wx.h"
21 #endif
22
23 #include "wx/image.h"
24 #include "wx/file.h"
25 #include "wx/filename.h"
26 #include "wx/mstream.h"
27 #include "wx/wfstream.h"
28 #include "wx/quantize.h"
29
30 #if wxUSE_CLIPBOARD
31 #include "wx/dataobj.h"
32 #include "wx/clipbrd.h"
33 #endif // wxUSE_CLIPBOARD
34
35 #include "smile.xbm"
36 #include "smile.xpm"
37
38 #if defined(__WXMSW__)
39 #ifdef wxHAVE_RAW_BITMAP
40 #include "wx/rawbmp.h"
41 #endif
42 #endif
43
44 #if defined(__WXMAC__) || defined(__WXGTK__)
45 #define wxHAVE_RAW_BITMAP
46 #include "wx/rawbmp.h"
47 #endif
48
49 // derived classes
50
51 class MyFrame;
52 class MyApp;
53
54 // MyCanvas
55
56 class MyCanvas: public wxScrolledWindow
57 {
58 public:
59 MyCanvas( wxWindow *parent, wxWindowID, const wxPoint &pos, const wxSize &size );
60 ~MyCanvas();
61 void OnPaint( wxPaintEvent &event );
62 void CreateAntiAliasedBitmap();
63
64 wxBitmap my_horse_png;
65 wxBitmap my_horse_jpeg;
66 wxBitmap my_horse_gif;
67 wxBitmap my_horse_bmp;
68 wxBitmap my_horse_bmp2;
69 wxBitmap my_horse_pcx;
70 wxBitmap my_horse_pnm;
71 wxBitmap my_horse_tiff;
72 wxBitmap my_horse_tga;
73 wxBitmap my_horse_xpm;
74 wxBitmap my_horse_ico32;
75 wxBitmap my_horse_ico16;
76 wxBitmap my_horse_ico;
77 wxBitmap my_horse_cur;
78
79 wxBitmap my_smile_xbm;
80 wxBitmap my_square;
81 wxBitmap my_anti;
82
83 wxBitmap my_horse_asciigrey_pnm;
84 wxBitmap my_horse_rawgrey_pnm;
85
86 wxBitmap colorized_horse_jpeg;
87 wxBitmap my_cmyk_jpeg;
88
89 wxBitmap my_toucan;
90 wxBitmap my_toucan_flipped_horiz;
91 wxBitmap my_toucan_flipped_vert;
92 wxBitmap my_toucan_flipped_both;
93 wxBitmap my_toucan_grey;
94 wxBitmap my_toucan_head;
95 wxBitmap my_toucan_scaled_normal;
96 wxBitmap my_toucan_scaled_high;
97 wxBitmap my_toucan_blur;
98
99 int xH, yH ;
100 int m_ani_images;
101 wxBitmap *my_horse_ani;
102
103 private:
104 wxBitmap m_bmpSmileXpm;
105 wxIcon m_iconSmileXpm;
106
107 DECLARE_EVENT_TABLE()
108 };
109
110
111 // MyFrame
112
113
114 class MyFrame: public wxFrame
115 {
116 public:
117 MyFrame();
118
119 void OnAbout( wxCommandEvent &event );
120 void OnNewFrame( wxCommandEvent &event );
121 void OnImageInfo( wxCommandEvent &event );
122 #ifdef wxHAVE_RAW_BITMAP
123 void OnTestRawBitmap( wxCommandEvent &event );
124 #endif // wxHAVE_RAW_BITMAP
125 void OnQuit( wxCommandEvent &event );
126
127 #if wxUSE_CLIPBOARD
128 void OnCopy(wxCommandEvent& event);
129 void OnPaste(wxCommandEvent& event);
130 #endif // wxUSE_CLIPBOARD
131
132 MyCanvas *m_canvas;
133
134 private:
135 // ask user for the file name and try to load an image from it
136 //
137 // return the file path on success, empty string if we failed to load the
138 // image or were cancelled by user
139 static wxString LoadUserImage(wxImage& image);
140
141
142 DECLARE_DYNAMIC_CLASS(MyFrame)
143 DECLARE_EVENT_TABLE()
144 };
145
146 // ----------------------------------------------------------------------------
147 // Frame used for showing a standalone image
148 // ----------------------------------------------------------------------------
149
150 enum
151 {
152 ID_ROTATE_LEFT = 100,
153 ID_ROTATE_RIGHT,
154 ID_RESIZE
155 };
156
157 class MyImageFrame : public wxFrame
158 {
159 public:
160 MyImageFrame(wxFrame *parent, const wxString& desc, const wxBitmap& bitmap)
161 : wxFrame(parent, wxID_ANY,
162 wxString::Format(_T("Image from %s"), desc.c_str()),
163 wxDefaultPosition, wxDefaultSize,
164 wxDEFAULT_FRAME_STYLE | wxFULL_REPAINT_ON_RESIZE),
165 m_bitmap(bitmap)
166 {
167 wxMenu *menu = new wxMenu;
168 menu->Append(wxID_SAVE);
169 menu->AppendSeparator();
170 menu->Append(ID_RESIZE, _T("&Fit to window\tCtrl-F"));
171 menu->AppendSeparator();
172 menu->Append(ID_ROTATE_LEFT, _T("Rotate &left\tCtrl-L"));
173 menu->Append(ID_ROTATE_RIGHT, _T("Rotate &right\tCtrl-R"));
174
175 wxMenuBar *mbar = new wxMenuBar;
176 mbar->Append(menu, _T("&Image"));
177 SetMenuBar(mbar);
178
179 CreateStatusBar();
180
181 SetClientSize(bitmap.GetWidth(), bitmap.GetHeight());
182
183 UpdateStatusBar();
184 }
185
186 void OnEraseBackground(wxEraseEvent& WXUNUSED(event))
187 {
188 // do nothing here to be able to see how transparent images are shown
189 }
190
191 void OnPaint(wxPaintEvent& WXUNUSED(event))
192 {
193 wxPaintDC dc(this);
194 const wxSize size = GetClientSize();
195 dc.DrawBitmap(m_bitmap,
196 (size.x - m_bitmap.GetWidth())/2,
197 (size.y - m_bitmap.GetHeight())/2,
198 true /* use mask */);
199 }
200
201 void OnSave(wxCommandEvent& WXUNUSED(event))
202 {
203 #if wxUSE_FILEDLG
204 wxImage image = m_bitmap.ConvertToImage();
205
206 wxString savefilename = wxFileSelector( wxT("Save Image"),
207 wxEmptyString,
208 wxEmptyString,
209 (const wxChar *)NULL,
210 wxT("BMP files (*.bmp)|*.bmp|")
211 wxT("PNG files (*.png)|*.png|")
212 wxT("JPEG files (*.jpg)|*.jpg|")
213 wxT("GIF files (*.gif)|*.gif|")
214 wxT("TIFF files (*.tif)|*.tif|")
215 wxT("PCX files (*.pcx)|*.pcx|")
216 wxT("ICO files (*.ico)|*.ico|")
217 wxT("CUR files (*.cur)|*.cur"),
218 wxFD_SAVE,
219 this);
220
221 if ( savefilename.empty() )
222 return;
223
224 wxString extension;
225 wxFileName::SplitPath(savefilename, NULL, NULL, &extension);
226
227 bool saved = false;
228 if ( extension == _T("bmp") )
229 {
230 static const int bppvalues[] =
231 {
232 wxBMP_1BPP,
233 wxBMP_1BPP_BW,
234 wxBMP_4BPP,
235 wxBMP_8BPP,
236 wxBMP_8BPP_GREY,
237 wxBMP_8BPP_RED,
238 wxBMP_8BPP_PALETTE,
239 wxBMP_24BPP
240 };
241
242 const wxString bppchoices[] =
243 {
244 _T("1 bpp color"),
245 _T("1 bpp B&W"),
246 _T("4 bpp color"),
247 _T("8 bpp color"),
248 _T("8 bpp greyscale"),
249 _T("8 bpp red"),
250 _T("8 bpp own palette"),
251 _T("24 bpp")
252 };
253
254 int bppselection = wxGetSingleChoiceIndex(_T("Set BMP BPP"),
255 _T("Image sample: save file"),
256 WXSIZEOF(bppchoices),
257 bppchoices,
258 this);
259 if ( bppselection != -1 )
260 {
261 int format = bppvalues[bppselection];
262 image.SetOption(wxIMAGE_OPTION_BMP_FORMAT, format);
263
264 if ( format == wxBMP_8BPP_PALETTE )
265 {
266 unsigned char *cmap = new unsigned char [256];
267 for ( int i = 0; i < 256; i++ )
268 cmap[i] = (unsigned char)i;
269 image.SetPalette(wxPalette(256, cmap, cmap, cmap));
270
271 delete[] cmap;
272 }
273 }
274 }
275 else if ( extension == _T("png") )
276 {
277 static const int pngvalues[] =
278 {
279 wxPNG_TYPE_COLOUR,
280 wxPNG_TYPE_COLOUR,
281 wxPNG_TYPE_GREY,
282 wxPNG_TYPE_GREY,
283 wxPNG_TYPE_GREY_RED,
284 wxPNG_TYPE_GREY_RED,
285 };
286
287 const wxString pngchoices[] =
288 {
289 _T("Colour 8bpp"),
290 _T("Colour 16bpp"),
291 _T("Grey 8bpp"),
292 _T("Grey 16bpp"),
293 _T("Grey red 8bpp"),
294 _T("Grey red 16bpp"),
295 };
296
297 int sel = wxGetSingleChoiceIndex(_T("Set PNG format"),
298 _T("Image sample: save file"),
299 WXSIZEOF(pngchoices),
300 pngchoices,
301 this);
302 if ( sel != -1 )
303 {
304 image.SetOption(wxIMAGE_OPTION_PNG_FORMAT, pngvalues[sel]);
305 image.SetOption(wxIMAGE_OPTION_PNG_BITDEPTH, sel % 2 ? 16 : 8);
306 }
307 }
308 else if ( extension == _T("cur") )
309 {
310 image.Rescale(32,32);
311 image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_X, 0);
312 image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y, 0);
313 // This shows how you can save an image with explicitly
314 // specified image format:
315 saved = image.SaveFile(savefilename, wxBITMAP_TYPE_CUR);
316 }
317
318 if ( !saved )
319 {
320 // This one guesses image format from filename extension
321 // (it may fail if the extension is not recognized):
322 image.SaveFile(savefilename);
323 }
324 #endif // wxUSE_FILEDLG
325 }
326
327 void OnResize(wxCommandEvent& WXUNUSED(event))
328 {
329 wxImage img(m_bitmap.ConvertToImage());
330
331 const wxSize size = GetClientSize();
332 img.Rescale(size.x, size.y, wxIMAGE_QUALITY_HIGH);
333 m_bitmap = wxBitmap(img);
334
335 UpdateStatusBar();
336 Refresh();
337 }
338
339 void OnRotate(wxCommandEvent& event)
340 {
341 double angle = 5;
342 if ( event.GetId() == ID_ROTATE_LEFT )
343 angle = -angle;
344
345 wxImage img(m_bitmap.ConvertToImage());
346 img = img.Rotate(angle, wxPoint(img.GetWidth() / 2, img.GetHeight() / 2));
347 if ( !img.Ok() )
348 {
349 wxLogWarning(_T("Rotation failed"));
350 return;
351 }
352
353 m_bitmap = wxBitmap(img);
354
355 UpdateStatusBar();
356 Refresh();
357 }
358
359 private:
360 void UpdateStatusBar()
361 {
362 wxLogStatus(this, _T("Image size: (%d, %d)"),
363 m_bitmap.GetWidth(),
364 m_bitmap.GetHeight());
365 }
366
367 wxBitmap m_bitmap;
368
369 DECLARE_EVENT_TABLE()
370 };
371
372 #ifdef wxHAVE_RAW_BITMAP
373
374 #include "wx/rawbmp.h"
375
376 class MyRawBitmapFrame : public wxFrame
377 {
378 public:
379 enum
380 {
381 BORDER = 15,
382 SIZE = 150,
383 REAL_SIZE = SIZE - 2*BORDER
384 };
385
386 MyRawBitmapFrame(wxFrame *parent)
387 : wxFrame(parent, wxID_ANY, _T("Raw bitmaps (how exciting)")),
388 m_bitmap(SIZE, SIZE, 24),
389 m_alphaBitmap(SIZE, SIZE, 32)
390 {
391 SetClientSize(SIZE, SIZE*2+25);
392
393 InitAlphaBitmap();
394 InitBitmap();
395
396 }
397
398 void InitAlphaBitmap()
399 {
400 // First, clear the whole bitmap by making it alpha
401 {
402 wxAlphaPixelData data( m_alphaBitmap, wxPoint(0,0), wxSize(SIZE, SIZE) );
403 if ( !data )
404 {
405 wxLogError(_T("Failed to gain raw access to bitmap data"));
406 return;
407 }
408 wxAlphaPixelData::Iterator p(data);
409 for ( int y = 0; y < SIZE; ++y )
410 {
411 wxAlphaPixelData::Iterator rowStart = p;
412 for ( int x = 0; x < SIZE; ++x )
413 {
414 p.Alpha() = 0;
415 ++p; // same as p.OffsetX(1)
416 }
417 p = rowStart;
418 p.OffsetY(data, 1);
419 }
420 }
421
422 // Then, draw colourful alpha-blended stripes
423 wxAlphaPixelData data(m_alphaBitmap, wxPoint(BORDER, BORDER),
424 wxSize(REAL_SIZE, REAL_SIZE));
425 if ( !data )
426 {
427 wxLogError(_T("Failed to gain raw access to bitmap data"));
428 return;
429 }
430
431 wxAlphaPixelData::Iterator p(data);
432
433 for ( int y = 0; y < REAL_SIZE; ++y )
434 {
435 wxAlphaPixelData::Iterator rowStart = p;
436
437 int r = y < REAL_SIZE/3 ? 255 : 0,
438 g = (REAL_SIZE/3 <= y) && (y < 2*(REAL_SIZE/3)) ? 255 : 0,
439 b = 2*(REAL_SIZE/3) <= y ? 255 : 0;
440
441 for ( int x = 0; x < REAL_SIZE; ++x )
442 {
443 // note that RGB must be premultiplied by alpha
444 unsigned a = (wxAlphaPixelData::Iterator::ChannelType)((x*255.)/REAL_SIZE);
445 p.Red() = r * a / 256;
446 p.Green() = g * a / 256;
447 p.Blue() = b * a / 256;
448 p.Alpha() = a;
449
450 ++p; // same as p.OffsetX(1)
451 }
452
453 p = rowStart;
454 p.OffsetY(data, 1);
455 }
456 }
457
458 void InitBitmap()
459 {
460 // draw some colourful stripes without alpha
461 wxNativePixelData data(m_bitmap);
462 if ( !data )
463 {
464 wxLogError(_T("Failed to gain raw access to bitmap data"));
465 return;
466 }
467
468 wxNativePixelData::Iterator p(data);
469 for ( int y = 0; y < SIZE; ++y )
470 {
471 wxNativePixelData::Iterator rowStart = p;
472
473 int r = y < SIZE/3 ? 255 : 0,
474 g = (SIZE/3 <= y) && (y < 2*(SIZE/3)) ? 255 : 0,
475 b = 2*(SIZE/3) <= y ? 255 : 0;
476
477 for ( int x = 0; x < SIZE; ++x )
478 {
479 p.Red() = r;
480 p.Green() = g;
481 p.Blue() = b;
482 ++p; // same as p.OffsetX(1)
483 }
484
485 p = rowStart;
486 p.OffsetY(data, 1);
487 }
488 }
489
490 void OnPaint(wxPaintEvent& WXUNUSED(event))
491 {
492 wxPaintDC dc( this );
493 dc.DrawText(_T("This is alpha and raw bitmap test"), 0, BORDER);
494 dc.DrawText(_T("This is alpha and raw bitmap test"), 0, SIZE/2 - BORDER);
495 dc.DrawText(_T("This is alpha and raw bitmap test"), 0, SIZE - 2*BORDER);
496 dc.DrawBitmap( m_alphaBitmap, 0, 0, true /* use mask */ );
497
498 dc.DrawText(_T("Raw bitmap access without alpha"), 0, SIZE+5);
499 dc.DrawBitmap( m_bitmap, 0, SIZE+5+dc.GetCharHeight());
500 }
501
502 private:
503 wxBitmap m_bitmap;
504 wxBitmap m_alphaBitmap;
505
506 DECLARE_EVENT_TABLE()
507 };
508
509 #endif // wxHAVE_RAW_BITMAP
510
511 // MyApp
512
513 class MyApp: public wxApp
514 {
515 public:
516 virtual bool OnInit();
517 };
518
519 // main program
520
521 IMPLEMENT_APP(MyApp)
522
523 // MyCanvas
524
525 BEGIN_EVENT_TABLE(MyImageFrame, wxFrame)
526 EVT_ERASE_BACKGROUND(MyImageFrame::OnEraseBackground)
527 EVT_PAINT(MyImageFrame::OnPaint)
528
529 EVT_MENU(wxID_SAVE, MyImageFrame::OnSave)
530 EVT_MENU_RANGE(ID_ROTATE_LEFT, ID_ROTATE_RIGHT, MyImageFrame::OnRotate)
531 EVT_MENU(ID_RESIZE, MyImageFrame::OnResize)
532 END_EVENT_TABLE()
533
534 #ifdef wxHAVE_RAW_BITMAP
535
536 BEGIN_EVENT_TABLE(MyRawBitmapFrame, wxFrame)
537 EVT_PAINT(MyRawBitmapFrame::OnPaint)
538 END_EVENT_TABLE()
539
540 #endif // wxHAVE_RAW_BITMAP
541
542 BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
543 EVT_PAINT(MyCanvas::OnPaint)
544 END_EVENT_TABLE()
545
546 MyCanvas::MyCanvas( wxWindow *parent, wxWindowID id,
547 const wxPoint &pos, const wxSize &size )
548 : wxScrolledWindow( parent, id, pos, size, wxSUNKEN_BORDER )
549 , m_bmpSmileXpm(smile_xpm)
550 , m_iconSmileXpm(smile_xpm)
551 {
552 my_horse_ani = NULL;
553 m_ani_images = 0 ;
554
555 SetBackgroundColour(* wxWHITE);
556
557 wxBitmap bitmap( 100, 100 );
558
559 wxMemoryDC dc;
560 dc.SelectObject( bitmap );
561 dc.SetBrush( wxBrush( wxT("orange"), wxSOLID ) );
562 dc.SetPen( *wxBLACK_PEN );
563 dc.DrawRectangle( 0, 0, 100, 100 );
564 dc.SetBrush( *wxWHITE_BRUSH );
565 dc.DrawRectangle( 20, 20, 60, 60 );
566 dc.SelectObject( wxNullBitmap );
567
568 // try to find the directory with our images
569 wxString dir;
570 if ( wxFile::Exists(wxT("./horse.png")) )
571 dir = wxT("./");
572 else if ( wxFile::Exists(wxT("../horse.png")) )
573 dir = wxT("../");
574 else
575 wxLogWarning(wxT("Can't find image files in either '.' or '..'!"));
576
577 wxImage image = bitmap.ConvertToImage();
578
579 #if wxUSE_LIBPNG
580 if ( !image.SaveFile( dir + _T("test.png"), wxBITMAP_TYPE_PNG ))
581 wxLogError(wxT("Can't save file"));
582
583 image.Destroy();
584
585 if ( image.LoadFile( dir + _T("test.png") ) )
586 my_square = wxBitmap( image );
587
588 image.Destroy();
589
590 if ( !image.LoadFile( dir + _T("horse.png")) )
591 wxLogError(wxT("Can't load PNG image"));
592 else
593 my_horse_png = wxBitmap( image );
594
595 if ( !image.LoadFile( dir + _T("toucan.png")) )
596 wxLogError(wxT("Can't load PNG image"));
597 else
598 my_toucan = wxBitmap(image);
599
600 my_toucan_flipped_horiz = wxBitmap(image.Mirror(true));
601 my_toucan_flipped_vert = wxBitmap(image.Mirror(false));
602 my_toucan_flipped_both = wxBitmap(image.Mirror(true).Mirror(false));
603 my_toucan_grey = wxBitmap(image.ConvertToGreyscale());
604 my_toucan_head = wxBitmap(image.GetSubImage(wxRect(40, 7, 80, 60)));
605 my_toucan_scaled_normal = wxBitmap(image.Scale(110,90,wxIMAGE_QUALITY_NORMAL));
606 my_toucan_scaled_high = wxBitmap(image.Scale(110,90,wxIMAGE_QUALITY_HIGH));
607 my_toucan_blur = wxBitmap(image.Blur(10));
608
609 #endif // wxUSE_LIBPNG
610
611 #if wxUSE_LIBJPEG
612 image.Destroy();
613
614 if ( !image.LoadFile( dir + _T("horse.jpg")) )
615 wxLogError(wxT("Can't load JPG image"));
616 else
617 {
618 my_horse_jpeg = wxBitmap( image );
619
620 // Colorize by rotating green hue to red
621 wxImage::HSVValue greenHSV = wxImage::RGBtoHSV(wxImage::RGBValue(0, 255, 0));
622 wxImage::HSVValue redHSV = wxImage::RGBtoHSV(wxImage::RGBValue(255, 0, 0));
623 image.RotateHue(redHSV.hue - greenHSV.hue);
624 colorized_horse_jpeg = wxBitmap( image );
625 }
626
627 if ( !image.LoadFile( dir + _T("cmyk.jpg")) )
628 wxLogError(_T("Can't load CMYK JPG image"));
629 else
630 my_cmyk_jpeg = wxBitmap(image);
631 #endif // wxUSE_LIBJPEG
632
633 #if wxUSE_GIF
634 image.Destroy();
635
636 if ( !image.LoadFile( dir + _T("horse.gif" )) )
637 wxLogError(wxT("Can't load GIF image"));
638 else
639 my_horse_gif = wxBitmap( image );
640 #endif
641
642 #if wxUSE_PCX
643 image.Destroy();
644
645 if ( !image.LoadFile( dir + _T("horse.pcx"), wxBITMAP_TYPE_PCX ) )
646 wxLogError(wxT("Can't load PCX image"));
647 else
648 my_horse_pcx = wxBitmap( image );
649 #endif
650
651 image.Destroy();
652
653 if ( !image.LoadFile( dir + _T("horse.bmp"), wxBITMAP_TYPE_BMP ) )
654 wxLogError(wxT("Can't load BMP image"));
655 else
656 my_horse_bmp = wxBitmap( image );
657
658 #if wxUSE_XPM
659 image.Destroy();
660
661 if ( !image.LoadFile( dir + _T("horse.xpm"), wxBITMAP_TYPE_XPM ) )
662 wxLogError(wxT("Can't load XPM image"));
663 else
664 my_horse_xpm = wxBitmap( image );
665
666 if ( !image.SaveFile( dir + _T("test.xpm"), wxBITMAP_TYPE_XPM ))
667 wxLogError(wxT("Can't save file"));
668 #endif
669
670 #if wxUSE_PNM
671 image.Destroy();
672
673 if ( !image.LoadFile( dir + _T("horse.pnm"), wxBITMAP_TYPE_PNM ) )
674 wxLogError(wxT("Can't load PNM image"));
675 else
676 my_horse_pnm = wxBitmap( image );
677
678 image.Destroy();
679
680 if ( !image.LoadFile( dir + _T("horse_ag.pnm"), wxBITMAP_TYPE_PNM ) )
681 wxLogError(wxT("Can't load PNM image"));
682 else
683 my_horse_asciigrey_pnm = wxBitmap( image );
684
685 image.Destroy();
686
687 if ( !image.LoadFile( dir + _T("horse_rg.pnm"), wxBITMAP_TYPE_PNM ) )
688 wxLogError(wxT("Can't load PNM image"));
689 else
690 my_horse_rawgrey_pnm = wxBitmap( image );
691 #endif
692
693 #if wxUSE_LIBTIFF
694 image.Destroy();
695
696 if ( !image.LoadFile( dir + _T("horse.tif"), wxBITMAP_TYPE_TIF ) )
697 wxLogError(wxT("Can't load TIFF image"));
698 else
699 my_horse_tiff = wxBitmap( image );
700 #endif
701
702 #if wxUSE_LIBTIFF
703 image.Destroy();
704
705 if ( !image.LoadFile( dir + _T("horse.tga"), wxBITMAP_TYPE_TGA ) )
706 wxLogError(wxT("Can't load TGA image"));
707 else
708 my_horse_tga = wxBitmap( image );
709 #endif
710
711 CreateAntiAliasedBitmap();
712
713 my_smile_xbm = wxBitmap( (const char*)smile_bits, smile_width,
714 smile_height, 1 );
715
716 // demonstrates XPM automatically using the mask when saving
717 if ( m_bmpSmileXpm.Ok() )
718 m_bmpSmileXpm.SaveFile(_T("saved.xpm"), wxBITMAP_TYPE_XPM);
719
720 #if wxUSE_ICO_CUR
721 image.Destroy();
722
723 if ( !image.LoadFile( dir + _T("horse.ico"), wxBITMAP_TYPE_ICO, 0 ) )
724 wxLogError(wxT("Can't load first ICO image"));
725 else
726 my_horse_ico32 = wxBitmap( image );
727
728 image.Destroy();
729
730 if ( !image.LoadFile( dir + _T("horse.ico"), wxBITMAP_TYPE_ICO, 1 ) )
731 wxLogError(wxT("Can't load second ICO image"));
732 else
733 my_horse_ico16 = wxBitmap( image );
734
735 image.Destroy();
736
737 if ( !image.LoadFile( dir + _T("horse.ico") ) )
738 wxLogError(wxT("Can't load best ICO image"));
739 else
740 my_horse_ico = wxBitmap( image );
741
742 image.Destroy();
743
744 if ( !image.LoadFile( dir + _T("horse.cur"), wxBITMAP_TYPE_CUR ) )
745 wxLogError(wxT("Can't load best ICO image"));
746 else
747 {
748 my_horse_cur = wxBitmap( image );
749 xH = 30 + image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X) ;
750 yH = 2420 + image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y) ;
751 }
752
753 m_ani_images = wxImage::GetImageCount ( dir + _T("horse3.ani"), wxBITMAP_TYPE_ANI );
754 if (m_ani_images==0)
755 wxLogError(wxT("No ANI-format images found"));
756 else
757 my_horse_ani = new wxBitmap [m_ani_images];
758 int i ;
759 for (i=0; i < m_ani_images; i++)
760 {
761 image.Destroy();
762 if (!image.LoadFile( dir + _T("horse3.ani"), wxBITMAP_TYPE_ANI, i ))
763 {
764 wxString tmp = wxT("Can't load image number ");
765 tmp << i ;
766 wxLogError(tmp);
767 }
768 else
769 my_horse_ani [i] = wxBitmap( image );
770 }
771 #endif // wxUSE_ICO_CUR
772
773 image.Destroy();
774
775 // test image loading from stream
776 wxFile file(dir + _T("horse.bmp"));
777 if ( file.IsOpened() )
778 {
779 wxFileOffset len = file.Length();
780 size_t dataSize = (size_t)len;
781 void *data = malloc(dataSize);
782 if ( file.Read(data, dataSize) != len )
783 wxLogError(_T("Reading bitmap file failed"));
784 else
785 {
786 wxMemoryInputStream mis(data, dataSize);
787 if ( !image.LoadFile(mis) )
788 wxLogError(wxT("Can't load BMP image from stream"));
789 else
790 my_horse_bmp2 = wxBitmap( image );
791 }
792
793 free(data);
794 }
795 }
796
797 MyCanvas::~MyCanvas()
798 {
799 delete [] my_horse_ani;
800 }
801
802 void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) )
803 {
804 wxPaintDC dc( this );
805 PrepareDC( dc );
806
807 dc.DrawText( _T("Loaded image"), 30, 10 );
808 if (my_square.Ok())
809 dc.DrawBitmap( my_square, 30, 30 );
810
811 dc.DrawText( _T("Drawn directly"), 150, 10 );
812 dc.SetBrush( wxBrush( wxT("orange"), wxSOLID ) );
813 dc.SetPen( *wxBLACK_PEN );
814 dc.DrawRectangle( 150, 30, 100, 100 );
815 dc.SetBrush( *wxWHITE_BRUSH );
816 dc.DrawRectangle( 170, 50, 60, 60 );
817
818 if (my_anti.Ok())
819 dc.DrawBitmap( my_anti, 280, 30 );
820
821 dc.DrawText( _T("PNG handler"), 30, 135 );
822 if (my_horse_png.Ok())
823 {
824 dc.DrawBitmap( my_horse_png, 30, 150 );
825 wxRect rect(0,0,100,100);
826 wxBitmap sub( my_horse_png.GetSubBitmap(rect) );
827 dc.DrawText( _T("GetSubBitmap()"), 280, 175 );
828 dc.DrawBitmap( sub, 280, 195 );
829 }
830
831 dc.DrawText( _T("JPEG handler"), 30, 365 );
832 if (my_horse_jpeg.Ok())
833 dc.DrawBitmap( my_horse_jpeg, 30, 380 );
834
835 dc.DrawText( _T("Green rotated to red"), 280, 365 );
836 if (colorized_horse_jpeg.Ok())
837 dc.DrawBitmap( colorized_horse_jpeg, 280, 380 );
838
839 dc.DrawText( _T("CMYK JPEG image"), 530, 365 );
840 if (my_cmyk_jpeg.Ok())
841 dc.DrawBitmap( my_cmyk_jpeg, 530, 380 );
842
843 dc.DrawText( _T("GIF handler"), 30, 595 );
844 if (my_horse_gif.Ok())
845 dc.DrawBitmap( my_horse_gif, 30, 610 );
846
847 dc.DrawText( _T("PCX handler"), 30, 825 );
848 if (my_horse_pcx.Ok())
849 dc.DrawBitmap( my_horse_pcx, 30, 840 );
850
851 dc.DrawText( _T("BMP handler"), 30, 1055 );
852 if (my_horse_bmp.Ok())
853 dc.DrawBitmap( my_horse_bmp, 30, 1070 );
854
855 dc.DrawText( _T("BMP read from memory"), 280, 1055 );
856 if (my_horse_bmp2.Ok())
857 dc.DrawBitmap( my_horse_bmp2, 280, 1070 );
858
859 dc.DrawText( _T("PNM handler"), 30, 1285 );
860 if (my_horse_pnm.Ok())
861 dc.DrawBitmap( my_horse_pnm, 30, 1300 );
862
863 dc.DrawText( _T("PNM handler (ascii grey)"), 280, 1285 );
864 if (my_horse_asciigrey_pnm.Ok())
865 dc.DrawBitmap( my_horse_asciigrey_pnm, 280, 1300 );
866
867 dc.DrawText( _T("PNM handler (raw grey)"), 530, 1285 );
868 if (my_horse_rawgrey_pnm.Ok())
869 dc.DrawBitmap( my_horse_rawgrey_pnm, 530, 1300 );
870
871 dc.DrawText( _T("TIFF handler"), 30, 1515 );
872 if (my_horse_tiff.Ok())
873 dc.DrawBitmap( my_horse_tiff, 30, 1530 );
874
875 dc.DrawText( _T("TGA handler"), 30, 1745 );
876 if (my_horse_tga.Ok())
877 dc.DrawBitmap( my_horse_tga, 30, 1760 );
878
879 dc.DrawText( _T("XPM handler"), 30, 1975 );
880 if (my_horse_xpm.Ok())
881 dc.DrawBitmap( my_horse_xpm, 30, 2000 );
882
883 // toucans
884 {
885 int x = 750, y = 10, yy = 170;
886
887 dc.DrawText(wxT("Original toucan"), x+50, y);
888 dc.DrawBitmap(my_toucan, x, y+15, true);
889 y += yy;
890 dc.DrawText(wxT("Flipped horizontally"), x+50, y);
891 dc.DrawBitmap(my_toucan_flipped_horiz, x, y+15, true);
892 y += yy;
893 dc.DrawText(wxT("Flipped vertically"), x+50, y);
894 dc.DrawBitmap(my_toucan_flipped_vert, x, y+15, true);
895 y += yy;
896 dc.DrawText(wxT("Flipped both h&v"), x+50, y);
897 dc.DrawBitmap(my_toucan_flipped_both, x, y+15, true);
898
899 y += yy;
900 dc.DrawText(wxT("In greyscale"), x+50, y);
901 dc.DrawBitmap(my_toucan_grey, x, y+15, true);
902
903 y += yy;
904 dc.DrawText(wxT("Toucan's head"), x+50, y);
905 dc.DrawBitmap(my_toucan_head, x, y+15, true);
906
907 y += yy;
908 dc.DrawText(wxT("Scaled with normal quality"), x+50, y);
909 dc.DrawBitmap(my_toucan_scaled_normal, x, y+15, true);
910
911 y += yy;
912 dc.DrawText(wxT("Scaled with high quality"), x+50, y);
913 dc.DrawBitmap(my_toucan_scaled_high, x, y+15, true);
914
915 y += yy;
916 dc.DrawText(wxT("Blured"), x+50, y);
917 dc.DrawBitmap(my_toucan_blur, x, y+15, true);
918 }
919
920 if (my_smile_xbm.Ok())
921 {
922 int x = 300, y = 1800;
923
924 dc.DrawText( _T("XBM bitmap"), x, y );
925 dc.DrawText( _T("(green on red)"), x, y + 15 );
926 dc.SetTextForeground( _T("GREEN") );
927 dc.SetTextBackground( _T("RED") );
928 dc.DrawBitmap( my_smile_xbm, x, y + 30 );
929
930 dc.SetTextForeground( *wxBLACK );
931 dc.DrawText( _T("After wxImage conversion"), x + 120, y );
932 dc.DrawText( _T("(red on white)"), x + 120, y + 15 );
933 dc.SetTextForeground( wxT("RED") );
934 wxImage i = my_smile_xbm.ConvertToImage();
935 i.SetMaskColour( 255, 255, 255 );
936 i.Replace( 0, 0, 0,
937 wxRED_PEN->GetColour().Red(),
938 wxRED_PEN->GetColour().Green(),
939 wxRED_PEN->GetColour().Blue() );
940 dc.DrawBitmap( wxBitmap(i), x + 120, y + 30, true );
941 dc.SetTextForeground( *wxBLACK );
942 }
943
944
945 wxBitmap mono( 60,50,1 );
946 wxMemoryDC memdc;
947 memdc.SelectObject( mono );
948 memdc.SetPen( *wxBLACK_PEN );
949 memdc.SetBrush( *wxWHITE_BRUSH );
950 memdc.DrawRectangle( 0,0,60,50 );
951 memdc.SetTextForeground( *wxBLACK );
952 #ifndef __WXGTK20__
953 // I cannot convince GTK2 to draw into mono bitmaps
954 memdc.DrawText( _T("Hi!"), 5, 5 );
955 #endif
956 memdc.SetBrush( *wxBLACK_BRUSH );
957 memdc.DrawRectangle( 33,5,20,20 );
958 memdc.SetPen( *wxRED_PEN );
959 memdc.DrawLine( 5, 42, 50, 42 );
960 memdc.SelectObject( wxNullBitmap );
961
962 if (mono.Ok())
963 {
964 int x = 300, y = 1900;
965
966 dc.DrawText( _T("Mono bitmap"), x, y );
967 dc.DrawText( _T("(red on green)"), x, y + 15 );
968 dc.SetTextForeground( wxT("RED") );
969 dc.SetTextBackground( wxT("GREEN") );
970 dc.DrawBitmap( mono, x, y + 30 );
971
972 dc.SetTextForeground( *wxBLACK );
973 dc.DrawText( _T("After wxImage conversion"), x + 120, y );
974 dc.DrawText( _T("(red on white)"), x + 120, y + 15 );
975 dc.SetTextForeground( wxT("RED") );
976 wxImage i = mono.ConvertToImage();
977 i.SetMaskColour( 255,255,255 );
978 i.Replace( 0,0,0,
979 wxRED_PEN->GetColour().Red(),
980 wxRED_PEN->GetColour().Green(),
981 wxRED_PEN->GetColour().Blue() );
982 dc.DrawBitmap( wxBitmap(i), x + 120, y + 30, true );
983 dc.SetTextForeground( *wxBLACK );
984 }
985
986 // For testing transparency
987 dc.SetBrush( *wxRED_BRUSH );
988 dc.DrawRectangle( 20, 2220, 560, 68 );
989
990 dc.DrawText(_T("XPM bitmap"), 30, 2230 );
991 if ( m_bmpSmileXpm.Ok() )
992 dc.DrawBitmap(m_bmpSmileXpm, 30, 2250, true);
993
994 dc.DrawText(_T("XPM icon"), 110, 2230 );
995 if ( m_iconSmileXpm.Ok() )
996 dc.DrawIcon(m_iconSmileXpm, 110, 2250);
997
998 // testing icon -> bitmap conversion
999 wxBitmap to_blit( m_iconSmileXpm );
1000 if (to_blit.Ok())
1001 {
1002 dc.DrawText( _T("SubBitmap"), 170, 2230 );
1003 wxBitmap sub = to_blit.GetSubBitmap( wxRect(0,0,15,15) );
1004 if (sub.Ok())
1005 dc.DrawBitmap( sub, 170, 2250, true );
1006
1007 dc.DrawText( _T("Enlarged"), 250, 2230 );
1008 dc.SetUserScale( 1.5, 1.5 );
1009 dc.DrawBitmap( to_blit, (int)(250/1.5), (int)(2250/1.5), true );
1010 dc.SetUserScale( 2, 2 );
1011 dc.DrawBitmap( to_blit, (int)(300/2), (int)(2250/2), true );
1012 dc.SetUserScale( 1.0, 1.0 );
1013
1014 dc.DrawText( _T("Blit"), 400, 2230);
1015 wxMemoryDC blit_dc;
1016 blit_dc.SelectObject( to_blit );
1017 dc.Blit( 400, 2250, to_blit.GetWidth(), to_blit.GetHeight(), &blit_dc, 0, 0, wxCOPY, true );
1018 dc.SetUserScale( 1.5, 1.5 );
1019 dc.Blit( (int)(450/1.5), (int)(2250/1.5), to_blit.GetWidth(), to_blit.GetHeight(), &blit_dc, 0, 0, wxCOPY, true );
1020 dc.SetUserScale( 2, 2 );
1021 dc.Blit( (int)(500/2), (int)(2250/2), to_blit.GetWidth(), to_blit.GetHeight(), &blit_dc, 0, 0, wxCOPY, true );
1022 dc.SetUserScale( 1.0, 1.0 );
1023 }
1024
1025 dc.DrawText( _T("ICO handler (1st image)"), 30, 2290 );
1026 if (my_horse_ico32.Ok())
1027 dc.DrawBitmap( my_horse_ico32, 30, 2330, true );
1028
1029 dc.DrawText( _T("ICO handler (2nd image)"), 230, 2290 );
1030 if (my_horse_ico16.Ok())
1031 dc.DrawBitmap( my_horse_ico16, 230, 2330, true );
1032
1033 dc.DrawText( _T("ICO handler (best image)"), 430, 2290 );
1034 if (my_horse_ico.Ok())
1035 dc.DrawBitmap( my_horse_ico, 430, 2330, true );
1036
1037 dc.DrawText( _T("CUR handler"), 30, 2390 );
1038 if (my_horse_cur.Ok())
1039 {
1040 dc.DrawBitmap( my_horse_cur, 30, 2420, true );
1041 dc.SetPen (*wxRED_PEN);
1042 dc.DrawLine (xH-10,yH,xH+10,yH);
1043 dc.DrawLine (xH,yH-10,xH,yH+10);
1044 }
1045
1046 dc.DrawText( _T("ANI handler"), 230, 2390 );
1047 for ( int i=0; i < m_ani_images; i++ )
1048 {
1049 if (my_horse_ani[i].Ok())
1050 {
1051 dc.DrawBitmap( my_horse_ani[i], 230 + i * 2 * my_horse_ani[i].GetWidth() , 2420, true );
1052 }
1053 }
1054 }
1055
1056 void MyCanvas::CreateAntiAliasedBitmap()
1057 {
1058 wxBitmap bitmap( 300, 300 );
1059
1060 wxMemoryDC dc;
1061
1062 dc.SelectObject( bitmap );
1063
1064 dc.Clear();
1065
1066 dc.SetFont( wxFont( 24, wxDECORATIVE, wxNORMAL, wxNORMAL) );
1067 dc.SetTextForeground( wxT("RED") );
1068 dc.DrawText( _T("This is anti-aliased Text."), 20, 5 );
1069 dc.DrawText( _T("And a Rectangle."), 20, 45 );
1070
1071 dc.SetBrush( *wxRED_BRUSH );
1072 dc.SetPen( *wxTRANSPARENT_PEN );
1073 dc.DrawRoundedRectangle( 20, 85, 200, 180, 20 );
1074
1075 wxImage original= bitmap.ConvertToImage();
1076 wxImage anti( 150, 150 );
1077
1078 /* This is quite slow, but safe. Use wxImage::GetData() for speed instead. */
1079
1080 for (int y = 1; y < 149; y++)
1081 for (int x = 1; x < 149; x++)
1082 {
1083 int red = original.GetRed( x*2, y*2 ) +
1084 original.GetRed( x*2-1, y*2 ) +
1085 original.GetRed( x*2, y*2+1 ) +
1086 original.GetRed( x*2+1, y*2+1 );
1087 red = red/4;
1088
1089 int green = original.GetGreen( x*2, y*2 ) +
1090 original.GetGreen( x*2-1, y*2 ) +
1091 original.GetGreen( x*2, y*2+1 ) +
1092 original.GetGreen( x*2+1, y*2+1 );
1093 green = green/4;
1094
1095 int blue = original.GetBlue( x*2, y*2 ) +
1096 original.GetBlue( x*2-1, y*2 ) +
1097 original.GetBlue( x*2, y*2+1 ) +
1098 original.GetBlue( x*2+1, y*2+1 );
1099 blue = blue/4;
1100 anti.SetRGB( x, y, (unsigned char)red, (unsigned char)green, (unsigned char)blue );
1101 }
1102 my_anti = wxBitmap(anti);
1103 }
1104
1105 // MyFrame
1106
1107 enum
1108 {
1109 ID_QUIT = wxID_EXIT,
1110 ID_ABOUT = wxID_ABOUT,
1111 ID_NEW = 100,
1112 ID_INFO,
1113 ID_SHOWRAW
1114 };
1115
1116 IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
1117
1118 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
1119 EVT_MENU (ID_ABOUT, MyFrame::OnAbout)
1120 EVT_MENU (ID_QUIT, MyFrame::OnQuit)
1121 EVT_MENU (ID_NEW, MyFrame::OnNewFrame)
1122 EVT_MENU (ID_INFO, MyFrame::OnImageInfo)
1123 #ifdef wxHAVE_RAW_BITMAP
1124 EVT_MENU (ID_SHOWRAW, MyFrame::OnTestRawBitmap)
1125 #endif
1126
1127 #if wxUSE_CLIPBOARD
1128 EVT_MENU(wxID_COPY, MyFrame::OnCopy)
1129 EVT_MENU(wxID_PASTE, MyFrame::OnPaste)
1130 #endif // wxUSE_CLIPBOARD
1131 END_EVENT_TABLE()
1132
1133 MyFrame::MyFrame()
1134 : wxFrame( (wxFrame *)NULL, wxID_ANY, _T("wxImage sample"),
1135 wxPoint(20, 20), wxSize(950, 700) )
1136 {
1137 wxMenuBar *menu_bar = new wxMenuBar();
1138
1139 wxMenu *menuImage = new wxMenu;
1140 menuImage->Append( ID_NEW, _T("&Show any image...\tCtrl-O"));
1141 menuImage->Append( ID_INFO, _T("Show image &information...\tCtrl-I"));
1142 #ifdef wxHAVE_RAW_BITMAP
1143 menuImage->AppendSeparator();
1144 menuImage->Append( ID_SHOWRAW, _T("Test &raw bitmap...\tCtrl-R"));
1145 #endif
1146 menuImage->AppendSeparator();
1147 menuImage->Append( ID_ABOUT, _T("&About..."));
1148 menuImage->AppendSeparator();
1149 menuImage->Append( ID_QUIT, _T("E&xit\tCtrl-Q"));
1150 menu_bar->Append(menuImage, _T("&Image"));
1151
1152 #if wxUSE_CLIPBOARD
1153 wxMenu *menuClipboard = new wxMenu;
1154 menuClipboard->Append(wxID_COPY, _T("&Copy test image\tCtrl-C"));
1155 menuClipboard->Append(wxID_PASTE, _T("&Paste image\tCtrl-V"));
1156 menu_bar->Append(menuClipboard, _T("&Clipboard"));
1157 #endif // wxUSE_CLIPBOARD
1158
1159 SetMenuBar( menu_bar );
1160
1161 #if wxUSE_STATUSBAR
1162 CreateStatusBar(2);
1163 int widths[] = { -1, 100 };
1164 SetStatusWidths( 2, widths );
1165 #endif // wxUSE_STATUSBAR
1166
1167 m_canvas = new MyCanvas( this, wxID_ANY, wxPoint(0,0), wxSize(10,10) );
1168
1169 // 500 width * 2750 height
1170 m_canvas->SetScrollbars( 10, 10, 50, 275 );
1171 }
1172
1173 void MyFrame::OnQuit( wxCommandEvent &WXUNUSED(event) )
1174 {
1175 Close( true );
1176 }
1177
1178 void MyFrame::OnAbout( wxCommandEvent &WXUNUSED(event) )
1179 {
1180 (void)wxMessageBox( _T("wxImage demo\n")
1181 _T("Robert Roebling (c) 1998,2000"),
1182 _T("About wxImage Demo"), wxICON_INFORMATION | wxOK );
1183 }
1184
1185 wxString MyFrame::LoadUserImage(wxImage& image)
1186 {
1187 wxString filename;
1188
1189 #if wxUSE_FILEDLG
1190 filename = wxFileSelector(_T("Select image file"));
1191 if ( !filename.empty() )
1192 {
1193 if ( !image.LoadFile(filename) )
1194 {
1195 wxLogError(_T("Couldn't load image from '%s'."), filename.c_str());
1196
1197 return wxEmptyString;
1198 }
1199 }
1200 #endif // wxUSE_FILEDLG
1201
1202 return filename;
1203 }
1204
1205 void MyFrame::OnNewFrame( wxCommandEvent &WXUNUSED(event) )
1206 {
1207 wxImage image;
1208 wxString filename = LoadUserImage(image);
1209 if ( !filename.empty() )
1210 (new MyImageFrame(this, filename, wxBitmap(image)))->Show();
1211 }
1212
1213 void MyFrame::OnImageInfo( wxCommandEvent &WXUNUSED(event) )
1214 {
1215 wxImage image;
1216 if ( !LoadUserImage(image).empty() )
1217 {
1218 // TODO: show more information about the file
1219 wxString info = wxString::Format("Image size: %dx%d",
1220 image.GetWidth(),
1221 image.GetHeight());
1222
1223 int xres = image.GetOptionInt(wxIMAGE_OPTION_RESOLUTIONX),
1224 yres = image.GetOptionInt(wxIMAGE_OPTION_RESOLUTIONY);
1225 if ( xres || yres )
1226 {
1227 info += wxString::Format("\nResolution: %dx%d", xres, yres);
1228 switch ( image.GetOptionInt(wxIMAGE_OPTION_RESOLUTIONUNIT) )
1229 {
1230 default:
1231 wxFAIL_MSG( "unknown image resolution units" );
1232 // fall through
1233
1234 case wxIMAGE_RESOLUTION_NONE:
1235 info += " in default units";
1236 break;
1237
1238 case wxIMAGE_RESOLUTION_INCHES:
1239 info += " in";
1240 break;
1241
1242 case wxIMAGE_RESOLUTION_CM:
1243 info += " cm";
1244 break;
1245 }
1246 }
1247
1248 wxLogMessage("%s", info);
1249 }
1250 }
1251
1252 #ifdef wxHAVE_RAW_BITMAP
1253
1254 void MyFrame::OnTestRawBitmap( wxCommandEvent &WXUNUSED(event) )
1255 {
1256 (new MyRawBitmapFrame(this))->Show();
1257 }
1258
1259 #endif // wxHAVE_RAW_BITMAP
1260
1261 #if wxUSE_CLIPBOARD
1262
1263 void MyFrame::OnCopy(wxCommandEvent& WXUNUSED(event))
1264 {
1265 wxBitmapDataObject *dobjBmp = new wxBitmapDataObject;
1266 dobjBmp->SetBitmap(m_canvas->my_horse_png);
1267
1268 wxTheClipboard->Open();
1269
1270 if ( !wxTheClipboard->SetData(dobjBmp) )
1271 {
1272 wxLogError(_T("Failed to copy bitmap to clipboard"));
1273 }
1274
1275 wxTheClipboard->Close();
1276 }
1277
1278 void MyFrame::OnPaste(wxCommandEvent& WXUNUSED(event))
1279 {
1280 wxBitmapDataObject dobjBmp;
1281
1282 wxTheClipboard->Open();
1283 if ( !wxTheClipboard->GetData(dobjBmp) )
1284 {
1285 wxLogMessage(_T("No bitmap data in the clipboard"));
1286 }
1287 else
1288 {
1289 (new MyImageFrame(this, _T("Clipboard"), dobjBmp.GetBitmap()))->Show();
1290 }
1291 wxTheClipboard->Close();
1292 }
1293
1294 #endif // wxUSE_CLIPBOARD
1295
1296 //-----------------------------------------------------------------------------
1297 // MyApp
1298 //-----------------------------------------------------------------------------
1299
1300 bool MyApp::OnInit()
1301 {
1302 if ( !wxApp::OnInit() )
1303 return false;
1304
1305 wxInitAllImageHandlers();
1306
1307 wxFrame *frame = new MyFrame();
1308 frame->Show( true );
1309
1310 return true;
1311 }