4 * Author: Robert Roebling
6 * Copyright: (C) 1998, Robert Roebling
10 // For compilers that support precompilation, includes "wx/wx.h".
11 #include "wx/wxprec.h"
23 #include "wx/mstream.h"
24 #include "wx/wfstream.h"
25 #include "wx/quantize.h"
38 class MyCanvas
: public wxScrolledWindow
42 MyCanvas( wxWindow
*parent
, wxWindowID
, const wxPoint
&pos
, const wxSize
&size
);
44 void OnPaint( wxPaintEvent
&event
);
45 void CreateAntiAliasedBitmap();
47 wxBitmap
*my_horse_png
;
48 wxBitmap
*my_horse_jpeg
;
49 wxBitmap
*my_horse_gif
;
50 wxBitmap
*my_horse_bmp
;
51 wxBitmap
*my_horse_pcx
;
52 wxBitmap
*my_horse_pnm
;
53 wxBitmap
*my_horse_tiff
;
54 wxBitmap
*my_horse_xpm
;
55 wxBitmap
*my_horse_ico32
;
56 wxBitmap
*my_horse_ico16
;
57 wxBitmap
*my_horse_ico
;
58 wxBitmap
*my_horse_cur
;
60 wxBitmap
*my_smile_xbm
;
67 wxBitmap m_bmpSmileXpm
;
68 wxIcon m_iconSmileXpm
;
71 DECLARE_DYNAMIC_CLASS(MyCanvas
)
76 const int nChoices
= 8 ;
77 static const wxString bppchoices
[nChoices
] =
89 static const int bppvalues
[nChoices
] =
104 class MyFrame
: public wxFrame
109 void OnAbout( wxCommandEvent
&event
);
110 void OnNewFrame( wxCommandEvent
&event
);
111 void OnQuit( wxCommandEvent
&event
);
116 DECLARE_DYNAMIC_CLASS(MyFrame
)
117 DECLARE_EVENT_TABLE()
120 class MyImageFrame
: public wxFrame
123 MyImageFrame(wxFrame
*parent
, const wxBitmap
& bitmap
)
124 : wxFrame(parent
, -1, _T("Double click to save"),
125 wxDefaultPosition
, wxDefaultSize
,
126 wxCAPTION
| wxSYSTEM_MENU
),
129 SetClientSize(bitmap
.GetWidth(), bitmap
.GetHeight());
132 void OnPaint(wxPaintEvent
& WXUNUSED(event
))
134 wxPaintDC
dc( this );
135 //TRUE for masked images
136 dc
.DrawBitmap( m_bitmap
, 0, 0, TRUE
);
139 void OnSave(wxCommandEvent
& WXUNUSED(event
))
141 wxImage
image(m_bitmap
);
143 int bppselection
= wxGetSingleChoiceIndex("Set BMP BPP",
148 if ( bppselection
== -1 )
154 image
.SetOption(wxIMAGE_OPTION_BMP_FORMAT
, bppvalues
[bppselection
]);
156 wxString deffilename
= bppchoices
[bppselection
];
157 deffilename
.Replace(wxT(" "), wxT("_"));
158 deffilename
+= wxT(".bmp");
159 wxString savefilename
= wxFileSelector( wxT("Save Image"),
162 (const wxChar
*)NULL
,
163 wxT("BMP files (*.bmp)|*.bmp|")
164 wxT("PNG files (*.png)|*.png|")
165 wxT("JPEG files (*.jpg)|*.jpg|")
166 wxT("GIF files (*.gif)|*.gif|")
167 wxT("TIFF files (*.tif)|*.tif|")
168 wxT("PCX files (*.pcx)|*.pcx|")
169 wxT("ICO files (*.ico)|*.ico|")
170 wxT("CUR files (*.cur)|*.cur"),
173 if ( savefilename
.empty() )
176 if ( image
.GetOptionInt(wxIMAGE_OPTION_BMP_FORMAT
) == wxBMP_8BPP_PALETTE
)
178 unsigned char *cmap
= new unsigned char [256];
179 for ( int i
= 0; i
< 256; i
++ )
181 image
.SetPalette(wxPalette(256, cmap
, cmap
, cmap
));
188 wxString extension
= savefilename
.AfterLast('.').Lower();
190 if (extension
== "bmp")
191 saved
=image
.SaveFile(savefilename
, wxBITMAP_TYPE_BMP
);
192 else if (extension
== "png")
193 saved
=image
.SaveFile(savefilename
, wxBITMAP_TYPE_PNG
);
194 else if (extension
== "pcx")
195 saved
=image
.SaveFile(savefilename
, wxBITMAP_TYPE_PCX
);
196 else if ((extension
== "tif") || (extension
== "tiff"))
197 saved
=image
.SaveFile(savefilename
, wxBITMAP_TYPE_TIF
);
198 else if (extension
== "jpg")
199 saved
=image
.SaveFile(savefilename
, wxBITMAP_TYPE_JPEG
);
200 else if (extension
== "pnm")
201 saved
=image
.SaveFile(savefilename
, wxBITMAP_TYPE_PNM
);
202 else if (extension
== "ico")
203 saved
=image
.SaveFile(savefilename
, wxBITMAP_TYPE_ICO
);
204 else if (extension
== "cur")
206 image
.Rescale(32,32);
207 image
.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_X
, 0);
208 image
.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y
, 0);
209 saved
=image
.SaveFile(savefilename
, wxBITMAP_TYPE_CUR
);
212 wxMessageBox("Unknown file type, see options in file selector.",
214 wxOK
|wxCENTRE
, this);
220 DECLARE_EVENT_TABLE()
225 class MyApp
: public wxApp
228 virtual bool OnInit();
237 IMPLEMENT_DYNAMIC_CLASS(MyCanvas
, wxScrolledWindow
)
239 BEGIN_EVENT_TABLE(MyImageFrame
, wxFrame
)
240 EVT_PAINT(MyImageFrame::OnPaint
)
241 EVT_LEFT_DCLICK(MyImageFrame::OnSave
)
244 BEGIN_EVENT_TABLE(MyCanvas
, wxScrolledWindow
)
245 EVT_PAINT(MyCanvas::OnPaint
)
248 MyCanvas::MyCanvas( wxWindow
*parent
, wxWindowID id
,
249 const wxPoint
&pos
, const wxSize
&size
)
250 : wxScrolledWindow( parent
, id
, pos
, size
, wxSUNKEN_BORDER
)
251 #if !defined(__WINDOWS__) || wxUSE_XPM_IN_MSW
252 , m_bmpSmileXpm((const char **) smile_xpm
)
253 , m_iconSmileXpm((const char **) smile_xpm
)
256 my_horse_png
= (wxBitmap
*) NULL
;
257 my_horse_jpeg
= (wxBitmap
*) NULL
;
258 my_horse_gif
= (wxBitmap
*) NULL
;
259 my_horse_bmp
= (wxBitmap
*) NULL
;
260 my_horse_pcx
= (wxBitmap
*) NULL
;
261 my_horse_pnm
= (wxBitmap
*) NULL
;
262 my_horse_tiff
= (wxBitmap
*) NULL
;
263 my_horse_xpm
= (wxBitmap
*) NULL
;
264 my_horse_ico32
= (wxBitmap
*) NULL
;
265 my_horse_ico16
= (wxBitmap
*) NULL
;
266 my_horse_ico
= (wxBitmap
*) NULL
;
267 my_horse_cur
= (wxBitmap
*) NULL
;
269 my_smile_xbm
= (wxBitmap
*) NULL
;
270 my_square
= (wxBitmap
*) NULL
;
271 my_anti
= (wxBitmap
*) NULL
;
273 SetBackgroundColour(* wxWHITE
);
275 wxBitmap
bitmap( 100, 100 );
278 dc
.SelectObject( bitmap
);
279 dc
.SetBrush( wxBrush( wxT("orange"), wxSOLID
) );
280 dc
.SetPen( *wxBLACK_PEN
);
281 dc
.DrawRectangle( 0, 0, 100, 100 );
282 dc
.SetBrush( *wxWHITE_BRUSH
);
283 dc
.DrawRectangle( 20, 20, 60, 60 );
284 dc
.SelectObject( wxNullBitmap
);
286 // try to find the directory with our images
288 if ( wxFile::Exists(wxT("./horse.png")) )
290 else if ( wxFile::Exists(wxT("../horse.png")) )
293 wxLogWarning(wxT("Can't find image files in either '.' or '..'!"));
295 wxImage image
= bitmap
.ConvertToImage();
298 if ( !image
.SaveFile( dir
+ wxString("test.png"), wxBITMAP_TYPE_PNG
))
299 wxLogError(wxT("Can't save file"));
303 image
.LoadFile( dir
+ wxString("test.png") );
304 my_square
= new wxBitmap( image
);
308 if ( !image
.LoadFile( dir
+ wxString("horse.png")) )
309 wxLogError(wxT("Can't load PNG image"));
311 my_horse_png
= new wxBitmap( image
);
312 #endif // wxUSE_LIBPNG
317 if ( !image
.LoadFile( dir
+ wxString("horse.jpg")) )
318 wxLogError(wxT("Can't load JPG image"));
320 my_horse_jpeg
= new wxBitmap( image
);
321 #endif // wxUSE_LIBJPEG
326 if ( !image
.LoadFile( dir
+ wxString("horse.gif")) )
327 wxLogError(wxT("Can't load GIF image"));
329 my_horse_gif
= new wxBitmap( image
);
335 if ( !image
.LoadFile( dir
+ wxString("horse.pcx"), wxBITMAP_TYPE_PCX
) )
336 wxLogError(wxT("Can't load PCX image"));
338 my_horse_pcx
= new wxBitmap( image
);
343 if ( !image
.LoadFile( dir
+ wxString("horse.bmp"), wxBITMAP_TYPE_BMP
) )
344 wxLogError(wxT("Can't load BMP image"));
346 my_horse_bmp
= new wxBitmap( image
);
351 if ( !image
.LoadFile( dir
+ wxString("horse.xpm"), wxBITMAP_TYPE_XPM
) )
352 wxLogError(wxT("Can't load XPM image"));
354 my_horse_xpm
= new wxBitmap( image
);
356 if ( !image
.SaveFile( dir
+ wxString("test.xpm"), wxBITMAP_TYPE_XPM
))
357 wxLogError(wxT("Can't save file"));
363 if ( !image
.LoadFile( dir
+ wxString("horse.pnm"), wxBITMAP_TYPE_PNM
) )
364 wxLogError(wxT("Can't load PNM image"));
366 my_horse_pnm
= new wxBitmap( image
);
372 if ( !image
.LoadFile( dir
+ wxString("horse.tif"), wxBITMAP_TYPE_TIF
) )
373 wxLogError(wxT("Can't load TIFF image"));
375 my_horse_tiff
= new wxBitmap( image
);
378 CreateAntiAliasedBitmap();
380 my_smile_xbm
= new wxBitmap( (const char*)smile_bits
, smile_width
,
383 #if !defined(__WINDOWS__) || wxUSE_XPM_IN_MSW
384 // demonstrates XPM automatically using the mask when saving
385 if ( m_bmpSmileXpm
.Ok() )
386 m_bmpSmileXpm
.SaveFile("saved.xpm", wxBITMAP_TYPE_XPM
);
392 if ( !image
.LoadFile( dir
+ wxString("horse.ico"), wxBITMAP_TYPE_ICO
, 0 ) )
393 wxLogError(wxT("Can't load first ICO image"));
395 my_horse_ico32
= new wxBitmap( image
);
399 if ( !image
.LoadFile( dir
+ wxString("horse.ico"), wxBITMAP_TYPE_ICO
, 1 ) )
400 wxLogError(wxT("Can't load second ICO image"));
402 my_horse_ico16
= new wxBitmap( image
);
406 if ( !image
.LoadFile( dir
+ wxString("horse.ico") ) )
407 wxLogError(wxT("Can't load best ICO image"));
409 my_horse_ico
= new wxBitmap( image
);
413 if ( !image
.LoadFile( dir
+ wxString("horse.cur"), wxBITMAP_TYPE_CUR
) )
414 wxLogError(wxT("Can't load best ICO image"));
417 my_horse_cur
= new wxBitmap( image
);
418 xH
= 30 + image
.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X
) ;
419 yH
= 2420 + image
.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y
) ;
426 MyCanvas::~MyCanvas()
430 delete my_horse_jpeg
;
434 delete my_horse_tiff
;
436 delete my_horse_ico32
;
437 delete my_horse_ico16
;
444 void MyCanvas::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
446 wxPaintDC
dc( this );
449 dc
.DrawText( "Loaded image", 30, 10 );
450 if (my_square
&& my_square
->Ok()) dc
.DrawBitmap( *my_square
, 30, 30 );
452 dc
.DrawText( "Drawn directly", 150, 10 );
453 dc
.SetBrush( wxBrush( wxT("orange"), wxSOLID
) );
454 dc
.SetPen( *wxBLACK_PEN
);
455 dc
.DrawRectangle( 150, 30, 100, 100 );
456 dc
.SetBrush( *wxWHITE_BRUSH
);
457 dc
.DrawRectangle( 170, 50, 60, 60 );
459 if (my_anti
&& my_anti
->Ok())
460 dc
.DrawBitmap( *my_anti
, 280, 30 );
462 dc
.DrawText( "PNG handler", 30, 135 );
463 if (my_horse_png
&& my_horse_png
->Ok())
465 dc
.DrawBitmap( *my_horse_png
, 30, 150 );
466 wxRect
rect(0,0,100,100);
467 wxBitmap
sub( my_horse_png
->GetSubBitmap(rect
) );
468 dc
.DrawText( "GetSubBitmap()", 280, 190 );
469 dc
.DrawBitmap( sub
, 280, 210 );
472 dc
.DrawText( "JPEG handler", 30, 365 );
473 if (my_horse_jpeg
&& my_horse_jpeg
->Ok())
474 dc
.DrawBitmap( *my_horse_jpeg
, 30, 380 );
476 dc
.DrawText( "GIF handler", 30, 595 );
477 if (my_horse_gif
&& my_horse_gif
->Ok())
478 dc
.DrawBitmap( *my_horse_gif
, 30, 610 );
480 dc
.DrawText( "PCX handler", 30, 825 );
481 if (my_horse_pcx
&& my_horse_pcx
->Ok())
482 dc
.DrawBitmap( *my_horse_pcx
, 30, 840 );
484 dc
.DrawText( "BMP handler", 30, 1055 );
485 if (my_horse_bmp
&& my_horse_bmp
->Ok())
486 dc
.DrawBitmap( *my_horse_bmp
, 30, 1070 );
488 dc
.DrawText( "PNM handler", 30, 1285 );
489 if (my_horse_pnm
&& my_horse_pnm
->Ok())
490 dc
.DrawBitmap( *my_horse_pnm
, 30, 1300 );
492 dc
.DrawText( "TIFF handler", 30, 1515 );
493 if (my_horse_tiff
&& my_horse_tiff
->Ok())
494 dc
.DrawBitmap( *my_horse_tiff
, 30, 1530 );
496 dc
.DrawText( "XPM handler", 30, 1745 );
497 if (my_horse_xpm
&& my_horse_xpm
->Ok())
498 dc
.DrawBitmap( *my_horse_xpm
, 30, 1760 );
501 if (my_smile_xbm
&& my_smile_xbm
->Ok())
503 dc
.DrawText( "XBM bitmap", 30, 1975 );
504 dc
.DrawText( "(green on red)", 30, 1990 );
505 dc
.SetTextForeground( wxT("GREEN") );
506 dc
.SetTextBackground( wxT("RED") );
507 dc
.DrawBitmap( *my_smile_xbm
, 30, 2010 );
509 dc
.SetTextForeground( wxT("BLACK") );
510 dc
.DrawText( "After wxImage conversion", 150, 1975 );
511 dc
.DrawText( "(red on white)", 150, 1990 );
512 dc
.SetTextForeground( wxT("RED") );
513 wxImage i
= my_smile_xbm
->ConvertToImage();
514 i
.SetMaskColour( 255, 255, 255 );
516 wxRED_PEN
->GetColour().Red(),
517 wxRED_PEN
->GetColour().Green(),
518 wxRED_PEN
->GetColour().Blue() );
519 dc
.DrawBitmap( i
.ConvertToBitmap(), 150, 2010, TRUE
);
520 dc
.SetTextForeground( wxT("BLACK") );
524 wxBitmap
mono( 60,50,1 );
526 memdc
.SelectObject( mono
);
527 memdc
.SetPen( *wxBLACK_PEN
);
528 memdc
.SetBrush( *wxWHITE_BRUSH
);
529 memdc
.DrawRectangle( 0,0,60,50 );
530 memdc
.SetTextForeground( *wxBLACK
);
531 memdc
.DrawText( "Hi!", 5, 5 );
532 memdc
.SetBrush( *wxBLACK_BRUSH
);
533 memdc
.DrawRectangle( 33,5,20,20 );
534 memdc
.SetPen( *wxRED_PEN
);
535 memdc
.DrawLine( 5, 42, 50, 42 );
536 memdc
.SelectObject( wxNullBitmap
);
540 dc
.DrawText( "Mono bitmap", 30, 2095 );
541 dc
.DrawText( "(red on green)", 30, 2110 );
542 dc
.SetTextForeground( wxT("RED") );
543 dc
.SetTextBackground( wxT("GREEN") );
544 dc
.DrawBitmap( mono
, 30, 2130 );
546 dc
.SetTextForeground( wxT("BLACK") );
547 dc
.DrawText( "After wxImage conversion", 150, 2095 );
548 dc
.DrawText( "(red on white)", 150, 2110 );
549 dc
.SetTextForeground( wxT("RED") );
550 wxImage i
= mono
.ConvertToImage();
551 i
.SetMaskColour( 255,255,255 );
553 wxRED_PEN
->GetColour().Red(),
554 wxRED_PEN
->GetColour().Green(),
555 wxRED_PEN
->GetColour().Blue() );
556 dc
.DrawBitmap( i
.ConvertToBitmap(), 150, 2130, TRUE
);
557 dc
.SetTextForeground( wxT("BLACK") );
560 dc
.DrawText("XPM bitmap", 30, 2230);
561 if ( m_bmpSmileXpm
.Ok() )
563 dc
.DrawBitmap(m_bmpSmileXpm
, 30, 2250, TRUE
);
566 dc
.DrawText("XPM icon", 150, 2230);
567 if ( m_iconSmileXpm
.Ok() )
569 dc
.DrawIcon(m_iconSmileXpm
, 150, 2250);
572 dc
.DrawText( "ICO handler (1st image)", 30, 2290 );
573 if (my_horse_ico32
&& my_horse_ico32
->Ok())
574 dc
.DrawBitmap( *my_horse_ico32
, 30, 2330, TRUE
);
576 dc
.DrawText( "ICO handler (2nd image)", 230, 2290 );
577 if (my_horse_ico16
&& my_horse_ico16
->Ok())
578 dc
.DrawBitmap( *my_horse_ico16
, 230, 2330, TRUE
);
580 dc
.DrawText( "ICO handler (best image)", 430, 2290 );
581 if (my_horse_ico
&& my_horse_ico
->Ok())
582 dc
.DrawBitmap( *my_horse_ico
, 430, 2330, TRUE
);
584 dc
.DrawText( "CUR handler", 30, 2390 );
585 if (my_horse_cur
&& my_horse_cur
->Ok())
587 dc
.DrawBitmap( *my_horse_cur
, 30, 2420, TRUE
);
588 dc
.SetPen (*wxRED_PEN
);
589 dc
.DrawLine (xH
-10,yH
,xH
+10,yH
);
590 dc
.DrawLine (xH
,yH
-10,xH
,yH
+10);
594 void MyCanvas::CreateAntiAliasedBitmap()
596 wxBitmap
bitmap( 300, 300 );
600 dc
.SelectObject( bitmap
);
604 dc
.SetFont( wxFont( 24, wxDECORATIVE
, wxNORMAL
, wxNORMAL
) );
605 dc
.SetTextForeground( wxT("RED") );
606 dc
.DrawText( "This is anti-aliased Text.", 20, 20 );
607 dc
.DrawText( "And a Rectangle.", 20, 60 );
609 dc
.SetBrush( *wxRED_BRUSH
);
610 dc
.SetPen( *wxTRANSPARENT_PEN
);
611 dc
.DrawRoundedRectangle( 20, 100, 200, 180, 20 );
613 wxImage original
= bitmap
.ConvertToImage();
614 wxImage
anti( 150, 150 );
616 /* This is quite slow, but safe. Use wxImage::GetData() for speed instead. */
618 for (int y
= 1; y
< 149; y
++)
619 for (int x
= 1; x
< 149; x
++)
621 int red
= original
.GetRed( x
*2, y
*2 ) +
622 original
.GetRed( x
*2-1, y
*2 ) +
623 original
.GetRed( x
*2, y
*2+1 ) +
624 original
.GetRed( x
*2+1, y
*2+1 );
627 int green
= original
.GetGreen( x
*2, y
*2 ) +
628 original
.GetGreen( x
*2-1, y
*2 ) +
629 original
.GetGreen( x
*2, y
*2+1 ) +
630 original
.GetGreen( x
*2+1, y
*2+1 );
633 int blue
= original
.GetBlue( x
*2, y
*2 ) +
634 original
.GetBlue( x
*2-1, y
*2 ) +
635 original
.GetBlue( x
*2, y
*2+1 ) +
636 original
.GetBlue( x
*2+1, y
*2+1 );
638 anti
.SetRGB( x
, y
, red
, green
, blue
);
640 my_anti
= new wxBitmap( anti
.ConvertToBitmap() );
645 const int ID_QUIT
= 108;
646 const int ID_ABOUT
= 109;
647 const int ID_NEW
= 110;
649 IMPLEMENT_DYNAMIC_CLASS( MyFrame
, wxFrame
)
651 BEGIN_EVENT_TABLE(MyFrame
,wxFrame
)
652 EVT_MENU (ID_ABOUT
, MyFrame::OnAbout
)
653 EVT_MENU (ID_QUIT
, MyFrame::OnQuit
)
654 EVT_MENU (ID_NEW
, MyFrame::OnNewFrame
)
658 : wxFrame( (wxFrame
*)NULL
, -1, "wxImage sample",
659 wxPoint(20,20), wxSize(470,360) )
661 wxMenu
*file_menu
= new wxMenu();
662 file_menu
->Append( ID_NEW
, "&Show image...");
663 file_menu
->AppendSeparator();
664 file_menu
->Append( ID_ABOUT
, "&About...");
665 file_menu
->AppendSeparator();
666 file_menu
->Append( ID_QUIT
, "E&xit");
668 wxMenuBar
*menu_bar
= new wxMenuBar();
669 menu_bar
->Append(file_menu
, "&File");
671 SetMenuBar( menu_bar
);
674 int widths
[] = { -1, 100 };
675 SetStatusWidths( 2, widths
);
677 m_canvas
= new MyCanvas( this, -1, wxPoint(0,0), wxSize(10,10) );
679 // 500 width * 2500 height
680 m_canvas
->SetScrollbars( 10, 10, 50, 250 );
683 void MyFrame::OnQuit( wxCommandEvent
&WXUNUSED(event
) )
688 void MyFrame::OnAbout( wxCommandEvent
&WXUNUSED(event
) )
690 (void)wxMessageBox( "wxImage demo\n"
691 "Robert Roebling (c) 1998,2000",
692 "About wxImage Demo", wxICON_INFORMATION
| wxOK
);
695 void MyFrame::OnNewFrame( wxCommandEvent
&WXUNUSED(event
) )
697 wxString filename
= wxFileSelector(_T("Select image file"));
702 if ( !image
.LoadFile(filename
) )
704 wxLogError(_T("Couldn't load image from '%s'."), filename
.c_str());
709 (new MyImageFrame(this, image
.ConvertToBitmap()))->Show();
712 //-----------------------------------------------------------------------------
714 //-----------------------------------------------------------------------------
719 wxImage::AddHandler( new wxPNGHandler
);
723 wxImage::AddHandler( new wxJPEGHandler
);
727 wxImage::AddHandler( new wxTIFFHandler
);
731 wxImage::AddHandler( new wxGIFHandler
);
735 wxImage::AddHandler( new wxPCXHandler
);
739 wxImage::AddHandler( new wxPNMHandler
);
743 wxImage::AddHandler( new wxXPMHandler
);
747 wxImage::AddHandler( new wxICOHandler
);
748 wxImage::AddHandler( new wxCURHandler
);
751 wxFrame
*frame
= new MyFrame();