Projet d`Interface GraphicsMagick

Transcription

Projet d`Interface GraphicsMagick
Projet d'Interface GraphicsMagick
Elève : Clément Follet
Professeur : Cédric Lejeune
Master 2 Audiovisuel et Multimédia Isis
DREAM - ISTV
Université de Valenciennes et du Hainaut-Cambrésis
Promotion 2008-09
Projet d'Interface GraphicsMagick – Projet Master 2 ISIS Audiovisuel et Multimédia – Dream – Université de Valenciennes (UVHC) - page 1
SOMMAIRE
page
1. Présentation de GraphicsMagick........................................................................................3
2. Les Outils GraphicsMagick.................................................................................................3
3. Réalisation du projet............................................................................................................4
3. 1. Installation de GraphicsMagick et autres outils sous Fedora.......................................4
3. 2. Installation de GraphicsMagick et autres outils sous Windows XP.............................4
3. 3. Cross-compilation Linux vers Windows......................................................................4
3. 4. Problème de compatibilité entre le code c (ou c++) sous Linux et sous Windows......7
4. Le Programme......................................................................................................................7
4. 1. Aspect du programme..................................................................................................7
4. 2. Organisation du code...................................................................................................11
4. 3. Quelques explications sur le code...............................................................................11
5. Problèmes rencontrés.........................................................................................................17
6. Remerciements....................................................................................................................17
Projet d'Interface GraphicsMagick – Projet Master 2 ISIS Audiovisuel et Multimédia – Dream – Université de Valenciennes (UVHC) - page 2
1. Présentation de GraphicsMagick
GraphicsMagick est en quelque sorte le couteau suisse du traitement d'image. Il ne contient
que 248k de lignes de code source pour le paquetage de base (891k avec les trois parties de la
librairie). Cela fait de lui une collection d'outils robuste et efficace supportant la lecture, l'écriture et
la manipulation des images avec 88 formats différents incluant des formats les plus connus comme
DPX, GIF, JPEG, JPEG-2000, PNG, PDF, PNG, PNM, and TIFF.
Le traitement d'image peut-être multi-tâche en utilisant OpenMP, d'où les capacités du CPU
augmentent linéairement avec le nombre de coeur. OpenMP demande la compilation avec GCC 4.2
ou plus, ou l'utilisation d'un compilateur C supportant au pire les spécification de OpenMP 2.0.
GraphicsMagick est quasiment portable et compile sous la plupart des systèmes
d'exploitation qui tournent avec un CPU de 32-bit ou 64-bit. GraphicsMagick est compatible avec
les systèmes Unix virtuels, avec Windows à partir de Windows 2000 (XP, Vista), et MacOS-X. Le
code source peut être exécuté sous Windows '98.
GraphicsMagick supporte un large type d'image et a été testé avec des images de la taille du
gigapixel. GraphicsMagick peut créer des nouvelles images à la volée, le rendant utilisable pour des
applications Web. GraphicsMagick peut être utilisé pour retailler, tourner, étirer, faire une réduction
de couleurs, ou ajouter des effets spéciaux et sauver le résultat au format choisi. Les opérations de
traitement d'image peuvent se faire à partir d'une ligne de commande, ou à partir des interfaces de
programmations C, C++, Perl, Tcl, Ruby, ou Windows COM.
GraphicsMagick provient du logiciel ImageMagick 5.5.2 mais est resté complètement
indépendant depuis 2002. Beaucoup d'améliorations ont été apportées par des auteurs développant
sous licence libre sans toucher à l'API ou aux outils de base.
2. Les Outils GraphicsMagick
Entre autre des API développées en langage de haut niveau, GraphicsMagick dispose d'un puissant
kit de ligne de commande qui peuvent être utilisées pour accéder à toutes les fonctions du logiciel.
GM sert un important set d'options et garantit l'accès à la majorité des modes de commande grâce à
un simple programme exécutable appellé gm . Par exemple, pour utiliser le mode convert, il suffit
de taper gm convert... Voici les différents modes de GraphicsMagick :
–
–
–
–
–
–
–
–
–
–
gm animate : anime une sequence d'image
gm composite : assemble des images
gm conjure : execute le script XML MSL (Magick Script Language)
gm compare : compare deux images suivant leurs différences statistiques et physiologiques
gm convert : convertie une image ou une sequence d'image
gm display : affiche une image sur une station de travail X
gm indentify : décrit une image ou une séquence d'image
gm import : capture une application ou un écran de serveur X
gm mogrify : transforme une image ou une sequence d'image
gm montage : crée une image composite (selon une grille) à partir de plusieurs images
Vous l'aurez compris, les outils GraphicsMagick permet un traitement d'image complexe à
partir d'une simple ligne de commande. On peut les exécuter à partir d'un script ou d'autre
programmes dans le but d'automatiser le système pour des centaines d'images.
Et bien c'est ce que nous allons faire!
Projet d'Interface GraphicsMagick – Projet Master 2 ISIS Audiovisuel et Multimédia – Dream – Université de Valenciennes (UVHC) - page 3
3. Réalisation du projet
3. 1. Installation de GraphicsMagick et autres outils sous Fedora.
Il faut installer une version inférieure à 1.3 de GraphicsMagick si l'on ne veut pas du multithreading OpenMD car son compilateur GCC est inférieur à 4.2. Sinon installer la dernière version.
On trouve les rpm sur le site, sous fedora on trouve le paquetage GraphicsMagick dans
Installer/enlever des logiciels.
–
–
Qt s'installe en téléchargeant et installant les paquetages suivants :
yum install qt-devel qt-doc qt-config
sur Fedora 10 : yum groupinstall "Development Tools" pour utiliser make
Le logiciel kate s'installe avec les paquetages kdeaddons(fedora 8) ou kdesdk(fedora 10), ca
va installer les programmes de KDE sur Gnome pour ceux qui préfèrent Gnome.
3. 2. Installation de GraphicsMagick et autres outils sous Windows XP.
Il suffit de se rendre à la page http://www.graphicsmagick.org/download.html et de choisir
les paquetages windows.
« Installable binary packages and the extended source code package for use with Microsoft Visual
C++ (including configured delegates and a Visual C++ workspace) may be found here. «
Ensuite on choisit le .exe GraphicsMagick-1.3.5-Q8-windows-dll.exe , le Q8 étant pour le
traitement d'images de résolution 32bits/pixel maximum alors que le Q16 pour des images 64bits
max pouvant servir à scannerisation dans les hopitaux ou à des fins militaires qui sait...
D'autre part pour pouvoir lire le programme développé en Qt sous Unix ou Windows peu
importe, on doit installer la librairie Qt et son compilateur windows qui s'appelle mingw.
On va alors sur Qtsoftware.com/downloads et on choisi l'executable Open source pour le
développement d'application et non pour les systèmes embarqués : Qt for windows C++
Installer Qt et Mingw. A la différence de Linux l'exécutable ne se forme pas dans le dossier
de compilation mais dans un dossier enfant Release . Un dossier debug est aussi créé et regroupe
des informations lorsque la compilation a échouée. Pour que le programme s'exécute correctement
il faut mettre dans le dossier au minimum 3 fichiers .dll : mingwm10.dll, QtCore4.dll et QtGui4.dll.
Le premier servant à décoder la compilation (le .exe), le second pour le multi-thread surement et le
troisième pour les librairies Qt (les .h).
On parlera plus tard des endroits où on peut se procurer ces .dll.
Dernièrement, pour éditer le programme on peut télécharger DevC++ que l'on trouve partout
sur internet.
3. 3. Cross-compilation Linux vers Windows
Comme je n'ai toujours pas d'ordinateur portable, et que la plupart des gens ont un windows
et qu'ils ne veulent pas qu'on leur installe un linux parce qu'il ne savent pas ce que c'est et que ça les
effraient. Il a fallu compiler le programme en .exe pour montrer le logiciel lors de la soutenance. Il
Projet d'Interface GraphicsMagick – Projet Master 2 ISIS Audiovisuel et Multimédia – Dream – Université de Valenciennes (UVHC) - page 4
est possible de le faire en changeant de système d'exploitation, soit en redémarrant son pc pour
tester de chaque côté, ce qui est lassant à la longue, soit en virtualisant ce que je n'ai pas essayé
mais qui ne doit pas être très commode non plus.
Une solution existe : la cross-compilation qui permet de compiler sous linux pour avoir un .exe.
Voici la démarche, sur les tutoriels internet elle paraît assez compliquée mais une fois simplifiée elle
ne l'est plus.
On part du principe que Qt a été installé sur le poste de travail Linux.
Une fois que Qt a été installé et que le programme compile correctement sous linux avec le
traditionnel :
– qmake-qt4 -project : génère le fichier .pro automatiquement à partir des fichiers sources et des
headers
– qmake-qt4 : génère le Makefile
– make : génère l'exécutable
On peut désormais commencer par installer le paquetage Qt pour windows avec son
compilateur mingw sur Linux! On le télécharge comme vu précédemment et on l'installe à partir de
wine qui est un logiciel Linux permettant d'éxécuter les .exe windows sur un Linux. (yum install
wine)
Une fois tout ça installé il est temps de créer un mkspeck. Un mkspec est le dossier où est
contenu le fichier qmake.conf de qt où est stocké toutes les informations importantes pour la
compilation : chemin des librairies et des compilateur, etc... Ici il s'agit du mkspec du compilateur
win32-g++. Il ne faut pas effacer ce dossier d'origine, il faut donc le copier :
sudo cp -r /usr/share/qt4/mkspecs/win32-g++ /usr/share/qt4/mkspecs/win32-x-g++
On se déplace alors dans l'arborescence pour ouvrir le fichier :
usr/share/qt4/mkspecs/win32-x-g++/qmake.conf
On peut le modifier de cette manière :
#
# qmake configuration for win32-g++
#
# Written for MinGW
#
MAKEFILE_GENERATOR
= MINGW
TEMPLATE
= app
CONFIG
+= qt warn_on release link_prl copy_dir_files debug_and_release
debug_and_release_target precompile_header
QT
+= core gui
DEFINES
+= UNICODE QT_LARGEFILE_SUPPORT
QMAKE_COMPILER_DEFINES += __GNUC__ WIN32
QMAKE_EXT_OBJ
QMAKE_EXT_RES
QMAKE_CC
QMAKE_LEX
QMAKE_LEXFLAGS
QMAKE_YACC
QMAKE_YACCFLAGS
QMAKE_CFLAGS
QMAKE_CFLAGS_DEPS
QMAKE_CFLAGS_WARN_ON
QMAKE_CFLAGS_WARN_OFF
QMAKE_CFLAGS_RELEASE
QMAKE_CFLAGS_DEBUG
QMAKE_CFLAGS_YACC
= .o
= _res.o
= /home/clem/mingw/bin/gcc.exe
= flex
=
= byacc
= -d
=
= -M
= -Wall
= -w
= -O2
= -g
= -Wno-unused -Wno-parentheses
QMAKE_CXX
=
QMAKE_CXXFLAGS
=
QMAKE_CXXFLAGS_DEPS
=
QMAKE_CXXFLAGS_WARN_ON=
/home/clem/mingw/bin/g++.exe
$$QMAKE_CFLAGS
$$QMAKE_CFLAGS_DEPS
$$QMAKE_CFLAGS_WARN_ON
//chemin du gcc de mingw
//chemin du g++ de mingw
Projet d'Interface GraphicsMagick – Projet Master 2 ISIS Audiovisuel et Multimédia – Dream – Université de Valenciennes (UVHC) - page 5
QMAKE_CXXFLAGS_WARN_OFF
= $$QMAKE_CFLAGS_WARN_OFF
QMAKE_CXXFLAGS_RELEASE= $$QMAKE_CFLAGS_RELEASE
QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
QMAKE_CXXFLAGS_YACC
= $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
QMAKE_CXXFLAGS_RTTI_ON= -frtti
QMAKE_CXXFLAGS_RTTI_OFF
= -fno-rtti
QMAKE_CXXFLAGS_EXCEPTIONS_ON = -fexceptions -mthreads
QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions
QMAKE_INCDIR
QMAKE_INCDIR_QT
QMAKE_LIBDIR_QT
= /home/clem/mingw/include
= /home/clem/QtWin/include
= /home/clem/QtWin/lib
QMAKE_RUN_CC
QMAKE_RUN_CC_IMP
QMAKE_RUN_CXX
QMAKE_RUN_CXX_IMP
=
=
=
=
$(CC) -c $(CFLAGS) $(INCPATH) -o
$(CC) -c $(CFLAGS) $(INCPATH) -o
$(CXX) -c $(CXXFLAGS) $(INCPATH)
$(CXX) -c $(CXXFLAGS) $(INCPATH)
//chemin du include de mingw
//chemin du include Qt
//chemin de la librairie Qt
$obj $src
$@ $<
-o $obj $src
-o $@ $<
QMAKE_LINK
= /home/clem/mingw/bin/g++.exe
//chemin du g++ de mingw
QMAKE_LFLAGS
= -mthreads -Wl,-enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enableruntime-pseudo-reloc -mwindows à la fin pour éviter d'avoir une console dans les applications
QMAKE_LFLAGS_EXCEPTIONS_ON = -mthreads -Wl
QMAKE_LFLAGS_EXCEPTIONS_OFF =
QMAKE_LFLAGS_RELEASE = -Wl,-s
QMAKE_LFLAGS_DEBUG
=
QMAKE_LFLAGS_CONSOLE = -Wl,-subsystem,console
QMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows
QMAKE_LFLAGS_DLL
= -shared
QMAKE_LINK_OBJECT_MAX = 10
QMAKE_LINK_OBJECT_SCRIPT= object_script
QMAKE_LIBS
=
QMAKE_LIBS_CORE
= -lkernel32 -luser32 -lshell32 -luuid -lole32 -ladvapi32 -lws2_32
QMAKE_LIBS_GUI
= -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lwinspool -lws2_32 -lole32
-luuid -luser32 -ladvapi32
QMAKE_LIBS_NETWORK
= -lws2_32
QMAKE_LIBS_OPENGL
= -lopengl32 -lglu32 -lgdi32 -luser32
QMAKE_LIBS_COMPAT
= -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32
QMAKE_LIBS_QT_ENTRY
= -lmingw32 -lqtmain
# les commande DOS sont à remplacer par les commandes shell unix
#!isEmpty(QMAKE_SH) {
#
MINGW_IN_SHELL
= 1
QMAKE_DIR_SEP
= /
QMAKE_COPY
= cp
QMAKE_COPY_DIR
= cp -r
QMAKE_MOVE
= mv
QMAKE_DEL_FILE
= rm -f
QMAKE_MKDIR
= mkdir -p
QMAKE_DEL_DIR
= rm -rf
QMAKE_CHK_DIR_EXISTS = test -d
#} else {
#
QMAKE_COPY
= copy /y
#
QMAKE_COPY_DIR
= xcopy /s /q /y /i
#
QMAKE_MOVE
= move
#
QMAKE_DEL_FILE
= del
#
QMAKE_MKDIR
= mkdir
#
QMAKE_DEL_DIR
= rmdir
#
QMAKE_CHK_DIR_EXISTS
= if not exist
#}
QMAKE_MOC
QMAKE_UIC
QMAKE_IDC
= $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}moc-qt4 //sans .exe
= $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}uic-qt4 //sans .exe
= $$[QT_INSTALL_BINS]$${DIR_SEPARATOR}idc-qt4 //sans .exe
QMAKE_IDL
QMAKE_LIB
QMAKE_RC
QMAKE_ZIP
=
=
=
=
QMAKE_STRIP
QMAKE_STRIPFLAGS_LIB
load(qt_config)
= /home/clem/mingw/bin/strip.exe
+= --strip-unneeded
midl
/home/clem/mingw/bin/ar.xe -ru
/home/clem/mingw/bin/windres.exe
zip -r -9
Une fois le fichier modifier, on peut repasser en console dans le dossier de son appli (il faut
que le fichier .pro du compilateur d'origine et les .cpp soit présents) pour compiler avec notre
nouveau compilateur : qmake-qt4 -spec win32-x-g++ win32/
Ceci crée le makefile dans le dossier win32 (qui avait été créé précédemment) ce qui permet de ne
pas écraser celui d'origine.
Puis make et les dossiers Release et Debug apparaissent avec si tout va bien le .exe dans Release.
Projet d'Interface GraphicsMagick – Projet Master 2 ISIS Audiovisuel et Multimédia – Dream – Université de Valenciennes (UVHC) - page 6
Pour lancer le .exe il faut mettre les .dll mingwm10.dll, QtCore4.dll et QtGui4.dll dans le dossier
Release comme dit plus tôt. Deux de ces dll se trouvent dans le dossier bin/ du répertoire
d'installation de Qt for Windows. En ce qui concerne mingwm10.dll je l'ai trouvé sur internet.
4. 4. Problème de compatibilité entre le code c (ou c++) sous Linux et sous Windows.
–
–
–
–
–
Les fonctions Qt étrangement ou logiquement (...) n'acceptent pas les images jpg sous Windows.
Les guillemets comme celui ci, ' ,ne sont pas possibles sous Windows il faut les remplacer par
un anti-slash suivi d'un guillemet double \ ».
Par contre le / sous Windows ne pose pas de problème alors que les chemins sont normalement
avec des anti-slash \.
La fonctions system() appartenant à la librairie C++ <stdlib.h> pose problème sous linux car
elle affiche une console durant le temps d'execution de la tâche, elle n'est donc vraiment pas
utilisable. Il a fallu trouver une alternative qui après maintes recherches est retombée sur la
classe Qprocess chez Qt. Il y a vraiment tout avec Qt si l'on arrive à trouver et comme c'est du
multi-plateforme, il est recommander de programmer entièrement en Qt.
Les widgets ne sont pas affichés de la même façon au niveau des marges.
5. Le Programme
4. 1. Aspect du programme.
Il a fallu se poser la question de l'aspect et de l'ergonomie du programme, comment rendre le
programme simple d'utilisation et intuitif. Le fait de placer un textEdit qui laissait apparaître la ligne
de commande à l'utilisateur paraîssait primordial, le logiciel Mkvmerge qui sert à regrouper des
fichiers dans un conteneur mkv (video+soustitres+chapitres) qui personnellement me paraîssait très
intuitif fut une source d'inspiration.
De la même manière que mkvmerge le programme se compose d'une partie supérieure pour
choisir les fichiers avec un textEdit et les pushButton add, append et remove. En plus, les boutons
Projet d'Interface GraphicsMagick – Projet Master 2 ISIS Audiovisuel et Multimédia – Dream – Université de Valenciennes (UVHC) - page 7
Up et Down sont ajoutés. La partie centrale sert de traitement, puis la partie inférieur affiche le
fichier de sortie et le textEdit où apparaît la commanLine :
La partie centrale s'organise en plusieurs onglets faisant partie d'un TabWidget, pour ajouter
des fichiers on peut faire un drag an Drop de n'importe où dans la TableView de la partie supérieure,
ou sur l'onglet d'accueil où se situe le logo GraphicsMagick. Dans le premier cas le fichier est
seulement ajouté à la liste, il faut double cliquer ensuite pour le choisir et le traiter. Plusieurs
fichiers peuvent être ajoutés à la liste en même temps. Dans le deuxième cas le fichier est ajouté à la
liste et est déjà disponible pour le traitement (un seul fichier peut être droppé).
Remarque : les drag and drop sous windows ne fonctionnent pas.
En réalité seul l'onglet Convert a été implémenté, la plus grande partie des fonctions de
GraphicsMagick se trouvant dans gm convert et insérer toutes les fonctions avec tous les paramètres
demande énormément de temps.
Une fois avoir choisi le fichier, on choisit l'onglet Convert et apparaît les miniatures de
gauche (image originale) et de droite (image convertie) avec les fonctions du logiciel au centre.
Visualize sert à afficher la miniature convertie et convert sert à convertir le fichier taille réelle et
demande un chemin pour le fichier de sortie. Le fichier sera automatiquement converti avec le
format se trouvant dans la Combobox (une amélioration pourraît être de mettre par défaut le format
du fichier d'entrée dans la Combobox). Le principe des miniatures est de travailler sur des images
tailles réduites 250x250. Lors du choix du fichier à traiter, le fichier original est converti en .png de
taille 250x250 qui s'affiche dans la miniature de gauche. Ensuite le logiciel travail sur la conversion
de cette image réduite pour afficher la miniature de droite, ce qui permet d'améliorer le temps de
calcul des effets par exemple. Un double clique sur les miniature permet d'afficher les images en
Projet d'Interface GraphicsMagick – Projet Master 2 ISIS Audiovisuel et Multimédia – Dream – Université de Valenciennes (UVHC) - page 8
taille réelle. Il s'agit d'une GraphicsView et d'une GraphicsScene réimplémentées qui permettent
d'afficher une image et de lier les évènements souris à une action. La molette de la souris permet de
zoomer et le clique dans la fenêtre déplace la vue. Le système est fait de telle manière que la fenêtre
est censée représenter l'image entière, lors d'un clique aux ¾ horizontaux et verticaux de la fenêtre,
la vue va se centrer sur les ¾ horizontaux et verticaux de l'image.
En ce qui concerne les paramètres, il faut passer en « mode traitement », c'est à dire cliquer
sur le bouton Show Parameters, la TableView pour le choix des fichiers disparaît au profit des
boutons paramètres.
Projet d'Interface GraphicsMagick – Projet Master 2 ISIS Audiovisuel et Multimédia – Dream – Université de Valenciennes (UVHC) - page 9
Pour sortir du mode, le bouton Hide Parameters est utile.
Les fonctions se présentent généralement sous la forme d'une QgroupeBox que l'on peut cocher
(cocher une fonction ajoute la commande -fonction à la ligne de commade) puis de paramètres,
souvent des sliders et quelques fois une combobox ou une checkbox qui s'ajoute à la ligne de
commande suivant la fonction.
De plus, une TableView dans l'onglet Tasklist est pratique pour changer l'ordre des fonctions
cochées. Les fonctions sont réparties selon les onglets : Région qui permet de choisir la portion de
l'image où sera aplliquer les effets, Equalize, Color, Levels, Transform, Effects, Noise effects, Draw
Frame, Sampling. Seules les fonctions Draw servant à faire des annotations et des figures
géométiques sur l'image n'ont pas été mises manque de temps.
Une fois les réglages effectués, une fenêtre de de dialog s'ouvre après le clic sur Convert
pour choisir un nom ou un dossier de sortie (sauf si le chemin est déjà inscrit dans le lineEdit).
On peut choisir 3 modes de conversion, soit on convertie le fichier choisi (qui s'affiche dans
la miniature de gauche de la partie Input Files), soit on décide de convertir à la volée tous les
fichiers sélectionnés, soit on convertie tous les fichiers de la liste. C'est pratique pour appliquer le
même effet a des centaines d'images.
Lors de l'import des images dans la TableView de la partie supérieure, une fonction
CheckPoint() sert à éliminer les fichiers qui ne sont pas lisibles par Graphicsmagick. La fonction
gm identify nous retourne si le fichier est lisible ou non. Dès l'import du fichier (du chemin en
réalité), un timer est lancé et renvoie à la fonction Checkpoint jusqu'à ce que tous les fichiers ait été
contrôlé, après essai sur une centaine de fichiers non valides cela fonctionne. L'utilisateur est
informé par des fenêtres modales qui apparaîssent, de la même manière la cause de l'erreur est
affichée lors d'une mauvaise conversion.
Dernièrement, des textEdit qui sont pratiques car possèdent les fonctions undo() et redo()
permettent d'enregistrer tous les geste importants de l'utilisateur, c'est à dire non pas à chaque fois
que l'utilisateur pousse le slider et change le slider de la valeur 1 à 2, mais à chaque fois que
l'utilisateur fait un réglage d'une fonction. Globalement, à chaque fois qu'il coche une tâche ou qu'il
fait un undo/redo ou qu'il monte ou descend une tâche. Ceci est fait avec un premier textEdit qui
enregistre tous les changements (infimes variations des sliders etc...), puis un deuxième textEdit qui
enregistre la commande qui se trouve dans le premier textEdit généralement à chaque fois qu'une
tâche est cochée. Il y a 3 chaines de caractères enregistrées, la première enregistre la commande
pour l'image à taille réelle, la seconde pour l'image taille réduite, la dernière enregistre tous les
paramètres des fonctions GraphicsMagick pour les remmettre lors des undo/redo où lors du
chargement d'une ligne de commande enregistrée. Pour cela il a fallu créer une fonction qui sache
relire cette chaîne de caractère pour remettre les valeurs des boutons.
Dans la barre de menu, on peut faire les mêmes actions que celles citées précédement, on
peut lire les informations sur le fichier selectionné, regarder les formats pris en charge par le
système et les formats pris en charge par GraphicsMagick. On peut aussi consulter la
documentation sur les fonctions graphicsmagick, les liens des page html lance un navigateur
internet (si connexion internet).
Les raccourcis de chaque action sont indiqués dans le menu.
Projet d'Interface GraphicsMagick – Projet Master 2 ISIS Audiovisuel et Multimédia – Dream – Université de Valenciennes (UVHC) - page 10
4.
2. Organisation du code.
Une fois que le fichier ait été choisi (après la fonction DoubleClick() ou un drop qui appelle
cette dernière, le fichier est traité suivant le schéma suivant :
4. 3. Quelques explications sur le code.
–
Pour que l'effet qui s'applique à
l'image réduite soit le même que
l'effet s'appliquant à l'image taille
réelle, il a fallu extraire
l'information de taille qui se
trouve dans un fichier créé par une
redirection de la commande gm
identify -verbose /path , voici le
code :
Projet d'Interface GraphicsMagick – Projet Master 2 ISIS Audiovisuel et Multimédia – Dream – Université de Valenciennes (UVHC) - page 11
Après avoir créé un Qprocess qui remplace la fonction system() non compatible avec
windows, on lui ajoute une redirection vers un fichier correspondant à > /fichier.
La taille de l'image se trouvait dans le fichier après la chaîne « Geometry: » où les deux valeurs
étaient séparées par un « x » et possédaient deux espaces de chaque côté. Les fonctions Qt de la
classe Qstring sont pratiques pour extraire les informations.
–
La fonction gm identify retourne un code d'erreur qui envoie une fenêtre de dialogue informant
si le ou les fichiers sont lisibles et seront supprimés de la liste.
–
Comment monter ou descendre un fichier dans une liste :
Si l'item dans la liste de la tableview est sélectionné, on prend cet item à i et on l'insert à i+1.
enregistre la nouvelle position de la liste dans la liste cell. On réaffiche dans le nouvel ordre les
items de la tableview puis on se met en mode multiselection pour sélectionner les fichiers déplacés.
–
Conversion de l'image :
La command est prise d'un Qdocument, qui contient à tout moment le même texte que le
QtextEdit correspondant, on lui ajoute les chemin de fichier, l'extension, le -debug Error qui permet
avec la redirection dans le fichier log.txt les informations sur le déroulement de la conversion.
Si erreur, on appelle la fonction d'affichage de la fenêtre d'erreur.
Projet d'Interface GraphicsMagick – Projet Master 2 ISIS Audiovisuel et Multimédia – Dream – Université de Valenciennes (UVHC) - page 12
–
A chaque convertion on insert au début progbar->setMinimum(0); puis après la conversion
progbar->setMaximum(100); qui permettent de faire tourner la barre de progression.
–
Dans la fonction Undo() on remarque que les trois historiques TextEdit sont changés en même
temps (sinon tout se décale), ensuite on reset les checkbox, on decode la chaine de caractère, on
affiche les tâches et on convertie l'image miniature.
–
Lors d'un chargement d'une ligne de commande, on récupère le nom du fichier qui avait été
enregistré, on enregistre les boutons paramètres s'il y a des changements, on reset les checkbox,
on lit le fichier enregistré et pour ne pas décaler l'historique, on doit enregistrer les commandes
image réelle et image miniature dans l'historique après avoir décodé la chaine de caractères des
paramètres et avoir édité les lignes de commande.
Projet d'Interface GraphicsMagick – Projet Master 2 ISIS Audiovisuel et Multimédia – Dream – Université de Valenciennes (UVHC) - page 13
–
Fonction Update() du timer :
void QtMini::update(){
if(afficherimage==true){//affiche la miniature de gauche dans Input Files
if(tv1->currentRow()<0){tv1->setCurrentCell(list.size()-1,0);}
QString str;
str.append("gm convert \"").append(list.at(tv1->currentRow())).append("\" -resize 150x150
").append("./imagestemp/label1.png");
QProcess *myProcess = new QProcess();
myProcess->start(str,QIODevice::NotOpen);
while(myProcess->waitForFinished()==false);
pixmap1 = QPixmap("./imagestemp/label1.png","png");
label1->setPixmap(pixmap1);
afficherimage=false;
}
//pour visualiser le temps de convertion a l'utilisateur (en réalité plus court)
progbar->setMaximum(100);
progbar->reset();
if(afficherwindo21==true){//image miniature de gauche dans Convert
savename="./imagestemp/converted1.png";//tiff pour voir l'image en bonne qualité
Convert();
QGraphicsView *view21 = new MyQGraphicsView();
scene21 = new QGraphicsScene();
pixmapwindo21 = QPixmap(savename,"png");
scene21->addPixmap(pixmapwindo21);
scene21->setBackgroundBrush(Qt::lightGray);//gris moyen 18% c0c0c0
view21->setWindowTitle("Original Frame");
view21->setScene(scene21);
view21->setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate);
view21->show();
afficherwindo21=false;
}
if(afficherwindo22==true){//image miniature de droite dans Convert
Visualize();//affiche l'image de droite avant d'ouvrir la fenêtre
savename="./imagestemp/converted2.png";
Convert();
QGraphicsView *view22 = new MyQGraphicsView();
scene22 = new QGraphicsScene();
pixmapwindo22 = QPixmap(savename,"png");
scene22->addPixmap(pixmapwindo22);
scene22->setBackgroundBrush(Qt::lightGray);//gris moyen 18% c0c0c0
view22->setWindowTitle("Final Frame");
view22->setScene(scene22);
view22->setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate);
view22->show();
afficherwindo22=false;
}
if(list.size()==0){
DisableTabs();
b12->setEnabled(false);
b13->setEnabled(false);
b14->setEnabled(false);
b15->setEnabled(false);
pixmap1 = QPixmap("./icones/label1.png","png");
label1->setPixmap(pixmap1);
pixmap1=QPixmap("./icones/froggris.png","png");label1->setPixmap(pixmap1);
}
Projet d'Interface GraphicsMagick – Projet Master 2 ISIS Audiovisuel et Multimédia – Dream – Université de Valenciennes (UVHC) - page 14
else{b12->setEnabled(true);b13->setEnabled(true);b14->setEnabled(true);b15->setEnabled(true);}
if(tasklist.size()==0)bundo->setEnabled(false);else bundo->setEnabled(true);
if(drop==true){FileNames();drop=false;timer2->start(300);}
if(drop23==true){FileNames();DoubleClick();drop23=false;timer2->start(300);}
if(visualize==true){Visualize();visualize=false;}
savepath=le3->text();
int n = savepath.lastIndexOf("/");
savefolder = savepath.left(n);
//labelw->setText(savefolder);
}
A chaque fois qu'il y a un drop ou un événement qui ordonne une action, des variables booléennes
sont utilisées pour que lorsque le timer envoie un timeout (toutes les 300ms), l'ordre soit exécuté.
Cela permet de récuperer les Drops, les évènements de l'utilisateur comme le double clique pour
afficher la fenêtre de l'image taille réelle, ou encore d'effectuer la conversion de l'image miniature
toutes les 300ms pour éviter un overflow du processeur.
–
Drop event :
Il faut réimplémenter la TableWidget pour qu'elle reçoive le drop, ensuite il ne faut prendre que le
nécessaire du contenu (mimedata) du drop. Dans notre cas on filtre les urls seulement c'est à dire les
chemins de fichiers et on les ajoute à la liste.
–
Une tâche est insérée dans la liste que si elle n'y est pas présente.
Cela pose un problème de limite du logiciel qui ne peut pas effectuer deux fois la même tâche...
Projet d'Interface GraphicsMagick – Projet Master 2 ISIS Audiovisuel et Multimédia – Dream – Université de Valenciennes (UVHC) - page 15
–
Ordre des tâche et édition de la ligne de commande :
La liste des tâches permet de changer l'ordre des tâches, on lit chaque à chaque id dans
l'ordre croissant de la liste pour voir si la tâche est présente, si c'est le cas on ajoute la commande
correspondante à la commande principale. Comme dit précédement, il y a trois commandes (str
pour l'image taille réelle, str250 pour la miniature, et buttonstring pour les paramètres des boutons).
Les lignes de commandes sont remplies par les valeurs des paramètres, ex : reggb1sl1->value() est
la valeur du slider 1 de la groupbox 1 de l'onglet Région.
La chaine de caractères comprenant les paramètres se compose de la manières suivante :
/-tache1/param1tâche1/param2tâche2/-tâche2/param1tâche2/.../...
–
Décodage de la chaine de paramètres :
On split la chaine grâce au slash en une liste et on lit chaque élément de la liste pour voir si une
tâche s'y trouve, si c'est le cas on enregistre les paramètres qui suivent.
–
La fonction ResetAll() sert à initialiser ou réinitialiser les textEdits et tous les boutons
paramètres de l'onglet Convert.
Projet d'Interface GraphicsMagick – Projet Master 2 ISIS Audiovisuel et Multimédia – Dream – Université de Valenciennes (UVHC) - page 16
5. Problèmes rencontrés
Il n'y a pas eu vraiment de problèmes rencontrés lors de la programmation car tout
simplement tout problème a sa solution, ensuite le problème majeur était de trouver la solution, soit
en recherchant toutes les options possibles dans la très bonne documentation Qt, soit sur Internet. Il
faut parfois essayer plusieurs solution et repenser le code si la solution ne convient pas.
Il faut aussi éviter les copier-coller mais il est parfois difficile de se représenter les paramètres qui
pourrait différencier chaque fonction. Par exemple on aurait pu faire une fonction pour créer les
boutons de paramètres en fonction de la tâche. Combien de slider pour cette tâche, combien de
ComboBox etc... il est certain maintenant que construire une fonction de la sorte aurait été plus
rapide que de faire du copier-coller pour tous les boutons paramètres. De plus le code est de ce fait
trop long et met beaucoup plus de temps à compiler, il est parfois difficile une fois que tout
fonctionne de réorganiser le code sans faire d'erreur. On fait face sans arrêt à des bugs dont il est
difficile d'en définir la cause, le plus simple et alors de prendre un crayon et une feuille.
Le temps passé pour réaliser ce logiciel est assez inquiétant par rapport à sa complexité. Il aurait
fallu insérer de nouvelles fonctions et faire des boutons paramètres plus adaptés et réimplémentés
mais le temps ne suffit pas.
6. Remerciements
Je remercie Cédric Lejeune pour ce sujet de projet qui s'est avéré en fait non pas une idée de
projet pour étudiant mais un vrai projet d'initiation au développement d'une interface
GraphicsMagick commerciale.
Je remercie Alain Gibaud pour les cours de Qt qui m'ont beaucoup servi cette année.
Projet d'Interface GraphicsMagick – Projet Master 2 ISIS Audiovisuel et Multimédia – Dream – Université de Valenciennes (UVHC) - page 17