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