kdesupport/kdewin32/tools/png2ico
Carlo Segato
brandon.ml at gmail.com
Wed Jun 18 22:00:47 CEST 2008
SVN commit 821936 by segato:
add the capability to create windows cursors(.cur and .ani)
the code is a bit messy but it works
CCMAIL:kde-windows at kde.org
M +1 -1 CMakeLists.txt
M +163 -81 png2ico.cpp
A qanihandler.cpp [License: GPL]
A qanihandler.h [License: GPL]
A qcurhandler.cpp [License: GPL]
A qcurhandler.h [License: GPL]
--- trunk/kdesupport/kdewin32/tools/png2ico/CMakeLists.txt #821935:821936
@@ -6,7 +6,7 @@
${CMAKE_CURRENT_BINARY_DIR}
)
-add_executable(png2ico png2ico.cpp qicohandler.cpp qicohandler.h)
+add_executable(png2ico png2ico.cpp qicohandler.cpp qicohandler.h qcurhandler.cpp qcurhandler.h qanihandler.cpp qanihandler.h)
target_link_libraries(png2ico ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY})
install(TARGETS png2ico DESTINATION bin)
--- trunk/kdesupport/kdewin32/tools/png2ico/png2ico.cpp #821935:821936
@@ -21,6 +21,8 @@
*/
#include "qicohandler.h"
+#include "qcurhandler.h"
+#include "qanihandler.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QFile>
@@ -28,13 +30,16 @@
#include <QtCore/QList>
#include <QtCore/QTextStream>
#include <QtGui/QImage>
+#include <QtGui/QPainter>
static void usage ( const QString &errMsg )
{
QString appname = QCoreApplication::instance()->arguments() [0];
fprintf ( stderr, "%s\n", qPrintable ( errMsg ) );
fprintf ( stdout, "%s version 0.1\n", qPrintable ( appname ) );
- fprintf ( stdout, "USAGE: %s icofile [--rcfile rcfile] pngfile1 [pngfile2 ...]\n", qPrintable ( appname ) );
+ fprintf ( stdout, "USAGE: %s file.ico [--rcfile rcfile] pngfile1 [pngfile2 ...]\n", qPrintable ( appname ) );
+ fprintf ( stdout, "USAGE: %s file.cur [--hotspotx hotspotx] [--hotspoty hotspoty] pngfile1\n", qPrintable ( appname ) );
+ fprintf ( stdout, "USAGE: %s file.ani [--hotspotx hotspotx] [--hotspoty hotspoty] [--framerate framerate] pngfile1 [pngfile2 ...]\n", qPrintable ( appname ) );
exit ( 1 );
}
@@ -49,6 +54,25 @@
exit ( 2 );
}
+QImage scaleImage(const QImage &source)
+{
+ //make an empty image and fill with transparent color
+ QImage result(32, 32, QImage::Format_ARGB32);
+ result.fill(0);
+
+ QPainter paint(&result);
+ paint.translate(0, 0);
+ if( source.width() > 32 || source.height() > 32 )
+ {
+ QImage scaled = source.scaled( 32, 32, Qt::KeepAspectRatio, Qt::SmoothTransformation );
+ paint.drawImage(QPoint(0, 0), scaled);
+ } else {
+ paint.drawImage(QPoint(0, 0), source);
+ }
+
+ return result;
+}
+
static bool sortQImageForSize ( const QImage &i1, const QImage &i2 )
{
int s1 = i1.size().width() * i1.size().height();
@@ -70,6 +94,9 @@
QString rcFileName;
QString icoFileName;
+ int hotspotx = 0;
+ int hotspoty = 0;
+ int framerate = 3;
for ( int i = 1; i < argc; i++ ) {
const QString arg = app.arguments() [i];
if ( arg == QLatin1String ( "--rcfile" ) ) {
@@ -80,7 +107,32 @@
} else {
usage ( "option '--rcfile' without filename" );
}
+ } else if (arg == "--hotspotx") {
+ if ( i + 1 < argc ) {
+ hotspotx = app.arguments()[i+1].toInt();
+ i++;
+ continue;
+ } else {
+ usage ( "option '--hotspotx' without value" );
+ }
+ } else if (arg == "--hotspoty") {
+ if ( i + 1 < argc ) {
+ hotspoty = app.arguments()[i+1].toInt();
+ i++;
+ continue;
+ } else {
+ usage ( "option '--hotspoty' without value" );
+ }
+ } else if (arg == "--framerate") {
+ if ( i + 1 < argc ) {
+ framerate = app.arguments()[i+1].toInt();
+ i++;
+ continue;
+ } else {
+ usage ( "option '--framerate' without value" );
+ }
}
+
if ( icoFileName.isEmpty() ) {
icoFileName = arg;
continue;
@@ -91,100 +143,130 @@
warning ( QString ( "Can not load image %1" ).arg ( arg ) );
continue;
}
- images += img;
- if ( img.size() == size16 ) {
- if ( imagesToUse.contains ( 16 ) ) {
- warning ( QString ( "Already have an Image with 16x16 - overwriting with %1" ).arg ( arg ) );
- }
- imagesToUse.insert ( 16, img );
- continue;
+
+ if (icoFileName.endsWith(".ico", Qt::CaseInsensitive)) {
+ images += img;
+ if ( img.size() == size16 ) {
+ if ( imagesToUse.contains ( 16 ) ) {
+ warning ( QString ( "Already have an Image with 16x16 - overwriting with %1" ).arg ( arg ) );
+ }
+ imagesToUse.insert ( 16, img );
+ continue;
+ }
+ if ( img.size() == size32 ) {
+ if ( imagesToUse.contains ( 32 ) ) {
+ warning ( QString ( "Already have an Image with 32x32 - overwriting with %1" ).arg ( arg ) );
+ }
+ imagesToUse.insert ( 32, img );
+ continue;
+ }
+ if ( img.size() == size48 ) {
+ if ( imagesToUse.contains ( 48 ) ) {
+ warning ( QString ( "Already have an Image with 48x48- overwriting with %1" ).arg ( arg ) );
+ }
+ imagesToUse.insert ( 48, img );
+ continue;
+ }
+ } else {
+ if (img.size() != QSize(32, 32)) {
+ img = scaleImage(img);
+ }
+
+ images += img;
}
- if ( img.size() == size32 ) {
- if ( imagesToUse.contains ( 32 ) ) {
- warning ( QString ( "Already have an Image with 32x32 - overwriting with %1" ).arg ( arg ) );
- }
- imagesToUse.insert ( 32, img );
- continue;
- }
- if ( img.size() == size48 ) {
- if ( imagesToUse.contains ( 48 ) ) {
- warning ( QString ( "Already have an Image with 48x48- overwriting with %1" ).arg ( arg ) );
- }
- imagesToUse.insert ( 48, img );
- continue;
- }
}
if ( images.count() == 0 )
usage ( "No valid images found!" );
-
- qSort ( images.begin(), images.end(), sortQImageForSize );
- // 48x48 available -> if not create one
- if ( !imagesToUse.contains ( 48 ) ) {
- QImage img;
- Q_FOREACH ( const QImage &i, images ) {
- if ( img.width() >= 32 && img.height() >= 32 ) {
- img = i;
- }
+ if (icoFileName.endsWith(".ico", Qt::CaseInsensitive)) {
+ qSort ( images.begin(), images.end(), sortQImageForSize );
+ // 48x48 available -> if not create one
+ if ( !imagesToUse.contains ( 48 ) ) {
+ QImage img;
+ Q_FOREACH ( const QImage &i, images ) {
+ if ( img.width() >= 32 && img.height() >= 32 ) {
+ img = i;
+ }
+ }
+ if ( img.isNull() ) {
+ // none found -> use the last (==biggest) available
+ img = images.last();
+ }
+ imagesToUse.insert ( 48, img.scaled ( 48, 48, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
}
- if ( img.isNull() ) {
- // none found -> use the last (==biggest) available
- img = images.last();
+ // 32x32 available -> if not create one
+ if ( !imagesToUse.contains ( 32 ) ) {
+ QImage img;
+ Q_FOREACH ( const QImage &i, images ) {
+ if ( img.width() >= 24 && img.height() >= 24 ) {
+ img = i;
+ // no need to scale from an higher size when we've 48x48
+ if ( img.width() >= 48 && img.height() >= 48 )
+ break;
+ }
+ }
+ if ( img.isNull() ) {
+ // none found -> use the last (==biggest) available
+ img = images.last();
+ }
+ imagesToUse.insert ( 32, img.scaled ( 32, 32, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
}
- imagesToUse.insert ( 48, img.scaled ( 48, 48, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
- }
- // 32x32 available -> if not create one
- if ( !imagesToUse.contains ( 32 ) ) {
- QImage img;
- Q_FOREACH ( const QImage &i, images ) {
- if ( img.width() >= 24 && img.height() >= 24 ) {
- img = i;
- // no need to scale from an higher size when we've 48x48
- if ( img.width() >= 48 && img.height() >= 48 )
- break;
- }
+ // 16x16 available -> if not create one
+ if ( !imagesToUse.contains ( 16 ) ) {
+ QImage img;
+ Q_FOREACH ( const QImage &i, images ) {
+ if ( img.width() >= 10 && img.height() >= 10 ) {
+ img = i;
+ // no need to scale from an higher size when we've 32x32
+ if ( img.width() >= 32 && img.height() >= 32 )
+ break;
+ }
+ }
+ if ( img.isNull() ) {
+ // none found -> use the last (==biggest) available
+ img = images.last();
+ }
+ imagesToUse.insert ( 16, img.scaled ( 16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
}
- if ( img.isNull() ) {
- // none found -> use the last (==biggest) available
- img = images.last();
- }
- imagesToUse.insert ( 32, img.scaled ( 32, 32, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
+ images.clear();
+ images += imagesToUse[16].convertToFormat ( QImage::Format_ARGB32, Qt::ColorOnly|Qt::DiffuseAlphaDither|Qt::AvoidDither );
+ images += imagesToUse[16].convertToFormat ( QImage::Format_Indexed8, Qt::ColorOnly|Qt::DiffuseAlphaDither|Qt::AvoidDither );
+ images += imagesToUse[32].convertToFormat ( QImage::Format_ARGB32, Qt::ColorOnly|Qt::DiffuseAlphaDither|Qt::AvoidDither );
+ images += imagesToUse[32].convertToFormat ( QImage::Format_Indexed8, Qt::ColorOnly|Qt::DiffuseAlphaDither|Qt::AvoidDither );
+ images += imagesToUse[48].convertToFormat ( QImage::Format_ARGB32, Qt::ColorOnly|Qt::DiffuseAlphaDither|Qt::AvoidDither );
+ images += imagesToUse[48].convertToFormat ( QImage::Format_Indexed8, Qt::ColorOnly|Qt::DiffuseAlphaDither|Qt::AvoidDither );
}
- // 16x16 available -> if not create one
- if ( !imagesToUse.contains ( 16 ) ) {
- QImage img;
- Q_FOREACH ( const QImage &i, images ) {
- if ( img.width() >= 10 && img.height() >= 10 ) {
- img = i;
- // no need to scale from an higher size when we've 32x32
- if ( img.width() >= 32 && img.height() >= 32 )
- break;
- }
- }
- if ( img.isNull() ) {
- // none found -> use the last (==biggest) available
- img = images.last();
- }
- imagesToUse.insert ( 16, img.scaled ( 16, 16, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
- }
- images.clear();
- images += imagesToUse[16].convertToFormat ( QImage::Format_ARGB32, Qt::ColorOnly|Qt::DiffuseAlphaDither|Qt::AvoidDither );
- images += imagesToUse[16].convertToFormat ( QImage::Format_Indexed8, Qt::ColorOnly|Qt::DiffuseAlphaDither|Qt::AvoidDither );
- images += imagesToUse[32].convertToFormat ( QImage::Format_ARGB32, Qt::ColorOnly|Qt::DiffuseAlphaDither|Qt::AvoidDither );
- images += imagesToUse[32].convertToFormat ( QImage::Format_Indexed8, Qt::ColorOnly|Qt::DiffuseAlphaDither|Qt::AvoidDither );
- images += imagesToUse[48].convertToFormat ( QImage::Format_ARGB32, Qt::ColorOnly|Qt::DiffuseAlphaDither|Qt::AvoidDither );
- images += imagesToUse[48].convertToFormat ( QImage::Format_Indexed8, Qt::ColorOnly|Qt::DiffuseAlphaDither|Qt::AvoidDither );
QFile f ( icoFileName );
if ( !f.open ( QIODevice::WriteOnly ) ) {
fatal ( QString ( "Can not open %1 for writing" ).arg ( icoFileName ) );
return 2;
}
- QtIcoHandler ico ( &f );
- if ( !ico.write ( images ) ) {
- fatal ( "Can not create ico data" );
- return 2;
+
+ if (icoFileName.endsWith(".cur", Qt::CaseInsensitive)) {
+ QtCurHandler ico ( &f );
+ if ( !ico.write ( images, hotspotx, hotspoty ) ) {
+ fatal ( "Can not create cur data" );
+ return 2;
+ }
+ f.close();
+
+ } else if (icoFileName.endsWith(".ani", Qt::CaseInsensitive)) {
+ QtAniHandler ico ( &f );
+ if ( !ico.write ( images, hotspotx, hotspoty, framerate ) ) {
+ fatal ( "Can not create ani data" );
+ return 2;
+ }
+ f.close();
+ } else if(icoFileName.endsWith(".ico", Qt::CaseInsensitive)) {
+ QtIcoHandler ico ( &f );
+ if ( !ico.write ( images ) ) {
+ fatal ( "Can not create ico data" );
+ return 2;
+ }
+ f.close();
+ } else {
+ f.close();
}
- f.close();
if ( !rcFileName.isEmpty() ) {
QFile rcFile ( rcFileName );
@@ -194,7 +276,7 @@
}
QTextStream ts(&rcFile);
ts << QString( "IDI_ICON1 ICON DISCARDABLE \"%1\"\n" ).arg ( icoFileName );
- f.close();
+ rcFile.close();
}
return 0;
}
More information about the Kde-windows
mailing list