/////////////////////////////////////////////////////////////////////////////// // Name: samples/image/image.cpp // Purpose: sample showing operations with wxImage // Author: Robert Roebling // Modified by: Francesco Montorsi // Created: 1998 // Copyright: (c) 1998-2005 Robert Roebling // (c) 2005-2009 Vadim Zeitlin // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// // For compilers that support precompilation, includes "wx/wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "wx/image.h" #include "wx/file.h" #include "wx/filename.h" #include "wx/graphics.h" #include "wx/mstream.h" #include "wx/wfstream.h" #include "wx/quantize.h" #include "wx/scopedptr.h" #include "wx/stopwatch.h" #include "wx/versioninfo.h" #if wxUSE_CLIPBOARD #include "wx/dataobj.h" #include "wx/clipbrd.h" #endif // wxUSE_CLIPBOARD #if defined(__WXMSW__) #ifdef wxHAVE_RAW_BITMAP #include "wx/rawbmp.h" #endif #endif #if defined(__WXMAC__) || defined(__WXGTK__) #define wxHAVE_RAW_BITMAP #include "wx/rawbmp.h" #endif #include "canvas.h" #ifndef wxHAS_IMAGES_IN_RESOURCES #include "../sample.xpm" #endif // ============================================================================ // declarations // ============================================================================ //----------------------------------------------------------------------------- // MyApp //----------------------------------------------------------------------------- class MyApp: public wxApp { public: virtual bool OnInit() wxOVERRIDE; }; // ---------------------------------------------------------------------------- // MyFrame // ---------------------------------------------------------------------------- class MyFrame: public wxFrame { public: MyFrame(); void OnAbout( wxCommandEvent &event ); void OnNewFrame( wxCommandEvent &event ); void OnNewFrameHiDPI(wxCommandEvent&); void OnImageInfo( wxCommandEvent &event ); void OnThumbnail( wxCommandEvent &event ); void OnUpdateNewFrameHiDPI(wxUpdateUIEvent&); #ifdef wxHAVE_RAW_BITMAP void OnTestRawBitmap( wxCommandEvent &event ); #endif // wxHAVE_RAW_BITMAP #if wxUSE_GRAPHICS_CONTEXT void OnTestGraphics(wxCommandEvent& event); #endif // wxUSE_GRAPHICS_CONTEXT void OnQuit( wxCommandEvent &event ); #if wxUSE_CLIPBOARD void OnCopy(wxCommandEvent& event); void OnPaste(wxCommandEvent& event); #endif // wxUSE_CLIPBOARD MyCanvas *m_canvas; private: // ask user for the file name and try to load an image from it // // return the file path on success, empty string if we failed to load the // image or were cancelled by user static wxString LoadUserImage(wxImage& image); wxDECLARE_DYNAMIC_CLASS(MyFrame); wxDECLARE_EVENT_TABLE(); }; // ---------------------------------------------------------------------------- // Frame used for showing a standalone image // ---------------------------------------------------------------------------- enum { ID_ROTATE_LEFT = wxID_HIGHEST+1, ID_ROTATE_RIGHT, ID_RESIZE, ID_PAINT_BG }; class MyImageFrame : public wxFrame { public: MyImageFrame(wxFrame *parent, const wxString& desc, const wxImage& image, double scale = 1.0) { Create(parent, desc, wxBitmap(image, wxBITMAP_SCREEN_DEPTH, scale), image.GetImageCount(desc)); } MyImageFrame(wxFrame *parent, const wxString& desc, const wxBitmap& bitmap) { Create(parent, desc, bitmap); } private: bool Create(wxFrame *parent, const wxString& desc, const wxBitmap& bitmap, int numImages = 1) { if ( !wxFrame::Create(parent, wxID_ANY, wxString::Format("Image from %s", desc), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE | wxFULL_REPAINT_ON_RESIZE) ) return false; m_bitmap = bitmap; m_zoom = 1.; wxMenu *menu = new wxMenu; menu->Append(wxID_SAVEAS); menu->AppendSeparator(); menu->AppendCheckItem(ID_PAINT_BG, "&Paint background", "Uncheck this for transparent images"); menu->AppendSeparator(); menu->Append(ID_RESIZE, "&Fit to window\tCtrl-F"); menu->Append(wxID_ZOOM_IN, "Zoom &in\tCtrl-+"); menu->Append(wxID_ZOOM_OUT, "Zoom &out\tCtrl--"); menu->Append(wxID_ZOOM_100, "Reset zoom to &100%\tCtrl-1"); menu->AppendSeparator(); menu->Append(ID_ROTATE_LEFT, "Rotate &left\tCtrl-L"); menu->Append(ID_ROTATE_RIGHT, "Rotate &right\tCtrl-R"); wxMenuBar *mbar = new wxMenuBar; mbar->Append(menu, "&Image"); SetMenuBar(mbar); mbar->Check(ID_PAINT_BG, true); CreateStatusBar(2); if ( numImages != 1 ) SetStatusText(wxString::Format("%d images", numImages), 1); SetClientSize(bitmap.GetWidth(), bitmap.GetHeight()); UpdateStatusBar(); Show(); return true; } void OnEraseBackground(wxEraseEvent& WXUNUSED(event)) { // do nothing here to be able to see how transparent images are shown } void OnPaint(wxPaintEvent& WXUNUSED(event)) { wxPaintDC dc(this); if ( GetMenuBar()->IsChecked(ID_PAINT_BG) ) dc.Clear(); dc.SetUserScale(m_zoom, m_zoom); const wxSize size = GetClientSize(); dc.DrawBitmap ( m_bitmap, dc.DeviceToLogicalX((size.x - m_zoom*m_bitmap.GetWidth())/2), dc.DeviceToLogicalY((size.y - m_zoom*m_bitmap.GetHeight())/2), true /* use mask */ ); } void OnSave(wxCommandEvent& WXUNUSED(event)) { #if wxUSE_FILEDLG wxImage image = m_bitmap.ConvertToImage(); wxString savefilename = wxFileSelector( "Save Image", wxEmptyString, wxEmptyString, wxEmptyString, "BMP files (*.bmp)|*.bmp|" #if wxUSE_LIBPNG "PNG files (*.png)|*.png|" #endif #if wxUSE_LIBJPEG "JPEG files (*.jpg)|*.jpg|" #endif #if wxUSE_GIF "GIF files (*.gif)|*.gif|" #endif #if wxUSE_LIBTIFF "TIFF files (*.tif)|*.tif|" #endif #if wxUSE_PCX "PCX files (*.pcx)|*.pcx|" #endif #if wxUSE_XPM "X PixMap files (*.xpm)|*.xpm|" #endif "ICO files (*.ico)|*.ico|" "CUR files (*.cur)|*.cur", wxFD_SAVE | wxFD_OVERWRITE_PROMPT, this); if ( savefilename.empty() ) return; wxString extension; wxFileName::SplitPath(savefilename, NULL, NULL, &extension); bool saved = false; if ( extension == "bmp" ) { static const int bppvalues[] = { wxBMP_1BPP, wxBMP_1BPP_BW, wxBMP_4BPP, wxBMP_8BPP, wxBMP_8BPP_GREY, wxBMP_8BPP_RED, #if wxUSE_PALETTE wxBMP_8BPP_PALETTE, #endif // wxUSE_PALETTE wxBMP_24BPP }; const wxString bppchoices[] = { "1 bpp color", "1 bpp B&W", "4 bpp color", "8 bpp color", "8 bpp greyscale", "8 bpp red", #if wxUSE_PALETTE "8 bpp own palette", #endif // wxUSE_PALETTE "24 bpp" }; int bppselection = wxGetSingleChoiceIndex("Set BMP BPP", "Image sample: save file", WXSIZEOF(bppchoices), bppchoices, this); if ( bppselection != -1 ) { int format = bppvalues[bppselection]; image.SetOption(wxIMAGE_OPTION_BMP_FORMAT, format); #if wxUSE_PALETTE if ( format == wxBMP_8BPP_PALETTE ) { unsigned char *cmap = new unsigned char [256]; for ( int i = 0; i < 256; i++ ) cmap[i] = (unsigned char)i; image.SetPalette(wxPalette(256, cmap, cmap, cmap)); delete[] cmap; } #endif // wxUSE_PALETTE } } #if wxUSE_LIBPNG else if ( extension == "png" ) { static const int pngvalues[] = { wxPNG_TYPE_COLOUR, wxPNG_TYPE_COLOUR, wxPNG_TYPE_GREY, wxPNG_TYPE_GREY, wxPNG_TYPE_GREY_RED, wxPNG_TYPE_GREY_RED, }; const wxString pngchoices[] = { "Colour 8bpp", "Colour 16bpp", "Grey 8bpp", "Grey 16bpp", "Grey red 8bpp", "Grey red 16bpp", }; int sel = wxGetSingleChoiceIndex("Set PNG format", "Image sample: save file", WXSIZEOF(pngchoices), pngchoices, this); if ( sel != -1 ) { image.SetOption(wxIMAGE_OPTION_PNG_FORMAT, pngvalues[sel]); image.SetOption(wxIMAGE_OPTION_PNG_BITDEPTH, sel % 2 ? 16 : 8); // these values are taken from OptiPNG with -o3 switch const wxString compressionChoices[] = { "compression = 9, memory = 8, strategy = 0, filter = 0", "compression = 9, memory = 9, strategy = 0, filter = 0", "compression = 9, memory = 8, strategy = 1, filter = 0", "compression = 9, memory = 9, strategy = 1, filter = 0", "compression = 1, memory = 8, strategy = 2, filter = 0", "compression = 1, memory = 9, strategy = 2, filter = 0", "compression = 9, memory = 8, strategy = 0, filter = 5", "compression = 9, memory = 9, strategy = 0, filter = 5", "compression = 9, memory = 8, strategy = 1, filter = 5", "compression = 9, memory = 9, strategy = 1, filter = 5", "compression = 1, memory = 8, strategy = 2, filter = 5", "compression = 1, memory = 9, strategy = 2, filter = 5", }; sel = wxGetSingleChoiceIndex("Select compression option (Cancel to use default)\n", "PNG Compression Options", WXSIZEOF(compressionChoices), compressionChoices, this); if ( sel != -1 ) { const int zc[] = {9, 9, 9, 9, 1, 1, 9, 9, 9, 9, 1, 1}; const int zm[] = {8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9}; const int zs[] = {0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2}; const int f[] = {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8}; image.SetOption(wxIMAGE_OPTION_PNG_COMPRESSION_LEVEL , zc[sel]); image.SetOption(wxIMAGE_OPTION_PNG_COMPRESSION_MEM_LEVEL , zm[sel]); image.SetOption(wxIMAGE_OPTION_PNG_COMPRESSION_STRATEGY , zs[sel]); image.SetOption(wxIMAGE_OPTION_PNG_FILTER , f[sel]); image.SetOption(wxIMAGE_OPTION_PNG_COMPRESSION_BUFFER_SIZE, 1048576); // 1 MB } } } #endif // wxUSE_LIBPNG else if ( extension == "cur" ) { image.Rescale(32,32); image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_X, 0); image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y, 0); // This shows how you can save an image with explicitly // specified image format: saved = image.SaveFile(savefilename, wxBITMAP_TYPE_CUR); } if ( !saved ) { // This one guesses image format from filename extension // (it may fail if the extension is not recognized): image.SaveFile(savefilename); } #endif // wxUSE_FILEDLG } void OnResize(wxCommandEvent& WXUNUSED(event)) { wxImage img(m_bitmap.ConvertToImage()); const wxSize size = GetClientSize(); img.Rescale(size.x, size.y, wxIMAGE_QUALITY_HIGH); m_bitmap = wxBitmap(img); UpdateStatusBar(); } void OnZoom(wxCommandEvent& event) { if ( event.GetId() == wxID_ZOOM_IN ) m_zoom *= 1.2; else if ( event.GetId() == wxID_ZOOM_OUT ) m_zoom /= 1.2; else // wxID_ZOOM_100 m_zoom = 1.; UpdateStatusBar(); } void OnRotate(wxCommandEvent& event) { double angle = 5; if ( event.GetId() == ID_ROTATE_LEFT ) angle = -angle; wxImage img(m_bitmap.ConvertToImage()); img = img.Rotate(angle, wxPoint(img.GetWidth() / 2, img.GetHeight() / 2)); if ( !img.IsOk() ) { wxLogWarning("Rotation failed"); return; } m_bitmap = wxBitmap(img); UpdateStatusBar(); } void UpdateStatusBar() { wxLogStatus(this, "Image size: (%d, %d), zoom %.2f", m_bitmap.GetWidth(), m_bitmap.GetHeight(), m_zoom); Refresh(); } wxBitmap m_bitmap; double m_zoom; wxDECLARE_EVENT_TABLE(); }; #ifdef wxHAVE_RAW_BITMAP #include "wx/rawbmp.h" class MyRawBitmapFrame : public wxFrame { public: enum { BORDER = 15, SIZE = 150, REAL_SIZE = SIZE - 2*BORDER }; MyRawBitmapFrame(wxFrame *parent) : wxFrame(parent, wxID_ANY, "Raw bitmaps (how exciting)"), m_bitmap(SIZE, SIZE, 24), m_alphaBitmap(SIZE, SIZE, 32) { SetClientSize(SIZE, SIZE*2+25); InitAlphaBitmap(); InitBitmap(); } void InitAlphaBitmap() { // First, clear the whole bitmap by making it alpha { wxAlphaPixelData data( m_alphaBitmap, wxPoint(0,0), wxSize(SIZE, SIZE) ); if ( !data ) { wxLogError("Failed to gain raw access to bitmap data"); return; } wxAlphaPixelData::Iterator p(data); for ( int y = 0; y < SIZE; ++y ) { wxAlphaPixelData::Iterator rowStart = p; for ( int x = 0; x < SIZE; ++x ) { p.Alpha() = 0; ++p; // same as p.OffsetX(1) } p = rowStart; p.OffsetY(data, 1); } } // Then, draw colourful alpha-blended stripes wxAlphaPixelData data(m_alphaBitmap, wxPoint(BORDER, BORDER), wxSize(REAL_SIZE, REAL_SIZE)); if ( !data ) { wxLogError("Failed to gain raw access to bitmap data"); return; } wxAlphaPixelData::Iterator p(data); for ( int y = 0; y < REAL_SIZE; ++y ) { wxAlphaPixelData::Iterator rowStart = p; int r = y < REAL_SIZE/3 ? 255 : 0, g = (REAL_SIZE/3 <= y) && (y < 2*(REAL_SIZE/3)) ? 255 : 0, b = 2*(REAL_SIZE/3) <= y ? 255 : 0; for ( int x = 0; x < REAL_SIZE; ++x ) { // note that RGB must be premultiplied by alpha unsigned a = (wxAlphaPixelData::Iterator::ChannelType)((x*255.)/REAL_SIZE); p.Red() = r * a / 256; p.Green() = g * a / 256; p.Blue() = b * a / 256; p.Alpha() = a; ++p; // same as p.OffsetX(1) } p = rowStart; p.OffsetY(data, 1); } } void InitBitmap() { // draw some colourful stripes without alpha wxNativePixelData data(m_bitmap); if ( !data ) { wxLogError("Failed to gain raw access to bitmap data"); return; } wxNativePixelData::Iterator p(data); for ( int y = 0; y < SIZE; ++y ) { wxNativePixelData::Iterator rowStart = p; int r = y < SIZE/3 ? 255 : 0, g = (SIZE/3 <= y) && (y < 2*(SIZE/3)) ? 255 : 0, b = 2*(SIZE/3) <= y ? 255 : 0; for ( int x = 0; x < SIZE; ++x ) { p.Red() = r; p.Green() = g; p.Blue() = b; ++p; // same as p.OffsetX(1) } p = rowStart; p.OffsetY(data, 1); } } void OnPaint(wxPaintEvent& WXUNUSED(event)) { wxPaintDC dc( this ); dc.DrawText("This is alpha and raw bitmap test", 0, BORDER); dc.DrawText("This is alpha and raw bitmap test", 0, SIZE/2 - BORDER); dc.DrawText("This is alpha and raw bitmap test", 0, SIZE - 2*BORDER); dc.DrawBitmap( m_alphaBitmap, 0, 0, true /* use mask */ ); dc.DrawText("Raw bitmap access without alpha", 0, SIZE+5); dc.DrawBitmap( m_bitmap, 0, SIZE+5+dc.GetCharHeight()); } private: wxBitmap m_bitmap; wxBitmap m_alphaBitmap; wxDECLARE_EVENT_TABLE(); }; #endif // wxHAVE_RAW_BITMAP // ============================================================================ // implementations // ============================================================================ //----------------------------------------------------------------------------- // MyImageFrame //----------------------------------------------------------------------------- wxBEGIN_EVENT_TABLE(MyImageFrame, wxFrame) EVT_ERASE_BACKGROUND(MyImageFrame::OnEraseBackground) EVT_PAINT(MyImageFrame::OnPaint) EVT_MENU(wxID_SAVEAS, MyImageFrame::OnSave) EVT_MENU_RANGE(ID_ROTATE_LEFT, ID_ROTATE_RIGHT, MyImageFrame::OnRotate) EVT_MENU(ID_RESIZE, MyImageFrame::OnResize) EVT_MENU(wxID_ZOOM_IN, MyImageFrame::OnZoom) EVT_MENU(wxID_ZOOM_OUT, MyImageFrame::OnZoom) EVT_MENU(wxID_ZOOM_100, MyImageFrame::OnZoom) wxEND_EVENT_TABLE() //----------------------------------------------------------------------------- // MyRawBitmapFrame //----------------------------------------------------------------------------- #ifdef wxHAVE_RAW_BITMAP wxBEGIN_EVENT_TABLE(MyRawBitmapFrame, wxFrame) EVT_PAINT(MyRawBitmapFrame::OnPaint) wxEND_EVENT_TABLE() #endif // wxHAVE_RAW_BITMAP //----------------------------------------------------------------------------- // MyFrame //----------------------------------------------------------------------------- enum { ID_QUIT = wxID_EXIT, ID_ABOUT = wxID_ABOUT, ID_NEW = 100, ID_NEW_HIDPI, ID_INFO, ID_SHOWRAW, ID_GRAPHICS, ID_SHOWTHUMBNAIL }; wxIMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame ); wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU (ID_ABOUT, MyFrame::OnAbout) EVT_MENU (ID_QUIT, MyFrame::OnQuit) EVT_MENU (ID_NEW, MyFrame::OnNewFrame) EVT_MENU (ID_NEW_HIDPI, MyFrame::OnNewFrameHiDPI) EVT_MENU (ID_INFO, MyFrame::OnImageInfo) EVT_MENU (ID_SHOWTHUMBNAIL, MyFrame::OnThumbnail) #ifdef wxHAVE_RAW_BITMAP EVT_MENU (ID_SHOWRAW, MyFrame::OnTestRawBitmap) #endif #if wxUSE_GRAPHICS_CONTEXT EVT_MENU (ID_GRAPHICS, MyFrame::OnTestGraphics) #endif // wxUSE_GRAPHICS_CONTEXT #if wxUSE_CLIPBOARD EVT_MENU(wxID_COPY, MyFrame::OnCopy) EVT_MENU(wxID_PASTE, MyFrame::OnPaste) #endif // wxUSE_CLIPBOARD EVT_UPDATE_UI(ID_NEW_HIDPI, MyFrame::OnUpdateNewFrameHiDPI) wxEND_EVENT_TABLE() MyFrame::MyFrame() : wxFrame( (wxFrame *)NULL, wxID_ANY, "wxImage sample", wxPoint(20, 20), wxSize(950, 700) ) { SetIcon(wxICON(sample)); wxMenuBar *menu_bar = new wxMenuBar(); wxMenu *menuImage = new wxMenu; menuImage->Append( ID_NEW, "&Show any image...\tCtrl-O"); menuImage->Append(ID_NEW_HIDPI, "Show any image as &HiDPI...\tCtrl-H"); menuImage->Append( ID_INFO, "Show image &information...\tCtrl-I"); #ifdef wxHAVE_RAW_BITMAP menuImage->AppendSeparator(); menuImage->Append( ID_SHOWRAW, "Test &raw bitmap...\tCtrl-R"); #endif #if wxUSE_GRAPHICS_CONTEXT menuImage->AppendSeparator(); menuImage->Append(ID_GRAPHICS, "Test &graphics context...\tCtrl-G"); #endif // wxUSE_GRAPHICS_CONTEXT menuImage->AppendSeparator(); menuImage->Append( ID_SHOWTHUMBNAIL, "Test &thumbnail...\tCtrl-T", "Test scaling the image during load (try with JPEG)"); menuImage->AppendSeparator(); menuImage->Append( ID_ABOUT, "&About\tF1"); menuImage->AppendSeparator(); menuImage->Append( ID_QUIT, "E&xit\tCtrl-Q"); menu_bar->Append(menuImage, "&Image"); #if wxUSE_CLIPBOARD wxMenu *menuClipboard = new wxMenu; menuClipboard->Append(wxID_COPY, "&Copy test image\tCtrl-C"); menuClipboard->Append(wxID_PASTE, "&Paste image\tCtrl-V"); menu_bar->Append(menuClipboard, "&Clipboard"); #endif // wxUSE_CLIPBOARD SetMenuBar( menu_bar ); #if wxUSE_STATUSBAR CreateStatusBar(2); int widths[] = { -1, 100 }; SetStatusWidths( 2, widths ); #endif // wxUSE_STATUSBAR m_canvas = new MyCanvas( this, wxID_ANY, wxPoint(0,0), wxSize(10,10) ); // 500 width * 2750 height m_canvas->SetScrollbars( 10, 10, 50, 275 ); m_canvas->SetCursor(wxImage("cursor.png")); } void MyFrame::OnQuit( wxCommandEvent &WXUNUSED(event) ) { Close( true ); } #if wxUSE_ZLIB && wxUSE_STREAMS #include "wx/zstream.h" #endif void MyFrame::OnAbout( wxCommandEvent &WXUNUSED(event) ) { wxArrayString array; array.Add("wxImage demo"); array.Add("(c) Robert Roebling 1998-2005"); array.Add("(c) Vadim Zeitlin 2005-2009"); array.Add(wxEmptyString); array.Add("Version of the libraries used:"); #if wxUSE_LIBPNG array.Add(wxPNGHandler::GetLibraryVersionInfo().ToString()); #endif #if wxUSE_LIBJPEG array.Add(wxJPEGHandler::GetLibraryVersionInfo().ToString()); #endif #if wxUSE_LIBTIFF array.Add(wxTIFFHandler::GetLibraryVersionInfo().ToString()); #endif #if wxUSE_ZLIB && wxUSE_STREAMS // zlib is used by libpng array.Add(wxGetZlibVersionInfo().ToString()); #endif (void)wxMessageBox( wxJoin(array, '\n'), "About wxImage Demo", wxICON_INFORMATION | wxOK ); } wxString MyFrame::LoadUserImage(wxImage& image) { wxString filename; #if wxUSE_FILEDLG filename = wxLoadFileSelector("image", wxEmptyString); if ( !filename.empty() ) { if ( !image.LoadFile(filename) ) { wxLogError("Couldn't load image from '%s'.", filename); return wxEmptyString; } } #endif // wxUSE_FILEDLG return filename; } void MyFrame::OnNewFrame( wxCommandEvent &WXUNUSED(event) ) { wxImage image; wxString filename = LoadUserImage(image); if ( !filename.empty() ) new MyImageFrame(this, filename, image); } void MyFrame::OnNewFrameHiDPI(wxCommandEvent&) { wxImage image; wxString filename = LoadUserImage(image); if (!filename.empty()) new MyImageFrame(this, filename, image, GetContentScaleFactor()); } void MyFrame::OnUpdateNewFrameHiDPI(wxUpdateUIEvent& event) { event.Enable(GetContentScaleFactor() > 1); } void MyFrame::OnImageInfo( wxCommandEvent &WXUNUSED(event) ) { wxImage image; if ( !LoadUserImage(image).empty() ) { // TODO: show more information about the file wxString info = wxString::Format("Image size: %dx%d", image.GetWidth(), image.GetHeight()); int xres = image.GetOptionInt(wxIMAGE_OPTION_RESOLUTIONX), yres = image.GetOptionInt(wxIMAGE_OPTION_RESOLUTIONY); if ( xres || yres ) { info += wxString::Format("\nResolution: %dx%d", xres, yres); switch ( image.GetOptionInt(wxIMAGE_OPTION_RESOLUTIONUNIT) ) { default: wxFAIL_MSG( "unknown image resolution units" ); wxFALLTHROUGH; case wxIMAGE_RESOLUTION_NONE: info += " in default units"; break; case wxIMAGE_RESOLUTION_INCHES: info += " in"; break; case wxIMAGE_RESOLUTION_CM: info += " cm"; break; } } wxLogMessage("%s", info); } } #ifdef wxHAVE_RAW_BITMAP void MyFrame::OnTestRawBitmap( wxCommandEvent &WXUNUSED(event) ) { (new MyRawBitmapFrame(this))->Show(); } #endif // wxHAVE_RAW_BITMAP #if wxUSE_GRAPHICS_CONTEXT class MyGraphicsFrame : public wxFrame { public: enum { WIDTH = 256, HEIGHT = 90 }; MyGraphicsFrame(wxWindow* parent) : wxFrame(parent, wxID_ANY, "Graphics context test"), m_image(WIDTH, HEIGHT, false) { // Create a test image: it has 3 horizontal primary colour bands with // alpha increasing from left to right. m_image.SetAlpha(); unsigned char* alpha = m_image.GetAlpha(); unsigned char* data = m_image.GetData(); for ( int y = 0; y < HEIGHT; y++ ) { unsigned char r = 0, g = 0, b = 0; if ( y < HEIGHT/3 ) r = 0xff; else if ( y < (2*HEIGHT)/3 ) g = 0xff; else b = 0xff; for ( int x = 0; x < WIDTH; x++ ) { *alpha++ = x; *data++ = r; *data++ = g; *data++ = b; } } m_bitmap = wxBitmap(m_image); Bind(wxEVT_PAINT, &MyGraphicsFrame::OnPaint, this); Show(); } private: void OnPaint(wxPaintEvent& WXUNUSED(event)) { wxPaintDC dc(this); wxScopedPtr gc(wxGraphicsContext::Create(dc)); wxGraphicsBitmap gb(gc->CreateBitmapFromImage(m_image)); gc->SetFont(*wxNORMAL_FONT, *wxBLACK); gc->DrawText("Bitmap", 0, HEIGHT/2); gc->DrawBitmap(m_bitmap, 0, 0, WIDTH, HEIGHT); wxGraphicsFont gf = gc->CreateFont(wxNORMAL_FONT->GetPixelSize().y, ""); gc->SetFont(gf); gc->DrawText("Graphics bitmap", 0, (3*HEIGHT)/2); gc->DrawBitmap(gb, 0, HEIGHT, WIDTH, HEIGHT); } wxImage m_image; wxBitmap m_bitmap; wxDECLARE_NO_COPY_CLASS(MyGraphicsFrame); }; void MyFrame::OnTestGraphics(wxCommandEvent& WXUNUSED(event)) { new MyGraphicsFrame(this); } #endif // wxUSE_GRAPHICS_CONTEXT #if wxUSE_CLIPBOARD void MyFrame::OnCopy(wxCommandEvent& WXUNUSED(event)) { wxBitmapDataObject *dobjBmp = new wxBitmapDataObject; dobjBmp->SetBitmap(m_canvas->my_horse_png); wxTheClipboard->Open(); if ( !wxTheClipboard->SetData(dobjBmp) ) { wxLogError("Failed to copy bitmap to clipboard"); } wxTheClipboard->Close(); } void MyFrame::OnPaste(wxCommandEvent& WXUNUSED(event)) { wxBitmapDataObject dobjBmp; wxTheClipboard->Open(); if ( !wxTheClipboard->GetData(dobjBmp) ) { wxLogMessage("No bitmap data in the clipboard"); } else { new MyImageFrame(this, "Clipboard", dobjBmp.GetBitmap()); } wxTheClipboard->Close(); } #endif // wxUSE_CLIPBOARD void MyFrame::OnThumbnail( wxCommandEvent &WXUNUSED(event) ) { #if wxUSE_FILEDLG wxString filename = wxLoadFileSelector("image", wxEmptyString, wxEmptyString, this); if ( filename.empty() ) return; static const int THUMBNAIL_WIDTH = 320; static const int THUMBNAIL_HEIGHT = 240; wxImage image; image.SetOption(wxIMAGE_OPTION_MAX_WIDTH, THUMBNAIL_WIDTH); image.SetOption(wxIMAGE_OPTION_MAX_HEIGHT, THUMBNAIL_HEIGHT); wxStopWatch sw; if ( !image.LoadFile(filename) ) { wxLogError("Couldn't load image from '%s'.", filename); return; } int origWidth = image.GetOptionInt( wxIMAGE_OPTION_ORIGINAL_WIDTH ); int origHeight = image.GetOptionInt( wxIMAGE_OPTION_ORIGINAL_HEIGHT ); const long loadTime = sw.Time(); MyImageFrame * const frame = new MyImageFrame(this, filename, image); wxLogStatus(frame, "Loaded \"%s\" in %ldms; original size was (%d, %d)", filename, loadTime, origWidth, origHeight); #else wxLogError( "Couldn't create file selector dialog" ); return; #endif // wxUSE_FILEDLG } //----------------------------------------------------------------------------- // MyApp //----------------------------------------------------------------------------- wxIMPLEMENT_APP(MyApp); bool MyApp::OnInit() { if ( !wxApp::OnInit() ) return false; wxInitAllImageHandlers(); wxFrame *frame = new MyFrame(); frame->Show( true ); return true; }