summaryrefslogtreecommitdiffstats
path: root/examples/showimg
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:24:15 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:24:15 -0500
commitbd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch)
tree7a520322212d48ebcb9fbe1087e7fca28b76185c /examples/showimg
downloadqt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz
qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip
Add Qt3 development HEAD version
Diffstat (limited to 'examples/showimg')
-rw-r--r--examples/showimg/README14
-rw-r--r--examples/showimg/imagefip.cpp61
-rw-r--r--examples/showimg/imagefip.h31
-rw-r--r--examples/showimg/imagetexteditor.cpp141
-rw-r--r--examples/showimg/imagetexteditor.h46
-rw-r--r--examples/showimg/main.cpp56
-rw-r--r--examples/showimg/showimg.cpp672
-rw-r--r--examples/showimg/showimg.doc29
-rw-r--r--examples/showimg/showimg.h93
-rw-r--r--examples/showimg/showimg.pro14
10 files changed, 1157 insertions, 0 deletions
diff --git a/examples/showimg/README b/examples/showimg/README
new file mode 100644
index 0000000..a6c9ca9
--- /dev/null
+++ b/examples/showimg/README
@@ -0,0 +1,14 @@
+This example demonstrates how to read in and display images, and the
+conversion facilities available. The CuteWidget can read a file into
+a pixmap and resizes the displayed pixmap when the widget is resized.
+
+Note that the function CuteWidget::paintEvent uses the drawPixmap function
+of QPainter to display the pixmap, the bitBlt function can also be used to
+display pixmaps.
+
+If you have installed the Qt imageio extension (see extensions/imageio
+in your Qt directory), you can build using that extension.
+
+Some of the conversion options will have no effect, depending on the
+display hardware used. Generally, these are disabled.
+
diff --git a/examples/showimg/imagefip.cpp b/examples/showimg/imagefip.cpp
new file mode 100644
index 0000000..c7f3f2f
--- /dev/null
+++ b/examples/showimg/imagefip.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#include "imagefip.h"
+#include <qimage.h>
+
+/* XPM */
+static const char *image_xpm[] = {
+"17 15 9 1",
+" c #7F7F7F",
+". c #FFFFFF",
+"X c #00B6FF",
+"o c #BFBFBF",
+"O c #FF6C00",
+"+ c #000000",
+"@ c #0000FF",
+"# c #6CFF00",
+"$ c #FFB691",
+" ..XX",
+" ........o .XXX",
+" .OOOOOOOo. XXX+",
+" .O@@@@@@+++XXX++",
+" .O@@@@@@O.XXX+++",
+" .O@@@@@@OXXX+++.",
+" .O######XXX++...",
+" .O#####XXX++....",
+" .O##$#$XX+o+....",
+" .O#$$$$$+.o+....",
+" .O##$$##O.o+....",
+" .OOOOOOOO.o+....",
+" ..........o+....",
+" ooooooooooo+....",
+"+++++++++++++...."
+};
+
+ImageIconProvider::ImageIconProvider( QWidget *parent, const char *name ) :
+ QFileIconProvider( parent, name ),
+ imagepm(image_xpm)
+{
+ fmts = QImage::inputFormats();
+}
+
+ImageIconProvider::~ImageIconProvider()
+{
+}
+
+const QPixmap * ImageIconProvider::pixmap( const QFileInfo &fi )
+{
+ QString ext = fi.extension().upper();
+ if ( fmts.contains(ext) ) {
+ return &imagepm;
+ } else {
+ return QFileIconProvider::pixmap(fi);
+ }
+}
diff --git a/examples/showimg/imagefip.h b/examples/showimg/imagefip.h
new file mode 100644
index 0000000..d4710da
--- /dev/null
+++ b/examples/showimg/imagefip.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#ifndef IMAGEFIP_H
+#define IMAGEFIP_H
+
+#include <qfiledialog.h>
+#include <qstrlist.h>
+#include <qpixmap.h>
+
+class ImageIconProvider : public QFileIconProvider
+{
+ Q_OBJECT
+ QStrList fmts;
+ QPixmap imagepm;
+
+public:
+ ImageIconProvider( QWidget *parent=0, const char *name=0 );
+ ~ImageIconProvider();
+
+ const QPixmap * pixmap( const QFileInfo &fi );
+};
+
+
+#endif // IMAGEFIP_H
diff --git a/examples/showimg/imagetexteditor.cpp b/examples/showimg/imagetexteditor.cpp
new file mode 100644
index 0000000..b3f34d9
--- /dev/null
+++ b/examples/showimg/imagetexteditor.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#include "imagetexteditor.h"
+#include <qimage.h>
+#include <qlayout.h>
+#include <qgrid.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qcombobox.h>
+#include <qmultilineedit.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qlistbox.h>
+#include <qpushbutton.h>
+
+
+ImageTextEditor::ImageTextEditor( QImage& i, QWidget *parent, const char *name, WFlags f ) :
+ QDialog(parent,name,TRUE,f),
+ image(i)
+{
+ QVBoxLayout* vbox = new QVBoxLayout(this,8);
+ vbox->setAutoAdd(TRUE);
+
+ QGrid* controls = new QGrid(3,QGrid::Horizontal,this);
+ controls->setSpacing(8);
+ QLabel* l;
+ l=new QLabel("Language",controls); l->setAlignment(AlignCenter);
+ l=new QLabel("Key",controls); l->setAlignment(AlignCenter);
+ (void)new QLabel("",controls); // dummy
+ languages = new QComboBox(controls);
+ keys = new QComboBox(controls);
+ QPushButton* remove = new QPushButton("Remove",controls);
+
+ newlang = new QLineEdit(controls);
+ newkey = new QLineEdit(controls);
+ QPushButton* add = new QPushButton("Add",controls);
+
+ text = new QMultiLineEdit(this);
+
+ QHBox* hbox = new QHBox(this);
+ QPushButton* cancel = new QPushButton("Cancel",hbox);
+ QPushButton* ok = new QPushButton("OK",hbox);
+
+ connect(add,SIGNAL(clicked()),
+ this,SLOT(addText()));
+
+ connect(remove,SIGNAL(clicked()),
+ this,SLOT(removeText()));
+
+ connect(ok,SIGNAL(clicked()),
+ this,SLOT(accept()));
+
+ connect(cancel,SIGNAL(clicked()),
+ this,SLOT(reject()));
+
+ connect(languages,SIGNAL(activated(int)),
+ this,SLOT(updateText()));
+
+ connect(keys,SIGNAL(activated(int)),
+ this,SLOT(updateText()));
+
+ imageChanged();
+}
+
+ImageTextEditor::~ImageTextEditor()
+{
+}
+
+void ImageTextEditor::imageChanged()
+{
+ languages->clear();
+ keys->clear();
+ text->clear();
+ languages->insertItem("<any>");
+
+ languages->insertStringList(image.textLanguages());
+ keys->insertStringList(image.textKeys());
+
+ updateText();
+}
+
+void ImageTextEditor::accept()
+{
+ storeText();
+ QDialog::accept();
+}
+
+void ImageTextEditor::updateText()
+{
+ storeText();
+ newlang->setText(languages->currentText());
+ newkey->setText(keys->currentText());
+ QString t = image.text(currKey(),currLang());
+
+ text->setText(t);
+}
+
+QString ImageTextEditor::currKey()
+{
+ return newkey->text();
+}
+
+QString ImageTextEditor::currLang()
+{
+ QString l = newlang->text();
+ if ( l=="<any>" )
+ l = QString::null;
+ return l;
+}
+
+QString ImageTextEditor::currText()
+{
+ QString t = text->text();
+ if ( t.isNull() ) t = "";
+ return t;
+}
+
+
+void ImageTextEditor::removeText()
+{
+ image.setText(currKey(),currLang(),QString::null);
+}
+
+void ImageTextEditor::addText()
+{
+ storeText();
+}
+
+void ImageTextEditor::storeText()
+{
+ if ( currKey().length() > 0 ) {
+ image.setText(currKey(),currLang(),currText());
+ }
+}
diff --git a/examples/showimg/imagetexteditor.h b/examples/showimg/imagetexteditor.h
new file mode 100644
index 0000000..0153771
--- /dev/null
+++ b/examples/showimg/imagetexteditor.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#ifndef IMAGETEXTEDITOR_H
+#define IMAGETEXTEDITOR_H
+
+#include <qdialog.h>
+
+class QImage;
+class QComboBox;
+class QListBox;
+class QLineEdit;
+class QMultiLineEdit;
+
+class ImageTextEditor : public QDialog
+{
+ Q_OBJECT
+public:
+ ImageTextEditor( QImage& i, QWidget *parent=0, const char *name=0, WFlags f=0 );
+ ~ImageTextEditor();
+ void accept();
+public slots:
+ void imageChanged();
+ void updateText();
+ void addText();
+ void removeText();
+private:
+ void storeText();
+ QImage& image;
+ QComboBox* languages;
+ QComboBox* keys;
+ QMultiLineEdit* text;
+ QLineEdit* newlang;
+ QLineEdit* newkey;
+ QString currKey();
+ QString currLang();
+ QString currText();
+};
+
+#endif // IMAGETEXTEDITOR_H
diff --git a/examples/showimg/main.cpp b/examples/showimg/main.cpp
new file mode 100644
index 0000000..5ee9503
--- /dev/null
+++ b/examples/showimg/main.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#include "showimg.h"
+#include "imagefip.h"
+#include <qapplication.h>
+#include <qimage.h>
+
+int main( int argc, char **argv )
+{
+ if ( argc > 1 && QString(argv[1]) == "-m" ) {
+ QApplication::setColorSpec( QApplication::ManyColor );
+ argc--;
+ argv++;
+ }
+ else if ( argc > 1 && QString(argv[1]) == "-n" ) {
+ QApplication::setColorSpec( QApplication::NormalColor );
+ argc--;
+ argv++;
+ }
+ else {
+ QApplication::setColorSpec( QApplication::CustomColor );
+ }
+
+ QApplication a( argc, argv );
+
+ ImageIconProvider iip;
+ QFileDialog::setIconProvider( &iip );
+
+ if ( argc <= 1 ) {
+ // Create a window which looks after its own existence.
+ ImageViewer *w =
+ new ImageViewer(0, "new window", Qt::WDestructiveClose | Qt::WResizeNoErase );
+ w->setCaption("Qt Example - Image Viewer");
+ w->show();
+ } else {
+ for ( int i=1; i<argc; i++ ) {
+ // Create a window which looks after its own existence.
+ ImageViewer *w =
+ new ImageViewer(0, argv[i], Qt::WDestructiveClose | Qt::WResizeNoErase );
+ w->setCaption("Qt Example - Image Viewer");
+ w->loadImage( argv[i] );
+ w->show();
+ }
+ }
+
+ QObject::connect(qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()));
+
+ return a.exec();
+}
diff --git a/examples/showimg/showimg.cpp b/examples/showimg/showimg.cpp
new file mode 100644
index 0000000..1ee9847
--- /dev/null
+++ b/examples/showimg/showimg.cpp
@@ -0,0 +1,672 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#include "showimg.h"
+#include "imagetexteditor.h"
+#include <qmenubar.h>
+#include <qfiledialog.h>
+#include <qmessagebox.h>
+#include <qpopupmenu.h>
+#include <qlabel.h>
+#include <qpainter.h>
+#include <qapplication.h>
+#include <qclipboard.h>
+
+
+/*
+ In the constructor, we just pass the standard parameters on to
+ QWidget.
+
+ The menu uses a single slot to simplify the process of adding
+ more items to the options menu.
+*/
+ImageViewer::ImageViewer( QWidget *parent, const char *name, int wFlags )
+ : QWidget( parent, name, wFlags ),
+ conversion_flags( PreferDither ),
+ helpmsg( 0 )
+{
+ pickx = -1;
+ picky = -1;
+ clickx = -1;
+ clicky = -1;
+ alloc_context = 0;
+
+ menubar = new QMenuBar(this);
+ menubar->setSeparator( QMenuBar::InWindowsStyle );
+
+ QStrList fmt = QImage::outputFormats();
+ saveimage = new QPopupMenu( menubar );
+ savepixmap = new QPopupMenu( menubar );
+ for (const char* f = fmt.first(); f; f = fmt.next()) {
+ saveimage->insertItem( f );
+ savepixmap->insertItem( f );
+ }
+ connect( saveimage, SIGNAL(activated(int)), this, SLOT(saveImage(int)) );
+ connect( savepixmap, SIGNAL(activated(int)), this, SLOT(savePixmap(int)) );
+
+ file = new QPopupMenu( menubar );
+ menubar->insertItem( "&File", file );
+ file->insertItem( "&New window", this, SLOT(newWindow()), CTRL+Key_N );
+ file->insertItem( "&Open...", this, SLOT(openFile()), CTRL+Key_O );
+ si = file->insertItem( "Save image", saveimage );
+ sp = file->insertItem( "Save pixmap", savepixmap );
+ file->insertSeparator();
+ file->insertItem( "E&xit", qApp, SLOT(quit()), CTRL+Key_Q );
+
+ edit = new QPopupMenu( menubar );
+ menubar->insertItem( "&Edit", edit );
+ edit->insertItem("&Copy", this, SLOT(copy()), CTRL+Key_C);
+ edit->insertItem("&Paste", this, SLOT(paste()), CTRL+Key_V);
+ edit->insertSeparator();
+ edit->insertItem("&Horizontal flip", this, SLOT(hFlip()), ALT+Key_H);
+ edit->insertItem("&Vertical flip", this, SLOT(vFlip()), ALT+Key_V);
+ edit->insertItem("&Rotate 180", this, SLOT(rot180()), ALT+Key_R);
+ edit->insertSeparator();
+ edit->insertItem("&Text...", this, SLOT(editText()));
+ edit->insertSeparator();
+ t1 = edit->insertItem( "Convert to &1 bit", this, SLOT(to1Bit()) );
+ t8 = edit->insertItem( "Convert to &8 bit", this, SLOT(to8Bit()) );
+ t32 = edit->insertItem( "Convert to &32 bit", this, SLOT(to32Bit()) );
+
+ options = new QPopupMenu( menubar );
+ menubar->insertItem( "&Options", options );
+ ac = options->insertItem( "AutoColor" );
+ co = options->insertItem( "ColorOnly" );
+ mo = options->insertItem( "MonoOnly" );
+ options->insertSeparator();
+ fd = options->insertItem( "DiffuseDither" );
+ bd = options->insertItem( "OrderedDither" );
+ td = options->insertItem( "ThresholdDither" );
+ options->insertSeparator();
+ ta = options->insertItem( "ThresholdAlphaDither" );
+ ba = options->insertItem( "OrderedAlphaDither" );
+ fa = options->insertItem( "DiffuseAlphaDither" );
+ options->insertSeparator();
+ ad = options->insertItem( "PreferDither" );
+ dd = options->insertItem( "AvoidDither" );
+ options->insertSeparator();
+ ss = options->insertItem( "Smooth scaling" );
+ cc = options->insertItem( "Use color context" );
+ if ( QApplication::colorSpec() == QApplication::ManyColor )
+ options->setItemEnabled( cc, FALSE );
+ options->setCheckable( TRUE );
+ setMenuItemFlags();
+
+ menubar->insertSeparator();
+
+ QPopupMenu* help = new QPopupMenu( menubar );
+ menubar->insertItem( "&Help", help );
+ help->insertItem( "Help!", this, SLOT(giveHelp()), CTRL+Key_H );
+
+ connect( options, SIGNAL(activated(int)), this, SLOT(doOption(int)) );
+
+ status = new QLabel(this);
+ status->setFrameStyle( QFrame::WinPanel | QFrame::Sunken );
+ status->setFixedHeight( fontMetrics().height() + 4 );
+
+ setMouseTracking( TRUE );
+}
+
+ImageViewer::~ImageViewer()
+{
+ if ( alloc_context )
+ QColor::destroyAllocContext( alloc_context );
+ if ( other == this )
+ other = 0;
+}
+
+/*
+ This function modifies the conversion_flags when an options menu item
+ is selected, then ensures all menu items are up to date, and reconverts
+ the image if possibly necessary.
+*/
+void ImageViewer::doOption(int item)
+{
+ if ( item == ss || item == cc ) {
+ // Toggle
+ bool newbool = !options->isItemChecked(item);
+ options->setItemChecked(item, newbool);
+ // And reconvert...
+ reconvertImage();
+ repaint(image.hasAlphaBuffer()); // show image in widget
+ return;
+ }
+
+ if ( options->isItemChecked( item ) ) return; // They are all radio buttons
+
+ int ocf = conversion_flags;
+
+ if ( item == ac ) {
+ conversion_flags = ( conversion_flags & ~ColorMode_Mask ) | AutoColor;
+ } else if ( item == co ) {
+ conversion_flags = ( conversion_flags & ~ColorMode_Mask ) | ColorOnly;
+ } else if ( item == mo ) {
+ conversion_flags = ( conversion_flags & ~ColorMode_Mask ) | MonoOnly;
+ } else if ( item == fd ) {
+ conversion_flags = ( conversion_flags & ~Dither_Mask ) | DiffuseDither;
+ } else if ( item == bd ) {
+ conversion_flags = ( conversion_flags & ~Dither_Mask ) | OrderedDither;
+ } else if ( item == td ) {
+ conversion_flags = ( conversion_flags & ~Dither_Mask ) | ThresholdDither;
+ } else if ( item == ta ) {
+ conversion_flags = ( conversion_flags & ~AlphaDither_Mask ) | ThresholdAlphaDither;
+ } else if ( item == fa ) {
+ conversion_flags = ( conversion_flags & ~AlphaDither_Mask ) | DiffuseAlphaDither;
+ } else if ( item == ba ) {
+ conversion_flags = ( conversion_flags & ~AlphaDither_Mask ) | OrderedAlphaDither;
+ } else if ( item == ad ) {
+ conversion_flags = ( conversion_flags & ~DitherMode_Mask ) | PreferDither;
+ } else if ( item == dd ) {
+ conversion_flags = ( conversion_flags & ~DitherMode_Mask ) | AvoidDither;
+ }
+
+ if ( ocf != conversion_flags ) {
+ setMenuItemFlags();
+ // And reconvert...
+ reconvertImage();
+ repaint(image.hasAlphaBuffer()); // show image in widget
+ }
+}
+
+/*
+ Set the options menu to reflect the conversion_flags value.
+*/
+void ImageViewer::setMenuItemFlags()
+{
+ // File
+ bool valid_image = pm.size() != QSize( 0, 0 );
+ file->setItemEnabled( si, valid_image );
+ file->setItemEnabled( sp, valid_image );
+
+ // Edit
+ edit->setItemEnabled( t1, image.depth() != 1 );
+ edit->setItemEnabled( t8, image.depth() != 8 );
+ edit->setItemEnabled( t32, image.depth() != 32 );
+
+ // Options
+ bool may_need_color_dithering =
+ !valid_image
+ || image.depth() == 32 && QPixmap::defaultDepth() < 24;
+ bool may_need_dithering = may_need_color_dithering
+ || image.depth() > 1 && options->isItemChecked(mo)
+ || image.depth() > 1 && QPixmap::defaultDepth() == 1;
+ bool has_alpha_mask = !valid_image || image.hasAlphaBuffer();
+
+ options->setItemEnabled( fd, may_need_dithering );
+ options->setItemEnabled( bd, may_need_dithering );
+ options->setItemEnabled( td, may_need_dithering );
+
+ options->setItemEnabled( ta, has_alpha_mask );
+ options->setItemEnabled( fa, has_alpha_mask );
+ options->setItemEnabled( ba, has_alpha_mask );
+
+ options->setItemEnabled( ad, may_need_color_dithering );
+ options->setItemEnabled( dd, may_need_color_dithering );
+
+ options->setItemChecked( ac, (conversion_flags & ColorMode_Mask) == AutoColor );
+ options->setItemChecked( co, (conversion_flags & ColorMode_Mask) == ColorOnly );
+ options->setItemChecked( mo, (conversion_flags & ColorMode_Mask) == MonoOnly );
+ options->setItemChecked( fd, (conversion_flags & Dither_Mask) == DiffuseDither );
+ options->setItemChecked( bd, (conversion_flags & Dither_Mask) == OrderedDither );
+ options->setItemChecked( td, (conversion_flags & Dither_Mask) == ThresholdDither );
+ options->setItemChecked( ta, (conversion_flags & AlphaDither_Mask) == ThresholdAlphaDither );
+ options->setItemChecked( fa, (conversion_flags & AlphaDither_Mask) == DiffuseAlphaDither );
+ options->setItemChecked( ba, (conversion_flags & AlphaDither_Mask) == OrderedAlphaDither );
+ options->setItemChecked( ad, (conversion_flags & DitherMode_Mask) == PreferDither );
+ options->setItemChecked( dd, (conversion_flags & DitherMode_Mask) == AvoidDither );
+}
+
+void ImageViewer::updateStatus()
+{
+ if ( pm.size() == QSize( 0, 0 ) ) {
+ if ( !filename.isEmpty() )
+ status->setText("Could not load image");
+ else
+ status->setText("No image - select Open from File menu.");
+ } else {
+ QString message, moremsg;
+ message.sprintf("%dx%d", image.width(), image.height());
+ if ( pm.size() != pmScaled.size() ) {
+ moremsg.sprintf(" [%dx%d]", pmScaled.width(),
+ pmScaled.height());
+ message += moremsg;
+ }
+ moremsg.sprintf(", %d bits ", image.depth());
+ message += moremsg;
+ if (image.valid(pickx,picky)) {
+ moremsg.sprintf("(%d,%d)=#%0*x ",
+ pickx, picky,
+ image.hasAlphaBuffer() ? 8 : 6,
+ image.pixel(pickx,picky));
+ message += moremsg;
+ }
+ if ( image.numColors() > 0 ) {
+ if (image.valid(pickx,picky)) {
+ moremsg.sprintf(", %d/%d colors", image.pixelIndex(pickx,picky),
+ image.numColors());
+ } else {
+ moremsg.sprintf(", %d colors", image.numColors());
+ }
+ message += moremsg;
+ }
+ if ( image.hasAlphaBuffer() ) {
+ if ( image.depth() == 8 ) {
+ int i;
+ bool alpha[256];
+ int nalpha=0;
+
+ for (i=0; i<256; i++)
+ alpha[i] = FALSE;
+
+ for (i=0; i<image.numColors(); i++) {
+ int alevel = image.color(i) >> 24;
+ if (!alpha[alevel]) {
+ alpha[alevel] = TRUE;
+ nalpha++;
+ }
+ }
+ moremsg.sprintf(", %d alpha levels", nalpha);
+ } else {
+ // Too many pixels to bother counting.
+ moremsg = ", 8-bit alpha channel";
+ }
+ message += moremsg;
+ }
+ status->setText(message);
+ }
+}
+
+/*
+ This function saves the image.
+*/
+void ImageViewer::saveImage( int item )
+{
+ const char* fmt = saveimage->text(item);
+ QString savefilename = QFileDialog::getSaveFileName(QString::null, QString::null,
+ this, filename);
+ if ( !savefilename.isEmpty() )
+ if ( !image.save( savefilename, fmt ) )
+ QMessageBox::warning( this, "Save failed", "Error saving file" );
+}
+
+/*
+ This function saves the converted image.
+*/
+void ImageViewer::savePixmap( int item )
+{
+ const char* fmt = savepixmap->text(item);
+ QString savefilename = QFileDialog::getSaveFileName(QString::null,
+ QString::null, this, filename);
+ if ( !savefilename.isEmpty() )
+ if ( !pmScaled.save( savefilename, fmt ) )
+ QMessageBox::warning( this, "Save failed", "Error saving file" );
+}
+
+
+void ImageViewer::newWindow()
+{
+ ImageViewer* that = new ImageViewer(0, "new window", WDestructiveClose);
+ that->options->setItemChecked( that->cc, useColorContext() );
+ that->show();
+}
+
+/*
+ This function is the slot for processing the Open menu item.
+*/
+void ImageViewer::openFile()
+{
+ QString newfilename = QFileDialog::getOpenFileName( QString::null,
+ QString::null,
+ this );
+ if ( !newfilename.isEmpty() ) {
+ loadImage( newfilename ) ;
+ repaint(); // show image in widget
+ }
+}
+
+/*
+ This function loads an image from a file and resizes the widget to
+ exactly fit the image size. If the file was not found or the image
+ format was unknown it will resize the widget to fit the errorText
+ message (see above) displayed in the current font.
+
+ Returns TRUE if the image was successfully loaded.
+*/
+
+bool ImageViewer::loadImage( const QString& fileName )
+{
+ filename = fileName;
+ bool ok = FALSE;
+ if ( !filename.isEmpty() ) {
+ QApplication::setOverrideCursor( waitCursor ); // this might take time
+ ok = image.load(filename, 0);
+ pickx = -1;
+ clickx = -1;
+ if ( ok )
+ ok = reconvertImage();
+ if ( ok ) {
+ setCaption( filename ); // set window caption
+ int w = pm.width();
+ int h = pm.height();
+
+ const int reasonable_width = 128;
+ if ( w < reasonable_width ) {
+ // Integer scale up to something reasonable
+ int multiply = ( reasonable_width + w - 1 ) / w;
+ w *= multiply;
+ h *= multiply;
+ }
+
+ h += menubar->heightForWidth(w) + status->height();
+ resize( w, h ); // we resize to fit image
+ } else {
+ pm.resize(0,0); // couldn't load image
+ update();
+ }
+ QApplication::restoreOverrideCursor(); // restore original cursor
+ }
+ updateStatus();
+ setMenuItemFlags();
+ return ok;
+}
+
+bool ImageViewer::reconvertImage()
+{
+ bool success = FALSE;
+
+ if ( image.isNull() ) return FALSE;
+
+ if ( alloc_context ) {
+ QColor::destroyAllocContext( alloc_context );
+ alloc_context = 0;
+ }
+ if ( useColorContext() ) {
+ alloc_context = QColor::enterAllocContext();
+ // Clear the image to hide flickering palette
+ QPainter painter(this);
+ painter.eraseRect(0, menubar->heightForWidth( width() ), width(), height());
+ }
+
+ QApplication::setOverrideCursor( waitCursor ); // this might take time
+ if ( pm.convertFromImage(image, conversion_flags) )
+ {
+ pmScaled = QPixmap();
+ scale();
+ resize( width(), height() );
+ success = TRUE; // load successful
+ } else {
+ pm.resize(0,0); // couldn't load image
+ }
+ updateStatus();
+ setMenuItemFlags();
+ QApplication::restoreOverrideCursor(); // restore original cursor
+
+ if ( useColorContext() )
+ QColor::leaveAllocContext();
+
+ return success; // TRUE if loaded OK
+}
+
+bool ImageViewer::smooth() const
+{
+ return options->isItemChecked(ss);
+}
+
+bool ImageViewer::useColorContext() const
+{
+ return options->isItemChecked(cc);
+}
+
+/*
+ This functions scales the pixmap in the member variable "pm" to fit the
+ widget size and puts the resulting pixmap in the member variable "pmScaled".
+*/
+
+void ImageViewer::scale()
+{
+ int h = height() - menubar->heightForWidth( width() ) - status->height();
+
+ if ( image.isNull() ) return;
+
+ QApplication::setOverrideCursor( waitCursor ); // this might take time
+ if ( width() == pm.width() && h == pm.height() )
+ { // no need to scale if widget
+ pmScaled = pm; // size equals pixmap size
+ } else {
+ if (smooth()) {
+ pmScaled.convertFromImage(image.smoothScale(width(), h),
+ conversion_flags);
+ } else {
+ QWMatrix m; // transformation matrix
+ m.scale(((double)width())/pm.width(),// define scale factors
+ ((double)h)/pm.height());
+ pmScaled = pm.xForm( m ); // create scaled pixmap
+ }
+ }
+ QApplication::restoreOverrideCursor(); // restore original cursor
+}
+
+/*
+ The resize event handler, if a valid pixmap was loaded it will call
+ scale() to fit the pixmap to the new widget size.
+*/
+
+void ImageViewer::resizeEvent( QResizeEvent * )
+{
+ status->setGeometry(0, height() - status->height(),
+ width(), status->height());
+
+ if ( pm.size() == QSize( 0, 0 ) ) // we couldn't load the image
+ return;
+
+ int h = height() - menubar->heightForWidth( width() ) - status->height();
+ if ( width() != pmScaled.width() || h != pmScaled.height())
+ { // if new size,
+ scale(); // scale pmScaled to window
+ updateStatus();
+ }
+ if ( image.hasAlphaBuffer() )
+ erase();
+}
+
+bool ImageViewer::convertEvent( QMouseEvent* e, int& x, int& y)
+{
+ if ( pm.size() != QSize( 0, 0 ) ) {
+ int h = height() - menubar->heightForWidth( width() ) - status->height();
+ int nx = e->x() * image.width() / width();
+ int ny = (e->y()-menubar->heightForWidth( width() )) * image.height() / h;
+ if (nx != x || ny != y ) {
+ x = nx;
+ y = ny;
+ updateStatus();
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void ImageViewer::mousePressEvent( QMouseEvent *e )
+{
+ may_be_other = convertEvent(e, clickx, clicky);
+}
+
+void ImageViewer::mouseReleaseEvent( QMouseEvent * )
+{
+ if ( may_be_other )
+ other = this;
+}
+
+/*
+ Record the pixel position of interest.
+*/
+void ImageViewer::mouseMoveEvent( QMouseEvent *e )
+{
+ if (convertEvent(e,pickx,picky)) {
+ updateStatus();
+ if ((e->state()&LeftButton)) {
+ may_be_other = FALSE;
+ if ( clickx >= 0 && other) {
+ copyFrom(other);
+ }
+ }
+ }
+}
+
+/*
+ Draws the portion of the scaled pixmap that needs to be updated or prints
+ an error message if no legal pixmap has been loaded.
+*/
+
+void ImageViewer::paintEvent( QPaintEvent *e )
+{
+ if ( pm.size() != QSize( 0, 0 ) ) { // is an image loaded?
+ QPainter painter(this);
+ painter.setClipRect(e->rect());
+ painter.drawPixmap(0, menubar->heightForWidth( width() ), pmScaled);
+ }
+}
+
+
+/*
+ Explain anything that might be confusing.
+*/
+void ImageViewer::giveHelp()
+{
+ if (!helpmsg) {
+ QString helptext =
+ "<b>Usage:</b> <tt>showimg [-m] <i>filename ...</i></tt>"
+ "<blockquote>"
+ "<tt>-m</tt> - use <i>ManyColor</i> color spec"
+ "</blockquote>"
+ "<p>Supported input formats:"
+ "<blockquote>";
+ helptext += QImage::inputFormatList().join(", ");
+ helptext += "</blockquote>";
+
+ helpmsg = new QMessageBox( "Help", helptext,
+ QMessageBox::Information, QMessageBox::Ok, 0, 0, 0, 0, FALSE );
+ }
+ helpmsg->show();
+ helpmsg->raise();
+}
+
+void ImageViewer::copyFrom(ImageViewer* s)
+{
+ if ( clickx >= 0 ) {
+ int dx = clickx;
+ int dy = clicky;
+ int sx = s->clickx;
+ int sy = s->clicky;
+ int sw = QABS(clickx - pickx)+1;
+ int sh = QABS(clicky - picky)+1;
+ if ( clickx > pickx ) {
+ dx = pickx;
+ sx -= sw-1;
+ }
+ if ( clicky > picky ) {
+ dy = picky;
+ sy -= sh-1;
+ }
+ bitBlt( &image, dx, dy, &s->image, sx, sy, sw, sh );
+ reconvertImage();
+ repaint( image.hasAlphaBuffer() );
+ }
+}
+ImageViewer* ImageViewer::other = 0;
+
+void ImageViewer::hFlip()
+{
+ setImage(image.mirror(TRUE,FALSE));
+}
+
+void ImageViewer::vFlip()
+{
+ setImage(image.mirror(FALSE,TRUE));
+}
+
+void ImageViewer::rot180()
+{
+ setImage(image.mirror(TRUE,TRUE));
+}
+
+void ImageViewer::copy()
+{
+#ifndef QT_NO_MIMECLIPBOARD
+ QApplication::clipboard()->setImage(image); // Less information loss
+#endif
+}
+
+void ImageViewer::paste()
+{
+#ifndef QT_NO_MIMECLIPBOARD
+ QImage p = QApplication::clipboard()->image();
+ if ( !p.isNull() ) {
+ filename = "pasted";
+ setImage(p);
+ }
+#endif
+}
+
+void ImageViewer::setImage(const QImage& newimage)
+{
+ image = newimage;
+
+ pickx = -1;
+ clickx = -1;
+ setCaption( filename ); // set window caption
+ int w = image.width();
+ int h = image.height();
+ if ( !w )
+ return;
+
+ const int reasonable_width = 128;
+ if ( w < reasonable_width ) {
+ // Integer scale up to something reasonable
+ int multiply = ( reasonable_width + w - 1 ) / w;
+ w *= multiply;
+ h *= multiply;
+ }
+
+ h += menubar->heightForWidth(w) + status->height();
+ resize( w, h ); // we resize to fit image
+
+ reconvertImage();
+ repaint( image.hasAlphaBuffer() );
+
+ updateStatus();
+ setMenuItemFlags();
+}
+
+void ImageViewer::editText()
+{
+ ImageTextEditor editor(image,this);
+ editor.exec();
+}
+
+void ImageViewer::to1Bit()
+{
+ toBitDepth(1);
+}
+
+void ImageViewer::to8Bit()
+{
+ toBitDepth(8);
+}
+
+void ImageViewer::to32Bit()
+{
+ toBitDepth(32);
+}
+
+void ImageViewer::toBitDepth(int d)
+{
+ image = image.convertDepth(d);
+ reconvertImage();
+ repaint( image.hasAlphaBuffer() );
+}
diff --git a/examples/showimg/showimg.doc b/examples/showimg/showimg.doc
new file mode 100644
index 0000000..d501bb8
--- /dev/null
+++ b/examples/showimg/showimg.doc
@@ -0,0 +1,29 @@
+/*
+*/
+/*! \page showimg-example.html
+
+ \ingroup examples
+ \title Show Image
+
+ This example reads and displays an image in any supported image
+ format (GIF, BMP, PPM, XMP, etc.).
+
+ <hr>
+
+ Header file:
+
+ \include showimg/showimg.h
+
+ <hr>
+
+ Implementation:
+
+ \include showimg/showimg.cpp
+
+ <hr>
+
+ Main:
+
+ \include showimg/main.cpp
+*/
+
diff --git a/examples/showimg/showimg.h b/examples/showimg/showimg.h
new file mode 100644
index 0000000..a9c63e0
--- /dev/null
+++ b/examples/showimg/showimg.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#ifndef SHOWIMG_H
+#define SHOWIMG_H
+
+#include <qwidget.h>
+#include <qimage.h>
+
+
+class QLabel;
+class QMenuBar;
+class QPopupMenu;
+
+class ImageViewer : public QWidget
+{
+ Q_OBJECT
+public:
+ ImageViewer( QWidget *parent=0, const char *name=0, int wFlags=0 );
+ ~ImageViewer();
+ bool loadImage( const QString& );
+protected:
+ void paintEvent( QPaintEvent * );
+ void resizeEvent( QResizeEvent * );
+ void mousePressEvent( QMouseEvent * );
+ void mouseReleaseEvent( QMouseEvent * );
+ void mouseMoveEvent( QMouseEvent * );
+
+private:
+ void scale();
+ int conversion_flags;
+ bool smooth() const;
+ bool useColorContext() const;
+ int alloc_context;
+ bool convertEvent( QMouseEvent* e, int& x, int& y );
+ QString filename;
+ QImage image; // the loaded image
+ QPixmap pm; // the converted pixmap
+ QPixmap pmScaled; // the scaled pixmap
+
+ QMenuBar *menubar;
+ QPopupMenu *file;
+ QPopupMenu *saveimage;
+ QPopupMenu *savepixmap;
+ QPopupMenu *edit;
+ QPopupMenu *options;
+
+ QWidget *helpmsg;
+ QLabel *status;
+ int si, sp, ac, co, mo, fd, bd, // Menu item ids
+ td, ta, ba, fa, au, ad, dd,
+ ss, cc, t1, t8, t32;
+ void updateStatus();
+ void setMenuItemFlags();
+ bool reconvertImage();
+ int pickx, picky;
+ int clickx, clicky;
+ bool may_be_other;
+ static ImageViewer* other;
+ void setImage(const QImage& newimage);
+
+private slots:
+ void to1Bit();
+ void to8Bit();
+ void to32Bit();
+ void toBitDepth(int);
+
+ void copy();
+ void paste();
+
+ void hFlip();
+ void vFlip();
+ void rot180();
+
+ void editText();
+
+ void newWindow();
+ void openFile();
+ void saveImage(int);
+ void savePixmap(int);
+ void giveHelp();
+ void doOption(int);
+ void copyFrom(ImageViewer*);
+};
+
+
+#endif // SHOWIMG_H
diff --git a/examples/showimg/showimg.pro b/examples/showimg/showimg.pro
new file mode 100644
index 0000000..b2df094
--- /dev/null
+++ b/examples/showimg/showimg.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+TARGET = showimg
+
+CONFIG += qt warn_on release
+DEPENDPATH = ../../include
+
+REQUIRES = full-config
+
+HEADERS = showimg.h imagetexteditor.h \
+ imagefip.h
+SOURCES = main.cpp \
+ imagetexteditor.cpp \
+ showimg.cpp \
+ imagefip.cpp