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