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