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 51class MyFrame; 52class MyApp; 53 54// MyCanvas 55 56class MyCanvas: public wxScrolledWindow 57{ 58public: 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 103private: 104 wxBitmap m_bmpSmileXpm; 105 wxIcon m_iconSmileXpm; 106 107 DECLARE_EVENT_TABLE() 108}; 109 110 111// MyFrame 112 113 114class MyFrame: public wxFrame 115{ 116public: 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 133private: 134 DECLARE_DYNAMIC_CLASS(MyFrame) 135 DECLARE_EVENT_TABLE() 136}; 137 138class MyImageFrame : public wxFrame 139{ 140public: 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 150 void OnEraseBackground(wxEraseEvent& WXUNUSED(event)) 151 { 152 // do nothing here to be able to see how transparent images are shown 153 } 154 155 void OnPaint(wxPaintEvent& WXUNUSED(event)) 156 { 157 wxPaintDC dc( this ); 158 dc.DrawBitmap( m_bitmap, 0, 0, true /* use mask */ ); 159 } 160 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 287private: 288 wxBitmap m_bitmap; 289 290 DECLARE_EVENT_TABLE() 291}; 292 293#ifdef wxHAVE_RAW_BITMAP 294 295#include "wx/rawbmp.h" 296 297class MyRawBitmapFrame : public wxFrame 298{ 299public: 300 enum 301 { 302 BORDER = 15, 303 SIZE = 150, 304 REAL_SIZE = SIZE - 2*BORDER 305 }; 306 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 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 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 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 425private: 426 wxBitmap m_bitmap; 427 wxBitmap m_alphaBitmap; 428 429 DECLARE_EVENT_TABLE() 430}; 431 432#endif // wxHAVE_RAW_BITMAP 433 434// MyApp 435 436class MyApp: public wxApp 437{ 438public: 439 virtual bool OnInit(); 440}; 441 442// main program 443 444IMPLEMENT_APP(MyApp) 445 446// MyCanvas 447 448BEGIN_EVENT_TABLE(MyImageFrame, wxFrame) 449 EVT_ERASE_BACKGROUND(MyImageFrame::OnEraseBackground) 450 EVT_PAINT(MyImageFrame::OnPaint) 451 EVT_LEFT_DCLICK(MyImageFrame::OnSave) 452END_EVENT_TABLE() 453 454#ifdef wxHAVE_RAW_BITMAP 455 456BEGIN_EVENT_TABLE(MyRawBitmapFrame, wxFrame) 457 EVT_PAINT(MyRawBitmapFrame::OnPaint) 458END_EVENT_TABLE() 459 460#endif // wxHAVE_RAW_BITMAP 461 462BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow) 463 EVT_PAINT(MyCanvas::OnPaint) 464END_EVENT_TABLE() 465 466MyCanvas::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 717MyCanvas::~MyCanvas() 718{ 719 delete [] my_horse_ani; 720} 721 722void 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 976void 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 1027enum 1028{ 1029 ID_QUIT = wxID_EXIT, 1030 ID_ABOUT = wxID_ABOUT, 1031 ID_NEW = 100, 1032 ID_SHOWRAW = 101 1033}; 1034 1035IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame ) 1036 1037BEGIN_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 1049END_EVENT_TABLE() 1050 1051MyFrame::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 1090void MyFrame::OnQuit( wxCommandEvent &WXUNUSED(event) ) 1091{ 1092 Close( true ); 1093} 1094 1095void 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 1102void 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 1123void MyFrame::OnTestRawBitmap( wxCommandEvent &WXUNUSED(event) ) 1124{ 1125 (new MyRawBitmapFrame(this))->Show(); 1126} 1127 1128#endif // wxHAVE_RAW_BITMAP 1129 1130#if wxUSE_CLIPBOARD 1131 1132void 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 1147void 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 1169bool MyApp::OnInit() 1170{ 1171 wxInitAllImageHandlers(); 1172 1173 wxFrame *frame = new MyFrame(); 1174 frame->Show( true ); 1175 1176 return true; 1177} 1178