diff options
Diffstat (limited to 'examples/showimg')
-rw-r--r-- | examples/showimg/README | 14 | ||||
-rw-r--r-- | examples/showimg/imagefip.cpp | 61 | ||||
-rw-r--r-- | examples/showimg/imagefip.h | 31 | ||||
-rw-r--r-- | examples/showimg/imagetexteditor.cpp | 141 | ||||
-rw-r--r-- | examples/showimg/imagetexteditor.h | 46 | ||||
-rw-r--r-- | examples/showimg/main.cpp | 56 | ||||
-rw-r--r-- | examples/showimg/showimg.cpp | 672 | ||||
-rw-r--r-- | examples/showimg/showimg.doc | 29 | ||||
-rw-r--r-- | examples/showimg/showimg.h | 93 | ||||
-rw-r--r-- | examples/showimg/showimg.pro | 14 |
10 files changed, 1157 insertions, 0 deletions
diff --git a/examples/showimg/README b/examples/showimg/README new file mode 100644 index 000000000..a6c9ca982 --- /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 000000000..418b612c2 --- /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 TQt. 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( TQWidget *parent, const char *name ) : + TQFileIconProvider( parent, name ), + imagepm(image_xpm) +{ + fmts = TQImage::inputFormats(); +} + +ImageIconProvider::~ImageIconProvider() +{ +} + +const TQPixmap * ImageIconProvider::pixmap( const TQFileInfo &fi ) +{ + TQString ext = fi.extension().upper(); + if ( fmts.contains(ext) ) { + return &imagepm; + } else { + return TQFileIconProvider::pixmap(fi); + } +} diff --git a/examples/showimg/imagefip.h b/examples/showimg/imagefip.h new file mode 100644 index 000000000..3537f9420 --- /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 TQt. 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 TQFileIconProvider +{ + Q_OBJECT + TQStrList fmts; + TQPixmap imagepm; + +public: + ImageIconProvider( TQWidget *parent=0, const char *name=0 ); + ~ImageIconProvider(); + + const TQPixmap * pixmap( const TQFileInfo &fi ); +}; + + +#endif // IMAGEFIP_H diff --git a/examples/showimg/imagetexteditor.cpp b/examples/showimg/imagetexteditor.cpp new file mode 100644 index 000000000..464f85d9c --- /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 TQt. 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( TQImage& i, TQWidget *parent, const char *name, WFlags f ) : + TQDialog(parent,name,TRUE,f), + image(i) +{ + TQVBoxLayout* vbox = new TQVBoxLayout(this,8); + vbox->setAutoAdd(TRUE); + + TQGrid* controls = new TQGrid(3,TQGrid::Horizontal,this); + controls->setSpacing(8); + TQLabel* l; + l=new TQLabel("Language",controls); l->setAlignment(AlignCenter); + l=new TQLabel("Key",controls); l->setAlignment(AlignCenter); + (void)new TQLabel("",controls); // dummy + languages = new TQComboBox(controls); + keys = new TQComboBox(controls); + TQPushButton* remove = new TQPushButton("Remove",controls); + + newlang = new TQLineEdit(controls); + newkey = new TQLineEdit(controls); + TQPushButton* add = new TQPushButton("Add",controls); + + text = new TQMultiLineEdit(this); + + TQHBox* hbox = new TQHBox(this); + TQPushButton* cancel = new TQPushButton("Cancel",hbox); + TQPushButton* ok = new TQPushButton("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(); + TQDialog::accept(); +} + +void ImageTextEditor::updateText() +{ + storeText(); + newlang->setText(languages->currentText()); + newkey->setText(keys->currentText()); + TQString t = image.text(currKey(),currLang()); + + text->setText(t); +} + +TQString ImageTextEditor::currKey() +{ + return newkey->text(); +} + +TQString ImageTextEditor::currLang() +{ + TQString l = newlang->text(); + if ( l=="<any>" ) + l = TQString::null; + return l; +} + +TQString ImageTextEditor::currText() +{ + TQString t = text->text(); + if ( t.isNull() ) t = ""; + return t; +} + + +void ImageTextEditor::removeText() +{ + image.setText(currKey(),currLang(),TQString::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 000000000..e33b6e70f --- /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 TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef IMAGETEXTEDITOR_H +#define IMAGETEXTEDITOR_H + +#include <qdialog.h> + +class TQImage; +class TQComboBox; +class TQListBox; +class TQLineEdit; +class TQMultiLineEdit; + +class ImageTextEditor : public TQDialog +{ + Q_OBJECT +public: + ImageTextEditor( TQImage& i, TQWidget *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(); + TQImage& image; + TQComboBox* languages; + TQComboBox* keys; + TQMultiLineEdit* text; + TQLineEdit* newlang; + TQLineEdit* newkey; + TQString currKey(); + TQString currLang(); + TQString currText(); +}; + +#endif // IMAGETEXTEDITOR_H diff --git a/examples/showimg/main.cpp b/examples/showimg/main.cpp new file mode 100644 index 000000000..213b91216 --- /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 TQt. 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 && TQString(argv[1]) == "-m" ) { + TQApplication::setColorSpec( TQApplication::ManyColor ); + argc--; + argv++; + } + else if ( argc > 1 && TQString(argv[1]) == "-n" ) { + TQApplication::setColorSpec( TQApplication::NormalColor ); + argc--; + argv++; + } + else { + TQApplication::setColorSpec( TQApplication::CustomColor ); + } + + TQApplication a( argc, argv ); + + ImageIconProvider iip; + TQFileDialog::setIconProvider( &iip ); + + if ( argc <= 1 ) { + // Create a window which looks after its own existence. + ImageViewer *w = + new ImageViewer(0, "new window", TQt::WDestructiveClose | TQt::WResizeNoErase ); + w->setCaption("TQt 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], TQt::WDestructiveClose | TQt::WResizeNoErase ); + w->setCaption("TQt Example - Image Viewer"); + w->loadImage( argv[i] ); + w->show(); + } + } + + TQObject::connect(qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(tquit())); + + return a.exec(); +} diff --git a/examples/showimg/showimg.cpp b/examples/showimg/showimg.cpp new file mode 100644 index 000000000..905f8184a --- /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 TQt. 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 + TQWidget. + + The menu uses a single slot to simplify the process of adding + more items to the options menu. +*/ +ImageViewer::ImageViewer( TQWidget *parent, const char *name, int wFlags ) + : TQWidget( parent, name, wFlags ), + conversion_flags( PreferDither ), + helpmsg( 0 ) +{ + pickx = -1; + picky = -1; + clickx = -1; + clicky = -1; + alloc_context = 0; + + menubar = new TQMenuBar(this); + menubar->setSeparator( TQMenuBar::InWindowsStyle ); + + TQStrList fmt = TQImage::outputFormats(); + saveimage = new TQPopupMenu( menubar ); + savepixmap = new TQPopupMenu( 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 TQPopupMenu( 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(tquit()), CTRL+Key_Q ); + + edit = new TQPopupMenu( 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 TQPopupMenu( 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 ( TQApplication::colorSpec() == TQApplication::ManyColor ) + options->setItemEnabled( cc, FALSE ); + options->setCheckable( TRUE ); + setMenuItemFlags(); + + menubar->insertSeparator(); + + TQPopupMenu* help = new TQPopupMenu( 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 TQLabel(this); + status->setFrameStyle( TQFrame::WinPanel | TQFrame::Sunken ); + status->setFixedHeight( fontMetrics().height() + 4 ); + + setMouseTracking( TRUE ); +} + +ImageViewer::~ImageViewer() +{ + if ( alloc_context ) + TQColor::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() != TQSize( 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 && TQPixmap::defaultDepth() < 24; + bool may_need_dithering = may_need_color_dithering + || image.depth() > 1 && options->isItemChecked(mo) + || image.depth() > 1 && TQPixmap::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() == TQSize( 0, 0 ) ) { + if ( !filename.isEmpty() ) + status->setText("Could not load image"); + else + status->setText("No image - select Open from File menu."); + } else { + TQString 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); + TQString savefilename = TQFileDialog::getSaveFileName(TQString::null, TQString::null, + this, filename); + if ( !savefilename.isEmpty() ) + if ( !image.save( savefilename, fmt ) ) + TQMessageBox::warning( this, "Save failed", "Error saving file" ); +} + +/* + This function saves the converted image. +*/ +void ImageViewer::savePixmap( int item ) +{ + const char* fmt = savepixmap->text(item); + TQString savefilename = TQFileDialog::getSaveFileName(TQString::null, + TQString::null, this, filename); + if ( !savefilename.isEmpty() ) + if ( !pmScaled.save( savefilename, fmt ) ) + TQMessageBox::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() +{ + TQString newfilename = TQFileDialog::getOpenFileName( TQString::null, + TQString::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 TQString& fileName ) +{ + filename = fileName; + bool ok = FALSE; + if ( !filename.isEmpty() ) { + TQApplication::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(); + } + TQApplication::restoreOverrideCursor(); // restore original cursor + } + updateStatus(); + setMenuItemFlags(); + return ok; +} + +bool ImageViewer::reconvertImage() +{ + bool success = FALSE; + + if ( image.isNull() ) return FALSE; + + if ( alloc_context ) { + TQColor::destroyAllocContext( alloc_context ); + alloc_context = 0; + } + if ( useColorContext() ) { + alloc_context = TQColor::enterAllocContext(); + // Clear the image to hide flickering palette + TQPainter painter(this); + painter.eraseRect(0, menubar->heightForWidth( width() ), width(), height()); + } + + TQApplication::setOverrideCursor( waitCursor ); // this might take time + if ( pm.convertFromImage(image, conversion_flags) ) + { + pmScaled = TQPixmap(); + scale(); + resize( width(), height() ); + success = TRUE; // load successful + } else { + pm.resize(0,0); // couldn't load image + } + updateStatus(); + setMenuItemFlags(); + TQApplication::restoreOverrideCursor(); // restore original cursor + + if ( useColorContext() ) + TQColor::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; + + TQApplication::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 { + TQWMatrix m; // transformation matrix + m.scale(((double)width())/pm.width(),// define scale factors + ((double)h)/pm.height()); + pmScaled = pm.xForm( m ); // create scaled pixmap + } + } + TQApplication::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( TQResizeEvent * ) +{ + status->setGeometry(0, height() - status->height(), + width(), status->height()); + + if ( pm.size() == TQSize( 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( TQMouseEvent* e, int& x, int& y) +{ + if ( pm.size() != TQSize( 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( TQMouseEvent *e ) +{ + may_be_other = convertEvent(e, clickx, clicky); +} + +void ImageViewer::mouseReleaseEvent( TQMouseEvent * ) +{ + if ( may_be_other ) + other = this; +} + +/* + Record the pixel position of interest. +*/ +void ImageViewer::mouseMoveEvent( TQMouseEvent *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( TQPaintEvent *e ) +{ + if ( pm.size() != TQSize( 0, 0 ) ) { // is an image loaded? + TQPainter painter(this); + painter.setClipRect(e->rect()); + painter.drawPixmap(0, menubar->heightForWidth( width() ), pmScaled); + } +} + + +/* + Explain anything that might be confusing. +*/ +void ImageViewer::giveHelp() +{ + if (!helpmsg) { + TQString 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 += TQImage::inputFormatList().join(", "); + helptext += "</blockquote>"; + + helpmsg = new TQMessageBox( "Help", helptext, + TQMessageBox::Information, TQMessageBox::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 = TQABS(clickx - pickx)+1; + int sh = TQABS(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 + TQApplication::clipboard()->setImage(image); // Less information loss +#endif +} + +void ImageViewer::paste() +{ +#ifndef QT_NO_MIMECLIPBOARD + TQImage p = TQApplication::clipboard()->image(); + if ( !p.isNull() ) { + filename = "pasted"; + setImage(p); + } +#endif +} + +void ImageViewer::setImage(const TQImage& 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 000000000..d501bb8fe --- /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 000000000..020c910be --- /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 TQt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef SHOWIMG_H +#define SHOWIMG_H + +#include <qwidget.h> +#include <qimage.h> + + +class TQLabel; +class TQMenuBar; +class TQPopupMenu; + +class ImageViewer : public TQWidget +{ + Q_OBJECT +public: + ImageViewer( TQWidget *parent=0, const char *name=0, int wFlags=0 ); + ~ImageViewer(); + bool loadImage( const TQString& ); +protected: + void paintEvent( TQPaintEvent * ); + void resizeEvent( TQResizeEvent * ); + void mousePressEvent( TQMouseEvent * ); + void mouseReleaseEvent( TQMouseEvent * ); + void mouseMoveEvent( TQMouseEvent * ); + +private: + void scale(); + int conversion_flags; + bool smooth() const; + bool useColorContext() const; + int alloc_context; + bool convertEvent( TQMouseEvent* e, int& x, int& y ); + TQString filename; + TQImage image; // the loaded image + TQPixmap pm; // the converted pixmap + TQPixmap pmScaled; // the scaled pixmap + + TQMenuBar *menubar; + TQPopupMenu *file; + TQPopupMenu *saveimage; + TQPopupMenu *savepixmap; + TQPopupMenu *edit; + TQPopupMenu *options; + + TQWidget *helpmsg; + TQLabel *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 TQImage& 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 000000000..b2df09493 --- /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 |