wxWidgets实现图片浏览、放大缩小、另存为新的图片格式等
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/filename.h"
#include "wx/zstream.h"
#include "imageviewctrl.h"
class MyFrame : public wxFrame
{
public:
MyFrame(wxWindow* parent,
wxWindowID id,
const wxString& title,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxDEFAULT_FRAME_STYLE | wxSUNKEN_BORDER,
ImageViewCtrl* imageview = NULL);
private:
wxString 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 OnOpen(wxCommandEvent& WXUNUSED(event))
{
wxImage image;
wxString filename = LoadUserImage(image);
if (!filename.empty())
{
this->image_view_ctrl_->SetBitmap(wxBitmap(image));
}
this->Refresh();
}
void OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close(true);
}
void OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxArrayString array;
array.Add("ImageView demo");
array.Add(wxT("交流QQ群:747166657"));
array.Add(wxT("QQ:1083969551"));
array.Add(wxT("Email:[email protected]"));
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 ImageView Demo",
wxICON_INFORMATION | wxOK);
}
void OnSave(wxCommandEvent& WXUNUSED(event))
{
#if wxUSE_FILEDLG
const wxBitmap& bitmap = this->image_view_ctrl_->GetBitmap();
wxImage image = 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 OnSize(wxSizeEvent& event)
{
//event.GetSize();
wxLogDebug("MyFrame OnSize");
wxSize size = this->GetClientSize();
wxLogDebug("MyFrame.w=%d, MyFrame.h=%d", size.x, size.y);
wxLogStatus(this, "Size size: (%d, %d), ClientSize size: (%d, %d)",
GetSize().x,
GetSize().y,
size.x,size.y);
if (image_view_ctrl_)
{
image_view_ctrl_->SetSize(10, 10, size.x-20, size.y-20);
}
event.Skip();
}
ImageViewCtrl* image_view_ctrl_;// = NULL;
wxDECLARE_EVENT_TABLE();
};
// ============================================================================
// implementations
// ============================================================================
//-----------------------------------------------------------------------------
// MyFrame
//-----------------------------------------------------------------------------
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
EVT_MENU(wxID_OPEN, MyFrame::OnOpen)
EVT_MENU(wxID_EXIT, MyFrame::OnQuit)
EVT_MENU(wxID_SAVEAS, MyFrame::OnSave)
EVT_SIZE(MyFrame::OnSize)
wxEND_EVENT_TABLE()
MyFrame::MyFrame(wxWindow* parent,
wxWindowID id,
const wxString& title,
const wxPoint& pos,
const wxSize& size,
long style,
ImageViewCtrl* imageview)
: wxFrame(parent, id, title, pos, size, style | wxFULL_REPAINT_ON_RESIZE), image_view_ctrl_(imageview)
{
wxMenu* fileMenu = new wxMenu;
fileMenu->Append(wxID_OPEN);
fileMenu->Append(wxID_EXIT);
fileMenu->Append(wxID_SAVEAS);
wxMenu* helpMenu = new wxMenu;
helpMenu->Append(wxID_ABOUT, "&About\tCtrl-O");
wxMenuBar* menuBar = new wxMenuBar;
menuBar->Append(fileMenu, "&File");
menuBar->Append(helpMenu, "&Help");
SetMenuBar(menuBar);
CreateStatusBar(1);
SetMinSize(wxSize(640, 480));
this->SetBackgroundColour(*wxRED);
wxPanel * panel = new wxPanel(this, wxID_ANY, wxPoint(0,0), GetClientSize());
image_view_ctrl_ = new ImageViewCtrl(panel, wxID_ANY, wxDefaultPosition, GetClientSize());
}
//-----------------------------------------------------------------------------
// MyApp
//-----------------------------------------------------------------------------
// declare
class MyApp: public wxApp
{
public:
virtual bool OnInit() wxOVERRIDE;
};
// implement
wxIMPLEMENT_APP(MyApp);
bool MyApp::OnInit()
{
if ( !wxApp::OnInit() )
return false;
wxInitAllImageHandlers();
wxFrame *frame = new MyFrame(NULL, wxID_ANY, "ImageView Demo", wxDefaultPosition, wxWindow::FromDIP(wxSize(900, 600), NULL), wxDEFAULT_FRAME_STYLE | wxSIMPLE_BORDER);
frame->Show();
return true;
}