Compare commits
47 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 92345f82ca | |||
| 3c8f49e932 | |||
| 37dd97e361 | |||
| da31187aa3 | |||
| 4801338160 | |||
| fb9d026ff5 | |||
| c2810faf8f | |||
| d3d302fd38 | |||
| a0497c7d19 | |||
| 8818e25eda | |||
| c3baa18087 | |||
| 66f0c05a48 | |||
| 461ffea874 | |||
| 7535ad87e7 | |||
| 273aef1594 | |||
| 9519c9830c | |||
| 342e5cc5db | |||
| ae84cbdfe0 | |||
| 933fd4a2a0 | |||
| c3588e1c36 | |||
| 174134a9ee | |||
| bbc13ec8a5 | |||
| 9f7e2ab6b4 | |||
| 4fe56acbd9 | |||
| f35db9d1af | |||
| 81d138f799 | |||
| ae07d4793b | |||
| dc2a781d3b | |||
| 90035f44ed | |||
| 53c9a58125 | |||
| 3f7e3689e8 | |||
| af9187737f | |||
| 4e952873e3 | |||
| fb24800050 | |||
| ea0dcc226a | |||
| 6a7b677b95 | |||
| 0cee4c9c53 | |||
| d5f2351905 | |||
| 18732a8cbf | |||
| 8c9c1d8d06 | |||
| e5f425ff8d | |||
| 428f9c360a | |||
| a8a1509db7 | |||
| 6539c78c57 | |||
| 0e0d29320e | |||
| 1efe8e6974 | |||
| dae10182d1 |
+2
-1
@@ -66,6 +66,7 @@ if(WIN32)
|
||||
set(tenmon_ICON "")
|
||||
elseif(APPLE)
|
||||
set(tenmon_ICON ${CMAKE_CURRENT_SOURCE_DIR}/resources/tenmon.icns)
|
||||
find_package(Qt6 COMPONENTS DBus REQUIRED)
|
||||
set_source_files_properties(${tenmon_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
|
||||
else()
|
||||
set(tenmon_ICON "")
|
||||
@@ -85,7 +86,7 @@ endif()
|
||||
|
||||
target_link_libraries(tenmon PRIVATE Qt6::Widgets Qt6::Sql Qt6::OpenGLWidgets Qt6::Qml ${GSL_LIB} ${GSLCBLAS_LIB} ${EXIF_LIB} ${FITS_LIB} ${RAW_LIB} ${WCS_LIB} XISF)
|
||||
if(APPLE)
|
||||
target_link_libraries(tenmon PRIVATE "-framework CoreFoundation")
|
||||
target_link_libraries(tenmon PRIVATE Qt6::DBus "-framework CoreFoundation")
|
||||
elseif(UNIX)
|
||||
target_link_libraries(tenmon PRIVATE Qt6::DBus ${GIO_LDFLAGS})
|
||||
endif(APPLE)
|
||||
|
||||
@@ -2,7 +2,7 @@ FITS/XISF image viewer with multithreaded image loading
|
||||
|
||||
To get all dependencies install these packages
|
||||
|
||||
sudo apt install qt6-base-dev libqt6opengl6-dev libraw-dev libexif-dev libcfitsio-dev libgsl-dev wcslib-dev cmake
|
||||
sudo apt install qt6-base-dev qt6-declarative-dev libqt6opengl6-dev libraw-dev libexif-dev libcfitsio-dev libgsl-dev wcslib-dev cmake
|
||||
|
||||
on OpenSUSE
|
||||
|
||||
|
||||
+118
-1
@@ -14,7 +14,7 @@ img { margin: 5px; }
|
||||
<li>FITS 8, 16, 32 bit integer and 32, 64 bit float</li>
|
||||
<li>XISF 8, 16, 32 bit integer and 32, 64 bit float</li>
|
||||
<li>JPEG, PNG, BMP, GIF, PBM, PGM, PPM and SVG images</li>
|
||||
<li>CR2, NEF, DNG raw images</li>
|
||||
<li>CR2, CR3, NEF, DNG raw images</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
@@ -115,6 +115,123 @@ Pressing Enter or clicking on <i>Filter</i> button will filter out database reco
|
||||
<br><img src=":/about/filter.png"><br>
|
||||
This example filters for files where: "Bias" is in the file name, the OBJECT property is "M_42" (where the underscore can be any single character), and the DATE property begins with "2022".
|
||||
</p>
|
||||
|
||||
|
||||
<h3>Batch processing</h3>
|
||||
|
||||
This module allow to write scripts in JavaScript that process image files. Batch Processing window consist from three main parts. On top is list of input files and directories.
|
||||
You can add directories or individual files to this list. Directories are scanned recursively to find all files even non image files. This list of files is then passed to script in array named <b>files</b>.
|
||||
In script you can then iterate through files like this.
|
||||
<pre>for(file of files)
|
||||
{
|
||||
if(file.suffix() == "fits")
|
||||
{
|
||||
core.log(file.fileName());
|
||||
file.convert(file.relativeFilePath(), "XISF");
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
<p>Bellow this list is output directory. All relative paths passed as arguments into methods like copy(), move() or convert() will be relative to this output directory. If you pass absolute path to methods then
|
||||
this output directory is ignored.</p>
|
||||
|
||||
<p>Bellow that is list of scripts. These scripts are located in application data directory. Select script which you want to run by clicking on it. Clicking on <i>Open scripts</i> will open directory with these scripts where you create new and edit them.
|
||||
Location of this directory is on Windows: "C:/Users/<USER>/AppData/Roaming/nou/Tenmon" Linux: "~/.local/share/nou/Tenmon/scripts" MacOS: "~/Library/Application Support/nou/Tenmon/scripts"</p>
|
||||
|
||||
<p>Next is Log windows that contain any messages that come from scripts. Mainly calls to <code>core.log()</code> At bottom there buttons that can start or stop execution of selected scripts.</p>
|
||||
|
||||
<h4>core</h4>
|
||||
There is global object called <b>core</b> that have these methods.
|
||||
<ul>
|
||||
<li><b>log(message)</b> print message to log window.</li>
|
||||
<li><b>mark(file)</b> mark file same way as in GUI. Takes object of type <i>File</i> as argument.</li>
|
||||
<li><b>unmark(file)</b> unmark file same was as in GUI. Takes object of type <i>File</i> as argument.</li>
|
||||
<li><b>isMarked(file)</b> check if file was marked. Takes object of type <i>File</i> as argument.</li>
|
||||
<li><b>setMaxThread(maxthread)</b> set maximum number of concurrent thread when doing asynchronous task.</li>
|
||||
<li><b>sync()</b> wait until all asynchronous tasks are done.</li>
|
||||
<li><b>getString(label = "", text = "")</b> show dialog box to get string value from user. String value passed in first argument is used as description label. Second argument text is default value in text box.
|
||||
Both parameters are optional so calling just <i>getString()</i> is valid. When cancel is pressed it return Undefined.</li>
|
||||
<li><b>getInt(label = "", value = 0)</b> show dialog box with input box to retrieve integer value. String value passed in first argument is used as description label.
|
||||
Second parameter is default value in input box. Both parameters are optional. When cancel is pressed it return Undefined.</li>
|
||||
<li><b>getFloat(label = "", value = 0, decimals = 3)</b> show dialog box with input box to retrieve decimal value. String value passed in first argument is used as description label.
|
||||
Second parameter is default value in input box. All three parameters are optional. When cancel is pressed it return Undefined.</li>
|
||||
<li><b>getItem(items)</b> show selection dialog which allow to select one item from array of items. It return selected item as string. When cancel is pressed it return Undefined.</li>
|
||||
</ul>
|
||||
|
||||
<h4>File</h4>
|
||||
In <b>files</b> array there are instances of type <b>File</b> objects that have these methods.
|
||||
<ul>
|
||||
<li><b>fileName()</b> returns the name of the file, excluding the path.</li>
|
||||
<li><b>absoluteFilePath()</b> returns an absolute path including the file name.</li>
|
||||
<li><b>absolutePath()</b> returns an absolute path without the file name</li>
|
||||
<li><b>relativeFilePath()</b> return relative path including file name relative to directory that was in list of directories to be scanned. For example you add C:/images as input directory. In this directory there
|
||||
is file <i>C:/images/lights/red/M42_001.fits</i> then this method will return <i>lights/red/M42_001.fits</i></li>
|
||||
<li><b>relativePath()</b> return same path as previous method just without file name. <i>lights/red</i></li>
|
||||
<li><b>baseName()</b> return file name up to the first dot. For example for <i>some.file.name.fits</i> it will return <i>some</i></li>
|
||||
<li><b>completeBaseName()</b> return file name up to the last dot. For example for <i>some.file.name.fits</i> it will return <i>some.file.name</i></li>
|
||||
<li><b>suffix()</b> return string after last dot in file name. For example <i>fits</i></li>
|
||||
<li><b>size()</b> return size of file in bytes.</li>
|
||||
<li><b>fitsKeywords()</b> return array of strings with every keyword that is in header. <i>SIMPLE,BITPIX,NAXIS,NAXIS1,NAXIS2,EXTEND,COMMENT</i></li>
|
||||
<li><b>fitsValue(key)</b> return value for keyword. In case that there is multiple occurrences it return last one.</li>
|
||||
<li><b>fitsValues(key)</b> return array of values for keyword.</li>
|
||||
<li><b>fitsRecords()</b> return array of objects with properties <b>key, value</b> and <b>comment</b> </li>
|
||||
<li><b>modifyFITSRecords(FITSRecordModify)</b> modify FITS header by adding, removing or updating FITS record. Return true on success. Refer to <i>FITSRecordModify</i></li>
|
||||
<li><b>isMarked()</b> return true if file is marked.</li>
|
||||
<li><b>copy(newpath)</b> copy file to new location. It return instance of new <i>File<i> object that represent this copied file. This path can be relative or absolute. In case that <i>newpath</i> parameter is relative
|
||||
path then it "Output directory" from GUI windows is used as base directory. Parameter <i>newpath</i> can absolute path. File is then copied to this path. In case that copy fail it return null.</li>
|
||||
<li><b>move(newpath)</b> move file to new location. It return false if move failed. This can happend if destination is not writable but also if destination file already exist. This functions does not overwrite existing file.
|
||||
This path can be relative or absolute. In case that <i>newpath</i> parameter is relative path then it "Output directory" from GUI windows is used as base directory. Parameter <i>newpath</i> can be absolute path.
|
||||
File is then moved to this path.</li>
|
||||
<li><b>convert(outpath, format, params)</b> convert image file from any format that program is able to open into FITS, XISF, JPEG, PNG, BMP.
|
||||
Parameters are: <i>outputpath</i> path where converted image will be saved. It automatically replace suffix according to format. <i>format</i> one of "FITS" "XISF", "JPG", "PNG" or "BMP". <i>params</i> object with attributes "compressionType" and "compressionLevel".
|
||||
Valid values for compressionType are be "gzip" or "rice" when converting to FITS. When converting to XISF compressionType can be "zlib", "lz4", "lz4hc", "zstd", "zlib+sh", "lz4+sh", "lz4hc+sh", "zstd+sh".
|
||||
It is recommended to use "+sh" variants of compression.
|
||||
XISF format also accept "compressionLevel" in range 0-100 where zero is fastest compression and 100 slowest. If you omit this attribute or set it to -1 then default compression level will be used.
|
||||
It return new instance of <i>File</i> that point to converted file.
|
||||
<pre>file.convert("converted_file.xisf", "xisf", {"compressionType": "zstd+sh", "compressionLevel": 70});
|
||||
file.convert("converted_file.fits", "fits", {"compressionType": "rice"});
|
||||
file.convert("converted_file.jpg", "png");</pre>
|
||||
</li>
|
||||
<li><b>convertAsync(outpath, format, params)</b> same as previous method but it does conversion in separated thread asynchronously and in parallel. Before calling any method on object returned by this method you must call
|
||||
<code>core.sync();</code> to ensure that conversion is done and destination file exists.
|
||||
<pre>let compression = {"compressionType": "zstd+sh"};
|
||||
let convertedFiles = [];
|
||||
for(file in files)
|
||||
{
|
||||
if(file.suffix() == "fits")
|
||||
convertedFiles.push(file.convertAsync("xisf/" + file.fileName(), "XISF", compression));
|
||||
}
|
||||
core.sync(); // ensure that files exist
|
||||
for(file of convertedFiles)// now we can iterate over the files
|
||||
{
|
||||
core.log(file.fileName() + " " + file.size()); // let print compressed file sizes
|
||||
}</pre></li>
|
||||
<li><b>stats()</b> calculate basic images statistics and return them as object with attributes "mean", "stddev", "median", "min", "max" and "mad".
|
||||
<pre>let s = file.stats();
|
||||
core.log("Median value is " + s.median);</pre></li>
|
||||
</ul>
|
||||
|
||||
<h4>FITSRecordModify</h4>
|
||||
This class is used to define modify operation FITS header in FITS and XISF files. It can remove update and add records. Order of operation is also remove then update and last add.
|
||||
The keyword names may be up to 8 characters long and can only contain uppercase letters, the digits 0-9, the hyphen, and the underscore character.
|
||||
<pre>let modify = new FITSRecordModify();
|
||||
modify.updateKeyword("OBJECT", "M42");
|
||||
modify.updateKeyword("MYTILE", "PART1", "adding custom keyword so WBPP can group it");
|
||||
modify.removeKeyword("OBJECT");
|
||||
// doesn't matter that it is specified as last. This will first remove
|
||||
// existing OBJECT record and then add again OBJECT=M42
|
||||
for(file in files)
|
||||
{
|
||||
file.modifyFITSRecords(modify);
|
||||
}</pre>
|
||||
|
||||
<ul>
|
||||
<li><b>new FITSRecordModify()</b> create new instance of object.</li>
|
||||
<li><b>removeKeyword(key);</b> specify removing of record with <i>key</i> as keyword.</li>
|
||||
<li><b>updateKeyword(key, value, comment = "")</b> specify updating existing keyword with value and comment. Comment is optional parameter. If record with keyword doesn't exist then it will add new one.
|
||||
Unless you want to have multiple records with same keyword (for example HISTORY) always use this method and not addKeyword.</li>
|
||||
<li><b>addKeyword(key, value, comment = "")</b> specify adding new keyword</li>
|
||||
</ul>
|
||||
|
||||
<p><small>PS: Kanji in icon means astronomy in Japanese</small></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+109
-1
@@ -14,7 +14,7 @@ img { margin: 5px; }
|
||||
<li>FITS 8, 16 bit entier et 32 bit point flottant</li>
|
||||
<li>XISF 8, 16 bit entier et 32 bit point flottant</li>
|
||||
<li>images JPEG, PNG, BMP, GIF, PBM, PGM, PPM et SVG</li>
|
||||
<li>images RAW CR2, NEF, DNG</li>
|
||||
<li>images RAW CR2, CR3, NEF, DNG</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
@@ -101,6 +101,114 @@ En appuyant sur la touche Enter ou en cliquant sur le bouton <i>Filtre</i>, les
|
||||
<br><img src=":/about/filter.png"><br>
|
||||
Cet exemple filtre les fichiers où : "Bias" figure dans le nom de fichier, la propriété OBJECT est "M_42" (où le trait de soulignement peut être n'importe quel caractère) et la propriété DATE commence par "2022".
|
||||
</p>
|
||||
|
||||
<h3>Traitement par lot</h3>
|
||||
|
||||
Ce module permet d'écrire des scripts en JavaScript qui traitent des fichiers images. La fenêtre de traitement par lots se compose de trois parties principales. En haut se trouve la liste des fichiers et répertoires d'entrée.
|
||||
Vous pouvez ajouter des répertoires ou des fichiers individuels à cette liste. Les répertoires sont analysés de manière récursive pour trouver tous les fichiers, même les fichiers non image. Cette liste de fichiers est ensuite transmise au script dans un tableau nommé <b>files</b>.
|
||||
Dans le script, vous pouvez ensuite parcourir les fichiers comme ici.
|
||||
<pre>for(file of files)
|
||||
{
|
||||
if(file.suffix() == "fits")
|
||||
{
|
||||
core.log(file.fileName());
|
||||
file.convert(file.relativeFilePath(), "XISF");
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h4>core</h4>
|
||||
Il existe un objet global appelé <b>core</b> qui possède ces méthodes.
|
||||
<ul>
|
||||
<li><b>log(message)</b> afficher le message dans la fenêtre du journal.</li>
|
||||
<li><b>mark(file)</b> marquer le fichier de la même manière que dans l'interface graphique. Prend un objet de type <i>File</i> comme argument.</li>
|
||||
<li><b>unmark(file)</b> décoche le fichier de la même manière que dans l'interface graphique. Prend un objet de type <i>File</i> comme argument.</li>
|
||||
<li><b>isMarked(file)</b> vérifie si le fichier a été marqué. Prend un objet de type <i>File</i> comme argument.</li>
|
||||
<li><b>setMaxThread(maxthread)</b> définir le nombre maximal de threads simultanés lors de l'exécution d'une tâche asynchrone.</li>
|
||||
<li><b>sync()</b> attendre que toutes les tâches asynchrones soient terminées.</li>
|
||||
<li><b>getString(label = "", text = "")</b> affiche la boîte de dialogue pour obtenir un text de l'utilisateur. La valeur text passée dans le premier argument est utilisée comme label de description. Le texte du deuxième argument est la valeur par défaut dans la zone de texte.
|
||||
Les deux paramètres sont facultatifs, donc l'appel à <i>getString()</i> est valide. Lorsque vous appuyez sur Annuler, il renvoie Undefined</li>
|
||||
<li><b>getInt(label = "", value = 0)</b> affiche une boîte de dialogue avec une zone de saisie pour récupérer une valeur entière. Le texte passé dans le premier argument est utilisé comme label de description.
|
||||
Le deuxième paramètre est la valeur par défaut dans la zone de saisie. Les deux paramètres sont facultatifs. Lorsque vous appuyez sur Annuler, il renvoie Undefined.</li>
|
||||
<li><b>getFloat(label = "", value = 0, decimals = 3)</b> affiche une boîte de dialogue avec une zone de saisie pour récupérer une valeur décimale. Le texte passé dans le premier argument est utilisé comme label de description.
|
||||
Le deuxième paramètre est la valeur par défaut dans la zone de saisie. Les trois paramètres sont facultatifs. Lorsque vous appuyez sur Annuler, il renvoie Undefined.</li>
|
||||
<li><b>getItem(items)</b> affiche une boîte de dialogue de sélection qui permet de sélectionner un élément dans un tableau d'éléments. Lorsque vous appuyez sur Annuler, il renvoie Undefined.</li>
|
||||
</ul>
|
||||
|
||||
<h4>File</h4>
|
||||
Dans le tableau <b>files</b>, il y a des instances d'objets de type <b>File</b> qui ont ces méthodes.
|
||||
<ul>
|
||||
<li><b>fileName()</b> renvoie le nom du fichier, à l'exclusion du chemin.</li>
|
||||
<li><b>absoluteFilePath()</b> renvoie un chemin absolu incluant le nom du fichier.</li>
|
||||
<li><b>absolutePath()</b> renvoie un chemin absolu sans le nom du fichier</li>
|
||||
<li><b>relativeFilePath()</b> renvoie le chemin relatif incluant le nom du fichier par rapport au répertoire qui était dans la liste des répertoires à analyser. Par exemple, vous ajoutez C:/images comme répertoire d'entrée. Dans ce répertoire, il y a
|
||||
le fichier <i>C:/images/lights/red/M42_001.fits</i>, alors cette méthode renverra <i>lights/red/M42_001.fits</i></li>
|
||||
<li><b>relativePath()</b> renvoie le même chemin que la méthode précédente, mais sans le nom de fichier. <i>lights/red</i></li>
|
||||
<li><b>baseName()</b> renvoie le nom du fichier jusqu'au premier point. Par exemple, pour <i>some.file.name.fits</i>, il renverra <i>some</i></li>
|
||||
<li><b>completeBaseName()</b> renvoie le nom du fichier jusqu'au dernier point. Par exemple, pour <i>some.file.name.fits</i>, il renverra <i>some.file.name</i></li>
|
||||
<li><b>suffix()</b> renvoie la chaîne après le dernier point du nom de fichier. Par exemple <i>fits</i></li>
|
||||
<li><b>size()</b> renvoie la taille du fichier en octets.</li>
|
||||
<li><b>fitsKeywords()</b> renvoie un tableau de chaînes avec chaque mot-clé présent dans l'en-tête. <i>SIMPLE,BITPIX,NAXIS,NAXIS1,NAXIS2,EXTEND,COMMENT</i></li>
|
||||
<li><b>fitsValue(key)</b> renvoie la valeur pour le mot-clé. En cas d'occurrences multiples, la dernière est renvoyée.</li>
|
||||
<li><b>fitsValues(key)</b> renvoie un tableau de valeurs pour le mot clé.</li>
|
||||
<li><b>fitsRecords()</b> renvoie un tableau d'objets avec des propriétés <b>key, value</b> et <b>comment</b> </li>
|
||||
<li><b>modifyFITSRecords(FITSRecordModify)</b> modifier l'en-tête FITS en ajoutant, supprimant ou mettant à jour l'enregistrement FITS. Renvoie true en cas de succès. Reportez-vous à <i>FITSRecordModify</i></li>
|
||||
<li><b>isMarked()</b> renvoie true si le fichier est marqué.</li>
|
||||
<li><b>copy(newpath)</b> Copie le fichier vers un nouvel emplacement. Il renvoie une instance du nouvel objet <i>File<i> qui représente ce fichier copié. Ce chemin peut être relatif ou absolu. Dans le cas où le paramètre <i>newpath</i> est un chemin relatif, le "Répertoire de sortie" des fenêtres de l'interface graphique est utilisé comme répertoire de base. Le paramètre <i>newpath</i> peut être un chemin absolu. Le fichier est ensuite copié vers ce chemin. En cas d'échec de la copie, il renvoie null.</li>
|
||||
<li><b>move(newpath)</b> déplacer le fichier vers un nouvel emplacement. Il renvoie false si le déplacement a échoué. Cela peut se produire si la destination n'est pas accessible en écriture mais aussi si le fichier de destination existe déjà. Cette fonction n'écrase pas le fichier existant.
|
||||
Ce chemin peut être relatif ou absolu. Dans le cas où le paramètre <i>newpath</i> est un chemin relatif, le "répertoire de sortie" des fenêtres de l'interface graphique est utilisé comme répertoire de base. Le paramètre <i>newpath</i> peut être un chemin absolu.
|
||||
Le fichier est ensuite déplacé vers ce chemin.</li>
|
||||
<li><b>convert(outpath, format, params)</b> Convertir un fichier image à partir de n'importe quel format que le programme peut ouvrir en FITS, XISF, JPEG, PNG, BMP.
|
||||
Les paramètres sont : <i>outputpath</i> chemin où l'image convertie sera enregistrée. Il remplace automatiquement le suffixe en fonction du format. <i>format</i> l'un des éléments suivants : "FITS", "XISF", "JPG", "PNG" ou "BMP". <i>params</i> objet avec les attributs "compressionType" et "compressionLevel".
|
||||
Les valeurs valides pour compressionType sont "gzip" ou "rice" lors de la conversion en FITS. Lors de la conversion en XISF, compressionType peut être "zlib", "lz4", "lz4hc", "zstd", "zlib+sh", "lz4+sh", "lz4hc+sh", "zstd+sh".
|
||||
Il est recommandé d'utiliser les variantes de compression "+sh".
|
||||
Le format XISF accepte également les "compressionLevel" dans la plage 0-100, où zéro est la compression la plus rapide et 100 la plus lente. Si vous omettez cet attribut ou le définissez sur -1, le niveau de compression par défaut sera utilisé.
|
||||
Il renvoie une nouvelle instance de <i>File</i> qui pointe vers le fichier converti.
|
||||
<pre>file.convert("converted_file.xisf", "xisf", {"compressionType": "zstd+sh", "compressionLevel": 70});
|
||||
file.convert("converted_file.fits", "fits", {"compressionType": "rice"});
|
||||
file.convert("converted_file.jpg", "png");</pre>
|
||||
</li>
|
||||
<li><b>convertAsync(outpath, format, params)</b> même méthode que la précédente, mais effectue la conversion dans un thread séparé de manière asynchrone et en parallèle. Avant d'appeler une méthode sur un objet renvoyé par cette méthode, vous devez appeler
|
||||
<code>core.sync();</code> pour s'assurer que la conversion est effectuée et que le fichier de destination existe.
|
||||
<pre>let compression = {"compressionType": "zstd+sh"};
|
||||
let convertedFiles = [];
|
||||
for(file of files)
|
||||
{
|
||||
if(file.suffix() == "fits")
|
||||
convertedFiles.push(file.convertAsync("xisf/" + file.fileName(), "XISF", compression));
|
||||
}
|
||||
core.sync(); // ensure that files exist
|
||||
for(file of convertedFiles)// now we can iterate over the files
|
||||
{
|
||||
core.log(file.fileName() + " " + file.size()); // let print compressed file sizes
|
||||
}</pre></li>
|
||||
<li><b>stats()</b> calculer les statistiques d'images de base et les renvoyer sous forme d'objet avec des attributs "mean", "stddev", "median", "min", "max" et "mad".
|
||||
<pre>let s = file.stats();
|
||||
core.log("Median value is " + s.median);</pre></li>
|
||||
</ul>
|
||||
|
||||
<h4>FITSRecordModify</h4>
|
||||
Cette classe est utilisée pour définir l'en-tête FITS des opérations de modification dans les fichiers FITS et XISF. Elle peut supprimer, mettre à jour et ajouter des enregistrements. L'ordre des opérations est également le suivant : suppression, puis mise à jour et enfin ajout.
|
||||
Les noms des mots-clés peuvent comporter jusqu'à 8 caractères et ne peuvent contenir que des lettres majuscules, les chiffres de 0 à 9, le trait d'union et le caractère de soulignement.
|
||||
<pre>let modify = new FITSRecordModify();
|
||||
modify.updateKeyword("OBJECT", "M42");
|
||||
modify.updateKeyword("MYTILE", "PART1", "adding custom keyword so WBPP can group it");
|
||||
modify.removeKeyword("OBJECT");
|
||||
// Peu importe qu'il soit spécifié comme dernier. Cela supprimera d'abord
|
||||
// l'enregistrement OBJECT existant, puis ajoutera à nouveau OBJECT=M42
|
||||
for(file in files)
|
||||
{
|
||||
file.modifyFITSRecords(modify);
|
||||
}</pre>
|
||||
|
||||
<ul>
|
||||
<li><b>new FITSRecordModify()</b> créer une nouvelle instance de l'objet.</li>
|
||||
<li><b>removeKeyword(key);</b> spécifier la suppression de l'enregistrement avec <i>key</i> comme mot-clé.</li>
|
||||
<li><b>updateKeyword(key, value, comment = "")</b> spécifiez la mise à jour du mot-clé existant avec la valeur et le commentaire. Le commentaire est un paramètre facultatif. Si l'enregistrement avec le mot-clé n'existe pas, il en ajoutera un nouveau.
|
||||
À moins que vous ne souhaitiez avoir plusieurs enregistrements avec le même mot-clé (par exemple HISTORY), utilisez toujours cette méthode et non addKeyword.</li>
|
||||
<li><b>addKeyword(key, value, comment = "")</b> spécifier l'ajout d'un nouveau mot-clé</li>
|
||||
</ul>
|
||||
|
||||
<p><small>PS: Le Kanji de icône (tenmon) signifie astronomie en japonais</small></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+120
-1
@@ -13,7 +13,7 @@ p { padding:0px; margin:5px 5px 10px 5px; }
|
||||
<li>FITS 8, 16, 32 bitové celočíselné 32 a 64 bitové s plávajúcou čiarkou</li>
|
||||
<li>XISF 8, 16, 32 bitové celočíselné 32 a 64 bitové s plávajúcou čiarkou</li>
|
||||
<li>JPEG, PNG, BMP, GIF, PBM, PGM, PPM a SVG obrázky</li>
|
||||
<li>CR2, NEF, DNG raw obrázky</li>
|
||||
<li>CR2, CR3, NEF, DNG raw obrázky</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
@@ -78,9 +78,128 @@ Pre indexovanie nových súborov je treba znova pustiť indexáciu.</p>
|
||||
kde sú jednotlivé stĺpcoch zobrazené vybrané vlastnosti. V spodnej časti panelu je tlačidlo ktoré zobrazí dialóg na výber zobrazovaných
|
||||
sĺpcov. Nasledujú tri výberové a textové polia. Tieto slúžia na vyhľadávanie v databáze. Výberové pole určuje stĺpec v ktorom sa
|
||||
má vyhľadávať a do textového poľa sa zadáva hodnota na vyhľadanie.
|
||||
|
||||
<p>Zastupné znaky:
|
||||
<ul>
|
||||
<li><b>%</b> (percent) je zastupný znak reprezentujúci žiadný alebo hocikoľko znakov.</li>
|
||||
<li><b>_</b> (underscore) je zastupný znak nahrádzajúci presne jeden znak.</i>
|
||||
<li>Bez zástupných znako sa hľadá presná zhoda.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<br><img src=":/about/filter.png"><br>
|
||||
V nasledovnom príklade sa vyhľadajú súbory ktoré majú v mene súboru "Bias", OBJECT je M_42 a DATE začína reťazcom 2022. Znak % sa berie ako
|
||||
zástupný znak za hocijaký reťazec znakov aj žiadny. Znak _ je tiež zástupný znak zastupujúci práve jeden znak.
|
||||
Bez použitia zástupných znakov sa vyhľadá iba presný výskyt.</p>
|
||||
|
||||
<h3>Hromadné spracovanie</h3>
|
||||
|
||||
Tento modul umožnuje písanie skriptov v JavaScripte ktoré spracujú súbory obrázkov. Okno Hromadného spracovanie pozostáva z troch častí. Navrchu je zoznam vstupných súborov a adresárov.
|
||||
Do zoznamu môžete pridať adresáre alebo jednotlivé súbory. Adresáre sú rekurzívne prehľadané na všetky súbory. Zoznam súborov je potom predaný do skriptu ako pole nazvané <b>files</b>.
|
||||
V skripte potom cez toto pole iteruje nasledovne.
|
||||
<pre>for(file in files)
|
||||
{
|
||||
if(file.suffix() == "fits")
|
||||
{
|
||||
core.log(file.fileName());
|
||||
file.convert(file.relativeFilePath(), "XISF");
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h4>core</h4>
|
||||
V skripte je dostupný globálny objekt nazvaný <b>core</b> ktorý má nasledovné metódy.
|
||||
<ul>
|
||||
<li><b>log(message)</b> vypíše message do okna záznamu.</li>
|
||||
<li><b>mark(file)</b> označí súbor rovnako ako cez GUI. Parameter je objekt typu <i>File</i>.</li>
|
||||
<li><b>unmark(file)</b> odznačí súbor rovnako ako cez GUI. Parameter je objekt typu <i>File</i>.</li>
|
||||
<li><b>isMarked(file)</b> overenie či je súbor označený. Parameter je objekt typu <i>File</i>.</li>
|
||||
<li><b>setMaxThread(maxthread)</b> nastavý maximálny počet paralelných vlákien pri vykonávaní asynchrónnych úloh.</li>
|
||||
<li><b>sync()</b> počká kým sa dokončia všetky asynchrónne úlohy.</li>
|
||||
<li><b>getString(label = "", text = "")</b> ukáže dialóg pre získanie textovej hodnoty od používateľa. Prvý parameter je textový popis. Druhý parameter je východzia hodnota. Obydva parametre sú voliteľné takže aj volanie <i>getString()</i> je valdiné.
|
||||
Metoda vracia textový retazec alebo Undefined ak bolo stlačené tlačidlo zrušiť.</li>
|
||||
<li><b>getInt(label = "", value = 0)</b> ukáže diálog pre získanie celočíselnej hodnoty. Prvý parameter je textový popis. Druhý parameter je východzia hodnota. Obydva parametre sú voliteľné. Vracia zadané číslo alebo ak je stlačené tlačidlo zrušiť vráti Undefined.</li>
|
||||
<li><b>getFloat(label = "", value = 0, decimals = 3)</b> ukáže diálog pre získanie reálneho čísla. Prvý parameter je textový popis. Druhý parameter je východzia hodnota. Tretí parameter je počet desatinných miest.
|
||||
Obydva parametre sú voliteľné. Vracia zadané číslo alebo ak je stlačené tlačidlo zrušiť vráti Undefined.</li>
|
||||
<li><b>getItem(items)</b> ukáže dialog pre výber jednej hodnoty z poľa hodnôt. Vracia vybranú hodnotu ako String alebo ak je stlačené tlačidlo zrušiť vráti Undefined.</li>
|
||||
</ul>
|
||||
|
||||
<h4>File</h4>
|
||||
V poli <b>files</b> sú inštancie objektu typu <b>File</b> ktorý ma nasledovné metódy.
|
||||
<ul>
|
||||
<li><b>fileName()</b> returns the name of the file, excluding the path.</li>
|
||||
<li><b>absoluteFilePath()</b> returns an absolute path including the file name.</li>
|
||||
<li><b>absolutePath()</b> returns an absolute path without the file name</li>
|
||||
<li><b>relativeFilePath()</b> return relative path including file name relative to directory that was in list of directories to be scanned. For example you add C:/images as input directory. In this directory there
|
||||
is file <i>C:/images/lights/red/M42_001.fits</i> then this method will return <i>lights/red/M42_001.fits</i></li>
|
||||
<li><b>relativePath()</b> return same path as previous method just without file name. <i>lights/red</i></li>
|
||||
<li><b>baseName()</b> return file name up to the first dot. For example for <i>some.file.name.fits</i> it will return <i>some</i></li>
|
||||
<li><b>completeBaseName()</b> return file name up to the last dot. For example for <i>some.file.name.fits</i> it will return <i>some.file.name</i></li>
|
||||
<li><b>suffix()</b> return string after last dot in file name. For example <i>fits</i></li>
|
||||
<li><b>size()</b> return size of file in bytes.</li>
|
||||
<li><b>fitsKeywords()</b> return array of strings with every keyword that is in header. <i>SIMPLE,BITPIX,NAXIS,NAXIS1,NAXIS2,EXTEND,COMMENT</i></li>
|
||||
<li><b>fitsValue(key)</b> return value for keyword. In case that there is multiple occurrences it return last one.</li>
|
||||
<li><b>fitsValues(key)</b> return array of values for keyword.</li>
|
||||
<li><b>fitsRecords()</b> return array of objects with properties <b>key, value</b> and <b>comment</b> </li>
|
||||
<li><b>modifyFITSRecords(FITSRecordModify)</b> modify FITS header by adding, removing or updating FITS record. Return true on success. Refer to <i>FITSRecordModify</i></li>
|
||||
<li><b>isMarked()</b> return true if file is marked.</li>
|
||||
<li><b>copy(newpath)</b> copy file to new location. It return instance of new <i>File<i> object that represent this copied file. This path can be relative or absolute. In case that <i>newpath</i> parameter is relative
|
||||
path then it "Output directory" from GUI windows is used as base directory. Parameter <i>newpath</i> can absolute path. File is then copied to this path. In case that copy fail it return null.</li>
|
||||
<li><b>move(newpath)</b> move file to new location. It return false if move failed. This can happend if destination is not writable but also if destination file already exist. This functions does not overwrite existing file.
|
||||
This path can be relative or absolute. In case that <i>newpath</i> parameter is relative path then it "Output directory" from GUI windows is used as base directory. Parameter <i>newpath</i> can be absolute path.
|
||||
File is then moved to this path.</li>
|
||||
<li><b>convert(outpath, format, params)</b> convert image file from any format that program is able to open into FITS, XISF, JPEG, PNG, BMP.
|
||||
Parameters are: <i>outputpath</i> path where converted image will be saved. It automatically replace suffix according to format. <i>format</i> one of "FITS" "XISF", "JPG", "PNG" or "BMP". <i>params</i> object with attributes "compressionType" and "compressionLevel".
|
||||
Valid values for compressionType are be "gzip" or "rice" when converting to FITS. When converting to XISF compressionType can be "zlib", "lz4", "lz4hc", "zstd", "zlib+sh", "lz4+sh", "lz4hc+sh", "zstd+sh".
|
||||
It is recommended to use "+sh" variants of compression.
|
||||
XISF format also accept "compressionLevel" in range 0-100 where zero is fastest compression and 100 slowest. If you omit this attribute or set it to -1 then default compression level will be used.
|
||||
It return new instance of <i>File</i> that point to converted file.
|
||||
<pre>file.convert("converted_file.xisf", "xisf", {"compressionType": "zstd+sh", "compressionLevel": 70});
|
||||
file.convert("converted_file.fits", "fits", {"compressionType": "rice"});
|
||||
file.convert("converted_file.jpg", "png");</pre>
|
||||
</li>
|
||||
<li><b>convertAsync(outpath, format, params)</b> same as previous method but it does conversion in separated thread asynchronously and in parallel. Before calling any method on object returned by this method you must call
|
||||
<code>core.sync();</code> to ensure that conversion is done and destination file exists.
|
||||
<pre>let compression = {"compressionType": "zstd+sh"};
|
||||
let convertedFiles = [];
|
||||
for(file of files)
|
||||
{
|
||||
if(file.suffix() == "fits")
|
||||
convertedFiles.push(file.convertAsync("xisf/" + file.fileName(), "XISF", compression));
|
||||
}
|
||||
core.sync(); // ensure that files exist
|
||||
for(file of convertedFiles)// now we can iterate over the files
|
||||
{
|
||||
core.log(file.fileName() + " " + file.size()); // let print compressed file sizes
|
||||
}</pre></li>
|
||||
<li><b>stats()</b> calculate basic images statistics and return them as object with attributes "mean", "stddev", "median", "min", "max" and "mad".
|
||||
<pre>let s = file.stats();
|
||||
core.log("Median value is " + s.median);</pre></li>
|
||||
</ul>
|
||||
|
||||
<h4>FITSRecordModify</h4>
|
||||
This class is used to define modify operation FITS header in FITS and XISF files. It can remove update and add records. Order of operation is also remove then update and last add.
|
||||
The keyword names may be up to 8 characters long and can only contain uppercase letters, the digits 0-9, the hyphen, and the underscore character.
|
||||
<pre>let modify = new FITSRecordModify();
|
||||
modify.updateKeyword("OBJECT", "M42");
|
||||
modify.updateKeyword("MYTILE", "PART1", "adding custom keyword so WBPP can group it");
|
||||
modify.removeKeyword("OBJECT");
|
||||
// doesn't matter that it is specified as last. This will first remove
|
||||
// existing OBJECT record and then add again OBJECT=M42
|
||||
for(file in files)
|
||||
{
|
||||
file.modifyFITSRecords(modify);
|
||||
}</pre>
|
||||
|
||||
<ul>
|
||||
<li><b>new FITSRecordModify()</b> create new instance of object.</li>
|
||||
<li><b>removeKeyword(key);</b> specify removing of record with <i>key</i> as keyword.</li>
|
||||
<li><b>updateKeyword(key, value, comment = "")</b> specify updating existing keyword with value and comment. Comment is optional parameter. If record with keyword doesn't exist then it will add new one.
|
||||
Unless you want to have multiple records with same keyword (for example HISTORY) always use this method and not addKeyword.</li>
|
||||
<li><b>addKeyword(key, value, comment = "")</b> specify adding new keyword</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p><small>PS: Kanji v ikone programu znamená "astronomia" v Japončine</small></p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+82
-29
@@ -1,5 +1,6 @@
|
||||
#include "batchprocessing.h"
|
||||
#include "ui_batchprocessing.h"
|
||||
#include <functional>
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QStandardPaths>
|
||||
@@ -7,49 +8,60 @@
|
||||
#include <QSettings>
|
||||
#include <QCloseEvent>
|
||||
#include <QMessageBox>
|
||||
#include <QDesktopServices>
|
||||
#include <QInputDialog>
|
||||
#include "scriptengine.h"
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#include <QCloseEvent>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusMessage>
|
||||
#include <QMessageBox>
|
||||
#endif
|
||||
|
||||
void scanDirectory(const QString &path, QStringList &files)
|
||||
QList<QPair<QString, QString>> scanDirectories(const QStringList &paths)
|
||||
{
|
||||
QFileInfo info(path);
|
||||
if(info.isDir())
|
||||
{
|
||||
QDir dir(path);
|
||||
QStringList entries = dir.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
|
||||
for(QString &entry : entries)
|
||||
scanDirectory(dir.absoluteFilePath(entry), files);
|
||||
}
|
||||
else if(info.isFile())
|
||||
{
|
||||
files.append(path);
|
||||
}
|
||||
}
|
||||
QList<QPair<QString, QString>> files;
|
||||
QStringList scannedDirs;
|
||||
|
||||
QStringList scanDirectories(const QStringList &paths)
|
||||
{
|
||||
QStringList files;
|
||||
std::function<void(const QString &root, const QString &path)> scanDirectory = [&](const QString &root, const QString &path)
|
||||
{
|
||||
QFileInfo info(path);
|
||||
if(info.isDir() && !scannedDirs.contains(info.canonicalFilePath()))
|
||||
{
|
||||
scannedDirs.append(info.canonicalFilePath());
|
||||
QDir dir(path);
|
||||
QStringList entries = dir.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
|
||||
for(QString &entry : entries)
|
||||
scanDirectory(root, dir.absoluteFilePath(entry));
|
||||
}
|
||||
else if(info.isFile())
|
||||
{
|
||||
if(path == root)
|
||||
files.append({path, info.absolutePath()});
|
||||
else
|
||||
files.append({path, root});
|
||||
}
|
||||
};
|
||||
|
||||
for(const QString &path : paths)
|
||||
scanDirectory(path, files);
|
||||
scanDirectory(path, path);
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
void BatchProcessing::scanScriptDir()
|
||||
{
|
||||
QString current;
|
||||
if(_ui->scriptsList->currentItem())
|
||||
current = _ui->scriptsList->currentItem()->text();
|
||||
|
||||
_ui->scriptsList->clear();
|
||||
QDir dir(_scriptBasePath);
|
||||
for(const QString &script : dir.entryList(QDir::Files | QDir::Readable))
|
||||
{
|
||||
_ui->scriptsList->addItem(script);
|
||||
}
|
||||
QStringList scripts = dir.entryList(QDir::Files | QDir::Readable);
|
||||
_ui->scriptsList->addItems(scripts);
|
||||
|
||||
int idx = scripts.indexOf(current);
|
||||
if(idx>=0)_ui->scriptsList->setCurrentRow(idx);
|
||||
}
|
||||
|
||||
BatchProcessing::BatchProcessing(QWidget *parent) : QDialog(parent)
|
||||
@@ -87,6 +99,8 @@ BatchProcessing::BatchProcessing(QWidget *parent) : QDialog(parent)
|
||||
connect(_ui->browseButton, &QPushButton::released, this, &BatchProcessing::browse);
|
||||
connect(_ui->openScriptsButton, &QPushButton::released, this, &BatchProcessing::openScriptDir);
|
||||
|
||||
_textColor = _ui->log->palette().text().color();
|
||||
|
||||
QSettings settings;
|
||||
_ui->outputPath->setText(settings.value("batchprocessing/outputpath", QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).first()).toString());
|
||||
}
|
||||
@@ -122,15 +136,24 @@ void BatchProcessing::closeEvent(QCloseEvent *event)
|
||||
|
||||
void BatchProcessing::addFiles()
|
||||
{
|
||||
QStringList files = QFileDialog::getOpenFileNames(this, tr("Select files"), "/home/nou/Obrázky/astro");
|
||||
_ui->pathsList->addItems(files);
|
||||
QSettings settings;
|
||||
QStringList files = QFileDialog::getOpenFileNames(this, tr("Select files"), settings.value("batchprocessing/inputpath", QDir::homePath()).toString());
|
||||
if(!files.isEmpty())
|
||||
{
|
||||
_ui->pathsList->addItems(files);
|
||||
settings.setValue("batchprocessing/inputpath", QFileInfo(files.first()).absolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
void BatchProcessing::addDir()
|
||||
{
|
||||
QString dir = QFileDialog::getExistingDirectory(this, tr("Select directory"), "/home/nou/Obrázky/astro");
|
||||
QSettings settings;
|
||||
QString dir = QFileDialog::getExistingDirectory(this, tr("Select directory"), settings.value("batchprocessing/inputpath", QDir::homePath()).toString());
|
||||
if(!dir.isEmpty())
|
||||
{
|
||||
_ui->pathsList->addItem(dir);
|
||||
settings.setValue("batchprocessing/inputpath", dir);
|
||||
}
|
||||
}
|
||||
|
||||
void BatchProcessing::removePath()
|
||||
@@ -163,6 +186,9 @@ void BatchProcessing::openScriptDir()
|
||||
#ifdef Q_OS_WINDOWS
|
||||
QProcess::startDetached("explorer.exe", {QDir::toNativeSeparators(_scriptBasePath)});
|
||||
#endif
|
||||
#ifdef Q_OS_MACOS
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(_scriptBasePath));
|
||||
#endif
|
||||
}
|
||||
|
||||
void BatchProcessing::runScript()
|
||||
@@ -205,14 +231,41 @@ void BatchProcessing::scriptFinished()
|
||||
_ui->startButton->setEnabled(true);
|
||||
_ui->stopButton->setEnabled(false);
|
||||
qDebug() << "script finished";
|
||||
delete _engineThread;
|
||||
_engineThread->deleteLater();
|
||||
_engineThread = nullptr;
|
||||
}
|
||||
|
||||
void BatchProcessing::newMessage(const QString &message, bool error)
|
||||
{
|
||||
QColor color = _ui->log->textColor();
|
||||
if(error)_ui->log->setTextColor(Qt::red);
|
||||
else _ui->log->setTextColor(_textColor);
|
||||
_ui->log->append(message);
|
||||
if(error)_ui->log->setTextColor(color);
|
||||
}
|
||||
|
||||
QJSValue BatchProcessing::getString(const QString &label, const QString &text)
|
||||
{
|
||||
bool ok = false;
|
||||
QString ret = QInputDialog::getText(this, tr("Enter text"), label, QLineEdit::Normal, text, &ok);
|
||||
return ok ? ret : QJSValue();
|
||||
}
|
||||
|
||||
QJSValue BatchProcessing::getInt(const QString &label, int value)
|
||||
{
|
||||
bool ok = false;
|
||||
int ret = QInputDialog::getInt(this, tr("Enter integer number"), label, value, INT_MIN, INT_MAX, 1, &ok);
|
||||
return ok ? ret : QJSValue();
|
||||
}
|
||||
|
||||
QJSValue BatchProcessing::getFloat(const QString &label, double value, int decimals)
|
||||
{
|
||||
bool ok = false;
|
||||
double ret = QInputDialog::getDouble(this, tr("Enter float number"), label, value, -INFINITY, INFINITY, decimals, &ok);
|
||||
return ok ? ret : QJSValue();
|
||||
}
|
||||
|
||||
QJSValue BatchProcessing::getItem(const QStringList &items, const QString &label, int current)
|
||||
{
|
||||
bool ok = false;
|
||||
QString ret = QInputDialog::getItem(this, tr("Select item"), label, items, current, false, &ok);
|
||||
return ok ? ret : QJSValue();
|
||||
}
|
||||
|
||||
+7
-1
@@ -9,10 +9,12 @@ namespace Ui { class BatchProcessing; }
|
||||
|
||||
class BatchProcessing : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
Ui::BatchProcessing *_ui;
|
||||
QString _scriptBasePath;
|
||||
QFileSystemWatcher _fileWatcher;
|
||||
Script::ScriptEngineThread *_engineThread = nullptr;
|
||||
QColor _textColor;
|
||||
private slots:
|
||||
void scanScriptDir();
|
||||
public:
|
||||
@@ -21,7 +23,6 @@ public:
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
public slots:
|
||||
void scriptDirChanged();
|
||||
void addFiles();
|
||||
void addDir();
|
||||
void removePath();
|
||||
@@ -32,6 +33,11 @@ public slots:
|
||||
void stopScript();
|
||||
void scriptFinished();
|
||||
void newMessage(const QString &message, bool error);
|
||||
|
||||
QJSValue getString(const QString &label, const QString &text);
|
||||
QJSValue getInt(const QString &label, int value);
|
||||
QJSValue getFloat(const QString &label, double value, int decimals);
|
||||
QJSValue getItem(const QStringList &items, const QString &label, int current);
|
||||
};
|
||||
|
||||
#endif // BATCHPROCESSING_H
|
||||
|
||||
+16
-7
@@ -156,23 +156,29 @@ int Database::checkVersion()
|
||||
|
||||
static QStringList nameFilters = {"*.fit", "*.fits", "*.xisf"};
|
||||
|
||||
static int countFiles(const QDir &dir, int count = 0)
|
||||
static int countFiles(const QDir &dir, QStringList &scannedDirs)
|
||||
{
|
||||
count += dir.entryList(nameFilters, QDir::Files).size();
|
||||
if(scannedDirs.contains(dir.canonicalPath()))return 0;
|
||||
scannedDirs.append(dir.canonicalPath());
|
||||
|
||||
int count = dir.entryList(nameFilters, QDir::Files).size();
|
||||
QStringList dirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
for(const QString &d : dirs)
|
||||
count += countFiles(dir.filePath(d));
|
||||
count += countFiles(dir.filePath(d), scannedDirs);
|
||||
return count;
|
||||
}
|
||||
|
||||
void Database::indexDir(const QDir &dir, QProgressDialog *progress)
|
||||
{
|
||||
m_progress = 0;
|
||||
int count = countFiles(dir);
|
||||
QStringList scannedDirs;
|
||||
int count = countFiles(dir, scannedDirs);
|
||||
progress->setMaximum(count);
|
||||
QSqlDatabase database = QSqlDatabase::database();
|
||||
database.transaction();
|
||||
if(indexDir2(dir, progress))
|
||||
|
||||
scannedDirs.clear();
|
||||
if(indexDir2(dir, progress, scannedDirs))
|
||||
{
|
||||
database.commit();
|
||||
emit databaseChanged();
|
||||
@@ -225,14 +231,17 @@ QStringList Database::getFitsKeywords()
|
||||
return keywords;
|
||||
}
|
||||
|
||||
bool Database::indexDir2(const QDir &dir, QProgressDialog *progress)
|
||||
bool Database::indexDir2(const QDir &dir, QProgressDialog *progress, QStringList &scannedDirs)
|
||||
{
|
||||
if(scannedDirs.contains(dir.canonicalPath()))return true;
|
||||
scannedDirs.append(dir.canonicalPath());
|
||||
|
||||
QFileInfoList files = dir.entryInfoList(nameFilters, QDir::Files);
|
||||
QStringList dirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
|
||||
for(const QString &d : dirs)
|
||||
{
|
||||
if(!indexDir2(dir.filePath(d), progress))
|
||||
if(!indexDir2(dir.filePath(d), progress, scannedDirs))
|
||||
return false;
|
||||
}
|
||||
for(const QFileInfo &file : files)
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ public:
|
||||
void reindex(QProgressDialog *progress);
|
||||
QStringList getFitsKeywords();
|
||||
protected:
|
||||
bool indexDir2(const QDir &dir, QProgressDialog *progress);
|
||||
bool indexDir2(const QDir &dir, QProgressDialog *progress, QStringList &scannedDirs);
|
||||
bool indexFile(const QFileInfo &file);
|
||||
bool checkError(QSqlQuery &query);
|
||||
int checkVersion();
|
||||
|
||||
+3
-2
@@ -48,6 +48,7 @@ FITSRecord::FITSRecord(const LibXISF::Property &property)
|
||||
key = property.id.c_str();
|
||||
value = QString::fromStdString(property.value.toString());
|
||||
comment = property.comment.c_str();
|
||||
xisf = true;
|
||||
}
|
||||
|
||||
QByteArray FITSRecord::valueToByteArray() const
|
||||
@@ -81,7 +82,7 @@ void ImageInfo::setInfo(const ImageInfoData &info)
|
||||
QTreeWidgetItem *fitsHeader = new QTreeWidgetItem({tr("FITS Header")});
|
||||
for(const FITSRecord &record : info.fitsHeader)
|
||||
{
|
||||
new QTreeWidgetItem(fitsHeader, {record.key, record.value.toString(), record.comment});
|
||||
new QTreeWidgetItem(fitsHeader, {record.key, record.value.toString().left(1024), record.comment});
|
||||
}
|
||||
addTopLevelItem(fitsHeader);
|
||||
}
|
||||
@@ -279,7 +280,7 @@ QString SkyPoint::toString() const
|
||||
t = t.addSecs(ra * 240);
|
||||
|
||||
double deg, min, sec;
|
||||
min = std::modf(dec, °) * 60;
|
||||
min = std::abs(std::modf(dec, °) * 60);
|
||||
sec = std::modf(min, &min) * 60;
|
||||
return QString("RA: %1 DEC: %2° %3' %4\"").arg(t.toString("HH'h' mm'm' ss's'")).arg(deg, 2, 'f', 0, '0').arg(min, 2, 'f', 0, '0').arg(sec, 2, 'f', 0, '0');
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ struct FITSRecord
|
||||
QByteArray key;
|
||||
QVariant value;
|
||||
QByteArray comment;
|
||||
bool xisf = false;
|
||||
bool editable() const;
|
||||
FITSRecord(){}
|
||||
FITSRecord(const QByteArray &key, const QVariant &value, const QByteArray &comment);
|
||||
|
||||
+28
-9
@@ -1,4 +1,5 @@
|
||||
#include "imageringlist.h"
|
||||
#include <functional>
|
||||
#include <QThreadPool>
|
||||
#include <QDir>
|
||||
#include <QSettings>
|
||||
@@ -124,21 +125,39 @@ ImageRingList::~ImageRingList()
|
||||
m_thumbPool->waitForDone();
|
||||
}
|
||||
|
||||
bool ImageRingList::setDir(const QString path, const QString ¤tFile)
|
||||
bool ImageRingList::setDir(const QString path, const QString ¤tFile, bool recursive)
|
||||
{
|
||||
QDir dir(path);
|
||||
|
||||
if(dir.exists())
|
||||
{
|
||||
QDir::SortFlags sortFlags = m_liveMode ? QDir::Time : m_sort | QDir::IgnoreCase;
|
||||
if(m_reversed)sortFlags |= QDir::Reversed;
|
||||
QStringList list = dir.entryList(m_nameFilter, QDir::Files | QDir::Readable, sortFlags);
|
||||
QStringList scannedDirs;
|
||||
QStringList absolutePaths;
|
||||
foreach(const QString &file, list)
|
||||
std::function<void(const QString&)> scanDir = [&](const QString &path)
|
||||
{
|
||||
absolutePaths.append(dir.absoluteFilePath(file));
|
||||
}
|
||||
setFiles(absolutePaths, m_liveMode ? list.first() : currentFile);
|
||||
QDir dir(path);
|
||||
if(scannedDirs.contains(dir.canonicalPath()))return;
|
||||
scannedDirs.append(dir.canonicalPath());
|
||||
QDir::SortFlags sortFlags = m_liveMode ? QDir::Time : m_sort | QDir::IgnoreCase;
|
||||
if(m_reversed)sortFlags |= QDir::Reversed;
|
||||
|
||||
if(recursive)
|
||||
{
|
||||
QStringList dirs = dir.entryList(QDir::Readable | QDir::Dirs | QDir::NoDotAndDotDot, sortFlags);
|
||||
for(const QString &subdir : dirs)
|
||||
scanDir(dir.absoluteFilePath(subdir));
|
||||
}
|
||||
|
||||
QStringList list = dir.entryList(m_nameFilter, QDir::Files | QDir::Readable, sortFlags);
|
||||
for(const QString &file : list)
|
||||
{
|
||||
absolutePaths.append(dir.absoluteFilePath(file));
|
||||
}
|
||||
};
|
||||
|
||||
scanDir(path);
|
||||
qDebug() << absolutePaths.size();
|
||||
setFiles(absolutePaths, m_liveMode ? absolutePaths.first() : currentFile);
|
||||
|
||||
m_fileSystemWatcher.removePaths(m_fileSystemWatcher.directories());
|
||||
m_fileSystemWatcher.addPath(path);
|
||||
@@ -151,7 +170,7 @@ void ImageRingList::setFile(const QString &file)
|
||||
{
|
||||
QFileInfo info(file);
|
||||
if(info.isDir())
|
||||
setDir(file);
|
||||
setDir(file, QString(), true);
|
||||
else
|
||||
setDir(info.absolutePath(), file);
|
||||
}
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ class ImageRingList : public QAbstractItemModel
|
||||
public:
|
||||
explicit ImageRingList(Database *database, const QStringList &nameFilter, QObject *parent = 0);
|
||||
~ImageRingList() override;
|
||||
bool setDir(const QString path, const QString ¤tFile = QString());
|
||||
bool setDir(const QString path, const QString ¤tFile = QString(), bool recursive = false);
|
||||
void setFile(const QString &file);
|
||||
ImagePtr currentImage();
|
||||
void setLiveMode(bool live);
|
||||
|
||||
+31
-6
@@ -90,14 +90,27 @@ ImageWidget::~ImageWidget()
|
||||
|
||||
void ImageWidget::setImage(std::shared_ptr<RawImage> image, int index)
|
||||
{
|
||||
if(image == nullptr)return;
|
||||
m_currentImg = index;
|
||||
|
||||
if(!image || !image->valid())
|
||||
{
|
||||
m_imgWidth = 0;
|
||||
m_imgHeight = 0;
|
||||
m_error = tr("Failed to load image");
|
||||
m_rawImage.reset();
|
||||
update();
|
||||
return;
|
||||
}
|
||||
|
||||
m_error.clear();
|
||||
makeCurrent();
|
||||
m_rawImage = image;
|
||||
m_rawImage->downscaleTo(m_maxTextureSize);
|
||||
if((int)image->width() > m_maxTextureSize || (int)image->height() > m_maxTextureSize)
|
||||
m_rawImage->resize(std::min(m_maxTextureSize, (int)image->width()), std::min(m_maxTextureSize, (int)image->height()));
|
||||
|
||||
m_imgWidth = image->width();
|
||||
m_imgHeight = image->height();
|
||||
m_currentImg = index;
|
||||
|
||||
|
||||
if(!m_image)return;
|
||||
|
||||
@@ -198,7 +211,7 @@ void ImageWidget::allocateThumbnails(const QStringList &paths)
|
||||
m_thumbnailTexture->create();
|
||||
m_thumbnailTexture->setFormat(QOpenGLTexture::RGB16_UNorm);
|
||||
m_thumbnailTexture->setSize(THUMB_SIZE, THUMB_SIZE);
|
||||
m_thumbnailTexture->setLayers(paths.size());
|
||||
m_thumbnailTexture->setLayers(std::min((int)paths.size(), m_maxArrayLayers));
|
||||
m_thumbnailTexture->allocateStorage();
|
||||
}
|
||||
|
||||
@@ -288,9 +301,12 @@ QImage ImageWidget::renderToImage()
|
||||
|
||||
void ImageWidget::thumbnailLoaded(const Image *image)
|
||||
{
|
||||
if(image->number() >= m_maxArrayLayers)
|
||||
return;
|
||||
|
||||
makeCurrent();
|
||||
const RawImage *raw = image->thumbnail();
|
||||
if(!raw)return;
|
||||
if(!raw || !raw->valid())return;
|
||||
m_thumbnailTexture->setData(0, image->number(), QOpenGLTexture::RGBA, QOpenGLTexture::UInt16, raw->data(), m_transferOptions.get());
|
||||
float a = raw->thumbAspect();
|
||||
int sizes[3] = { std::max(1, a > 1.0f ? THUMB_SIZE : (int)(THUMB_SIZE * a)), std::max(1, a < 1.0f ? THUMB_SIZE : (int)(THUMB_SIZE / a)), image->number() };
|
||||
@@ -350,7 +366,9 @@ void ImageWidget::paintGL()
|
||||
QPainter painter(this);
|
||||
const int w = width()/THUMB_SIZE_BORDER;
|
||||
const int off = (THUMB_SIZE_BORDER - THUMB_SIZE) / 2;
|
||||
for(int i=0; i < m_thumbnailCount; i++)
|
||||
int start = std::max((int)(m_dy / THUMB_SIZE_BORDER_Y * w - w), 0);
|
||||
int end = std::min((int)(m_dy + m_height) / THUMB_SIZE_BORDER_Y * w + w, m_thumbnailCount);
|
||||
for(int i=start; i < end; i++)
|
||||
{
|
||||
float x = (i % w) * THUMB_SIZE_BORDER;
|
||||
float y = i / w * THUMB_SIZE_BORDER_Y + THUMB_SIZE - m_dy + off;
|
||||
@@ -375,6 +393,13 @@ void ImageWidget::paintGL()
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!m_error.isEmpty())
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.setPen(Qt::red);
|
||||
painter.setFont(QFont("Sans", 24, QFont::Bold));
|
||||
painter.drawText(0, 0, width(), height(), Qt::AlignCenter | Qt::AlignHCenter, m_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
debayer();
|
||||
|
||||
@@ -69,6 +69,7 @@ class ImageWidget : public QOpenGLWidget
|
||||
QVector<ImageThumb> m_thumnails;
|
||||
Database *m_database = nullptr;
|
||||
QPointF m_lastPos;
|
||||
QString m_error;
|
||||
public:
|
||||
explicit ImageWidget(Database *database, QWidget *parent = nullptr);
|
||||
~ImageWidget() override;
|
||||
|
||||
+1
-1
Submodule libXISF updated: aa356443d3...922d4b73c9
+172
-106
@@ -7,6 +7,7 @@
|
||||
#include <QElapsedTimer>
|
||||
#include <QDebug>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <libexif/exif-data.h>
|
||||
#include <fitsio2.h>
|
||||
#include <libxisf.h>
|
||||
@@ -190,19 +191,22 @@ bool loadFITS(const QString path, ImageInfoData &info, std::shared_ptr<RawImage>
|
||||
{
|
||||
fitsfile *file;
|
||||
int status = 0;
|
||||
int type;
|
||||
fits_open_image(&file, path.toLocal8Bit().data(), READONLY, &status);
|
||||
fits_get_hdu_type(file, &type, &status);
|
||||
int type = -1;
|
||||
fits_open_diskfile(&file, path.toLocal8Bit().data(), READONLY, &status);
|
||||
int num = 0;
|
||||
fits_get_num_hdus(file, &num, &status);
|
||||
|
||||
if(type == IMAGE_HDU)
|
||||
int imgtype;
|
||||
int naxis;
|
||||
long naxes[3] = {0};
|
||||
for(int i=1; i <= num; i++)
|
||||
{
|
||||
int imgtype;
|
||||
int naxis;
|
||||
long naxes[3] = {0};
|
||||
fits_movabs_hdu(file, i, IMAGE_HDU, &status);
|
||||
fits_get_hdu_type(file, &type, &status);
|
||||
fits_get_img_param(file, 3, &imgtype, &naxis, naxes, &status);
|
||||
fits_get_img_equivtype(file, &imgtype, &status);
|
||||
|
||||
if(naxis >= 2 && naxis <= 3 && status == 0)
|
||||
if(type == IMAGE_HDU && naxis >= 2 && naxis <= 3 && status == 0)
|
||||
{
|
||||
RawImage::DataType type;
|
||||
int fitstype;
|
||||
@@ -268,12 +272,23 @@ bool loadFITS(const QString path, ImageInfoData &info, std::shared_ptr<RawImage>
|
||||
|
||||
if(image)
|
||||
image->convertToGLFormat();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
noload:
|
||||
if(file)
|
||||
loadFITSHeader(file, info);
|
||||
|
||||
if(image)
|
||||
{
|
||||
for(auto fits : info.fitsHeader)
|
||||
{
|
||||
if(fits.key == "ROWORDER" && fits.value == "BOTTOM-UP")
|
||||
image->flip();
|
||||
}
|
||||
}
|
||||
|
||||
fits_close_file(file, &status);
|
||||
if(status)
|
||||
{
|
||||
@@ -363,44 +378,10 @@ void LoadRunable::run()
|
||||
info.info.append({QObject::tr("Filename"), finfo.fileName()});
|
||||
|
||||
std::shared_ptr<RawImage> rawImage;
|
||||
timer.start();
|
||||
if(m_file.endsWith(".CR2", Qt::CaseInsensitive) || m_file.endsWith(".CR3", Qt::CaseInsensitive) || m_file.endsWith(".NEF", Qt::CaseInsensitive) || m_file.endsWith(".DNG", Qt::CaseInsensitive))
|
||||
{
|
||||
loadRAW(m_file, info, rawImage);
|
||||
qDebug() << "LoadRAW" << timer.elapsed();
|
||||
}
|
||||
else if(m_file.endsWith(".FIT", Qt::CaseInsensitive) || m_file.endsWith(".FITS", Qt::CaseInsensitive))
|
||||
{
|
||||
loadFITS(m_file, info, rawImage);
|
||||
qDebug() << "LoadFITS" << timer.elapsed();
|
||||
}
|
||||
else if(m_file.endsWith(".XISF", Qt::CaseInsensitive))
|
||||
{
|
||||
loadXISF(m_file, info, rawImage);
|
||||
qDebug() << "LoadXISF" << timer.elapsed();
|
||||
}
|
||||
else
|
||||
{
|
||||
QImage img(m_file);
|
||||
#ifdef COLOR_MANAGMENT
|
||||
if(img.colorSpace().isValid() && img.colorSpace() != QColorSpace::SRgb)
|
||||
img.convertToColorSpace(QColorSpace::SRgb);
|
||||
#endif
|
||||
if(!loadImage(m_file, info, rawImage))
|
||||
info.info.append({QObject::tr("Error"), QObject::tr("Failed to load image")});
|
||||
|
||||
ExifData *exif = exif_data_new_from_file(m_file.toLocal8Bit().constData());
|
||||
info.info.append({QObject::tr("Width"), QString::number(img.width())});
|
||||
info.info.append({QObject::tr("Height"), QString::number(img.height())});
|
||||
if(exif)
|
||||
{
|
||||
loadExifEntry(info, exif->ifd[EXIF_IFD_EXIF], EXIF_TAG_ISO_SPEED_RATINGS);
|
||||
loadExifEntry(info, exif->ifd[EXIF_IFD_EXIF], EXIF_TAG_SHUTTER_SPEED_VALUE);
|
||||
exif_data_free(exif);
|
||||
}
|
||||
rawImage = std::make_shared<RawImage>(img);
|
||||
qDebug() << "LoadQImage" << timer.elapsed();
|
||||
}
|
||||
|
||||
if(rawImage /*&& m_analyzeLevel >= Statistics*/ && !m_thumbnail)
|
||||
if(rawImage && !m_thumbnail)
|
||||
{
|
||||
timer.start();
|
||||
rawImage->calcStats();
|
||||
@@ -428,68 +409,27 @@ void LoadRunable::run()
|
||||
.arg(100.0 * stats.m_saturated[1] / rawImage->size())
|
||||
.arg(100.0 * stats.m_saturated[2] / rawImage->size())});
|
||||
}
|
||||
|
||||
if(m_analyzeLevel >= Peaks)
|
||||
{
|
||||
std::vector<Peak> peaks;
|
||||
/*RawImage *medianImage = rawImage->medianFilter();
|
||||
qDebug() << "median" << timer.restart();
|
||||
int numPeaks = medianImage->findPeaks(median+stdDev*2, 20, peaks);
|
||||
delete medianImage;
|
||||
qDebug() << "peaks" << timer.restart();
|
||||
//if(m_analyzeLevel == Peaks)
|
||||
// drawPeaks(img, peaks);
|
||||
qDebug() << "draw peaks" << timer.restart();
|
||||
info.info.append({QObject::tr("Peaks"), QString::number(numPeaks)});
|
||||
//info.info.append({QObject::tr("Peaks draw"), QString::number(peaks.size())});
|
||||
|
||||
if(m_analyzeLevel>= Stars)
|
||||
{
|
||||
double fwhmX = 0;
|
||||
double fwhmY = 0;
|
||||
const int radius = 13;
|
||||
StarFit starFit(radius);
|
||||
std::vector<Star> stars;
|
||||
for(uint i=0; i<peaks.size(); i++)
|
||||
{
|
||||
Peak p = peaks[i];
|
||||
std::vector<double> r;
|
||||
int x = p.x();
|
||||
int y = p.y();
|
||||
rawImage->rect(x, y, radius, radius, r);
|
||||
Star star = starFit.fitStar(r, false);
|
||||
if(star.valid())
|
||||
{
|
||||
//printStarModel(radius, r, star);
|
||||
star.m_x += x;
|
||||
star.m_y += y;
|
||||
fwhmX += star.fwhmX();
|
||||
fwhmY += star.fwhmY();
|
||||
stars.push_back(star);
|
||||
}
|
||||
}
|
||||
//drawStars(img, stars);
|
||||
info.info.append({QObject::tr("FWHM X"), QString::number(fwhmX/stars.size())});
|
||||
info.info.append({QObject::tr("FWHM Y"), QString::number(fwhmY/stars.size())});
|
||||
}
|
||||
qDebug() << "Star fit" << timer.restart();*/
|
||||
}
|
||||
}
|
||||
|
||||
if(m_thumbnail)
|
||||
{
|
||||
if(rawImage)
|
||||
if(rawImage && rawImage->valid())
|
||||
{
|
||||
if(QUALITY_RESIZE)
|
||||
rawImage->resize(THUMB_SIZE, THUMB_SIZE);
|
||||
|
||||
rawImage->convertToThumbnail();
|
||||
QMetaObject::invokeMethod(m_receiver, "thumbnailLoadFinish", Qt::QueuedConnection, Q_ARG(std::shared_ptr<RawImage>, rawImage));
|
||||
}
|
||||
QMetaObject::invokeMethod(m_receiver, "thumbnailLoadFinish", Qt::QueuedConnection, Q_ARG(std::shared_ptr<RawImage>, rawImage));
|
||||
}
|
||||
else
|
||||
{
|
||||
QMetaObject::invokeMethod(m_receiver, "imageLoaded", Qt::QueuedConnection, Q_ARG(std::shared_ptr<RawImage>, rawImage), Q_ARG(ImageInfoData, info));
|
||||
}
|
||||
}
|
||||
catch(std::exception e)
|
||||
{
|
||||
qDebug() << e.what();
|
||||
qDebug() << m_file << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,10 +477,56 @@ bool readXISFHeader(const QString &path, ImageInfoData &info)
|
||||
return true;
|
||||
}
|
||||
|
||||
ConvertRunable::ConvertRunable(const QString &in, const QString &out, const QString &format) :
|
||||
bool loadImage(const QString &path, ImageInfoData &info, std::shared_ptr<RawImage> &rawImage)
|
||||
{
|
||||
bool ret = false;
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
if(path.endsWith(".CR2", Qt::CaseInsensitive) || path.endsWith(".CR3", Qt::CaseInsensitive) || path.endsWith(".NEF", Qt::CaseInsensitive) || path.endsWith(".DNG", Qt::CaseInsensitive))
|
||||
{
|
||||
ret = loadRAW(path, info, rawImage);
|
||||
qDebug() << "LoadRAW" << timer.elapsed();
|
||||
}
|
||||
else if(path.endsWith(".FIT", Qt::CaseInsensitive) || path.endsWith(".FITS", Qt::CaseInsensitive))
|
||||
{
|
||||
ret = loadFITS(path, info, rawImage);
|
||||
qDebug() << "LoadFITS" << timer.elapsed();
|
||||
}
|
||||
else if(path.endsWith(".XISF", Qt::CaseInsensitive))
|
||||
{
|
||||
ret = loadXISF(path, info, rawImage);
|
||||
qDebug() << "LoadXISF" << timer.elapsed();
|
||||
}
|
||||
else
|
||||
{
|
||||
QImage img(path);
|
||||
#ifdef COLOR_MANAGMENT
|
||||
if(img.colorSpace().isValid() && img.colorSpace() != QColorSpace::SRgb)
|
||||
img.convertToColorSpace(QColorSpace::SRgb);
|
||||
#endif
|
||||
|
||||
ExifData *exif = exif_data_new_from_file(path.toLocal8Bit().constData());
|
||||
info.info.append({QObject::tr("Width"), QString::number(img.width())});
|
||||
info.info.append({QObject::tr("Height"), QString::number(img.height())});
|
||||
if(exif)
|
||||
{
|
||||
loadExifEntry(info, exif->ifd[EXIF_IFD_EXIF], EXIF_TAG_ISO_SPEED_RATINGS);
|
||||
loadExifEntry(info, exif->ifd[EXIF_IFD_EXIF], EXIF_TAG_SHUTTER_SPEED_VALUE);
|
||||
exif_data_free(exif);
|
||||
}
|
||||
rawImage = std::make_shared<RawImage>(img);
|
||||
qDebug() << "LoadQImage" << timer.elapsed();
|
||||
ret = !img.isNull();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ConvertRunable::ConvertRunable(const QString &in, const QString &out, const QString &format, const ConvertParams ¶ms, QSemaphore *semaphore) :
|
||||
m_infile(in),
|
||||
m_outfile(out),
|
||||
m_format(format)
|
||||
m_format(format),
|
||||
m_params(params),
|
||||
m_semaphore(semaphore)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -587,10 +573,12 @@ void writeFITSImage(fitsfile *fw, std::shared_ptr<RawImage> rawimage, ImageInfoD
|
||||
fits_write_pix(fw, TFLOAT, firstpix, rawimage->size(), planes[i].data(), &status);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
for(const FITSRecord &record : imageinfo.fitsHeader)
|
||||
{
|
||||
if(skipKeys.contains(record.key))continue;
|
||||
if(skipKeys.contains(record.key) || record.xisf)continue;
|
||||
|
||||
bool isdouble;
|
||||
bool isint;
|
||||
@@ -616,16 +604,18 @@ void writeFITSImage(fitsfile *fw, std::shared_ptr<RawImage> rawimage, ImageInfoD
|
||||
|
||||
void ConvertRunable::run()
|
||||
{
|
||||
QSemaphoreReleaser release;
|
||||
if(m_semaphore)release = QSemaphoreReleaser(m_semaphore);
|
||||
|
||||
ImageInfoData imageinfo;
|
||||
std::shared_ptr<RawImage> rawimage;
|
||||
if(m_infile.endsWith(".FITS", Qt::CaseInsensitive) || m_infile.endsWith(".FIT", Qt::CaseInsensitive))
|
||||
loadFITS(m_infile, imageinfo, rawimage);
|
||||
if(m_infile.endsWith(".XISF", Qt::CaseInsensitive))
|
||||
loadXISF(m_infile, imageinfo, rawimage);
|
||||
loadImage(m_infile, imageinfo, rawimage);
|
||||
QFileInfo info(m_outfile);
|
||||
info.dir().mkpath(".");
|
||||
|
||||
if(rawimage)
|
||||
{
|
||||
if(m_format == "XISF")
|
||||
if(m_format == "xisf")
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -640,16 +630,43 @@ void ConvertRunable::run()
|
||||
default: return;
|
||||
}
|
||||
|
||||
LibXISF::Image image(rawimage->width(), rawimage->height(), channelCount, sampleFormat, channelCount == 1 ? LibXISF::Image::Gray : LibXISF::Image::RGB, LibXISF::Image::Normal);
|
||||
std::memcpy(image.imageData(), rawimage->data(), image.imageDataSize());
|
||||
LibXISF::Image image(rawimage->width(), rawimage->height(), channelCount, sampleFormat, channelCount == 1 ? LibXISF::Image::Gray : LibXISF::Image::RGB, LibXISF::Image::Planar);
|
||||
if(channelCount == 1)
|
||||
{
|
||||
std::memcpy(image.imageData(), rawimage->data(), image.imageDataSize());
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t off = 0;
|
||||
std::vector<RawImage> planes = rawimage->split();
|
||||
for(const auto &plane : planes)
|
||||
{
|
||||
std::memcpy(image.imageData<uint8_t>() + off, plane.data(), plane.size() * RawImage::typeSize(plane.type()));
|
||||
off += plane.size() * RawImage::typeSize(plane.type());
|
||||
}
|
||||
}
|
||||
for(auto &record : imageinfo.fitsHeader)
|
||||
{
|
||||
if(record.value.type() == QVariant::Bool)
|
||||
if(record.xisf)continue;
|
||||
|
||||
if(record.value.typeId() == QMetaType::Bool)
|
||||
image.addFITSKeyword({record.key.toStdString(), record.value.toBool() ? "T" : "F", record.comment.toStdString()});
|
||||
else
|
||||
image.addFITSKeyword({record.key.toStdString(), record.value.toString().toStdString(), record.comment.toStdString()});
|
||||
}
|
||||
|
||||
if(m_params.compressionType.startsWith("zstd") && LibXISF::DataBlock::CompressionCodecSupported(LibXISF::DataBlock::ZSTD))
|
||||
image.setCompression(LibXISF::DataBlock::ZSTD, m_params.compressionLevel);
|
||||
else if(m_params.compressionType.startsWith("lz4hc"))
|
||||
image.setCompression(LibXISF::DataBlock::LZ4HC, m_params.compressionLevel);
|
||||
else if(m_params.compressionType.startsWith("lz4"))
|
||||
image.setCompression(LibXISF::DataBlock::LZ4, m_params.compressionLevel);
|
||||
else if(m_params.compressionType.startsWith("zlib"))
|
||||
image.setCompression(LibXISF::DataBlock::Zlib, m_params.compressionLevel);
|
||||
|
||||
if(m_params.compressionType.endsWith("+sh"))
|
||||
image.setByteshuffling(true);
|
||||
|
||||
xisf.writeImage(image);
|
||||
xisf.save(m_outfile.toLocal8Bit().data());
|
||||
}
|
||||
@@ -657,16 +674,65 @@ void ConvertRunable::run()
|
||||
{
|
||||
qDebug() << "Failed to save XISF image" << err.what();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_format == "FITS")
|
||||
if(m_format == "fits")
|
||||
{
|
||||
int status = 0;
|
||||
fitsfile *fw;
|
||||
if(QFileInfo(m_outfile).exists())QFile::remove(m_outfile);
|
||||
fits_create_diskfile(&fw, m_outfile.toLocal8Bit().data(), &status);
|
||||
if(!m_params.compressionType.isEmpty())
|
||||
{
|
||||
if(m_params.compressionType == "gzip")
|
||||
fits_set_compression_type(fw, GZIP_1, &status);
|
||||
else if(m_params.compressionType == "rice")
|
||||
fits_set_compression_type(fw, RICE_1, &status);
|
||||
}
|
||||
writeFITSImage(fw, rawimage, imageinfo);
|
||||
fits_close_file(fw, &status);
|
||||
return;
|
||||
}
|
||||
|
||||
// if nothing else try QImage
|
||||
{
|
||||
QImage::Format format = QImage::Format_Invalid;
|
||||
int width = rawimage->widthBytes();
|
||||
switch(rawimage->type())
|
||||
{
|
||||
case RawImage::UINT8:
|
||||
if(rawimage->channels() == 1)format = QImage::Format_Grayscale8;
|
||||
else if(rawimage->channels() == 3)format = QImage::Format_RGBX8888;
|
||||
else if(rawimage->channels() == 4)format = QImage::Format_RGBA8888;
|
||||
break;
|
||||
case RawImage::UINT16:
|
||||
if(rawimage->channels() == 1)format = QImage::Format_Grayscale16;
|
||||
else if(rawimage->channels() == 3)format = QImage::Format_RGBX64;
|
||||
else if(rawimage->channels() == 4)format = QImage::Format_RGBA64;
|
||||
width *= 2;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if(format == QImage::Format_Invalid)return;
|
||||
|
||||
QImage qimage(rawimage->width(), rawimage->height(), format);
|
||||
for(uint32_t i=0; i < rawimage->height(); i++)
|
||||
std::memcpy(qimage.scanLine(i), rawimage->data(i), width);
|
||||
qimage.save(m_outfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConvertRunable::ConvertParams::ConvertParams(const QVariantMap &map)
|
||||
{
|
||||
bool ok = false;
|
||||
if(map.contains("compressionLevel"))
|
||||
compressionLevel = std::clamp(map["compressionLevel"].toInt(&ok), -1, 100);
|
||||
|
||||
if(!ok)compressionLevel = -1;
|
||||
|
||||
if(map.contains("compressionType"))
|
||||
compressionType = map["compressionType"].toString();
|
||||
}
|
||||
|
||||
+18
-3
@@ -3,10 +3,14 @@
|
||||
|
||||
#include <QRunnable>
|
||||
#include <QString>
|
||||
#include <QSemaphore>
|
||||
#include "imageinfo.h"
|
||||
|
||||
class RawImage;
|
||||
|
||||
bool readFITSHeader(const QString &path, ImageInfoData &info);
|
||||
bool readXISFHeader(const QString &path, ImageInfoData &info);
|
||||
bool loadImage(const QString &path, ImageInfoData &info, std::shared_ptr<RawImage> &rawImage);
|
||||
|
||||
class Image;
|
||||
|
||||
@@ -21,14 +25,25 @@ public:
|
||||
void run() override;
|
||||
};
|
||||
|
||||
|
||||
class ConvertRunable : public QRunnable
|
||||
{
|
||||
public:
|
||||
struct ConvertParams
|
||||
{
|
||||
int compressionLevel = -1;
|
||||
QString compressionType;
|
||||
ConvertParams(){}
|
||||
ConvertParams(const QVariantMap &map);
|
||||
};
|
||||
ConvertRunable(const QString &in, const QString &out, const QString &format, const ConvertParams ¶ms = ConvertParams(), QSemaphore *semaphore = nullptr);
|
||||
void run() override;
|
||||
private:
|
||||
QString m_infile;
|
||||
QString m_outfile;
|
||||
QString m_format;
|
||||
public:
|
||||
ConvertRunable(const QString &in, const QString &out, const QString &format);
|
||||
void run() override;
|
||||
ConvertParams m_params;
|
||||
QSemaphore *m_semaphore;
|
||||
};
|
||||
|
||||
#endif // LOADRUNABLE_H
|
||||
|
||||
+22
-6
@@ -62,6 +62,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
||||
_openFilter.append("*.fit *.fits *.xisf *.cr2 *.cr3 *.nef *.dng)");
|
||||
_openFilter.append(tr(";;All files (*)"));
|
||||
nameFilter.append({"fit", "fits", "xisf", "cr2", "cr3", "nef", "dng"});
|
||||
QImageReader::setAllocationLimit(0);
|
||||
|
||||
m_info = new ImageInfo(this);
|
||||
QDockWidget *infoDock = new QDockWidget(tr("Image info"), this);
|
||||
@@ -143,6 +144,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
||||
|
||||
QMenu *fileMenu = new QMenu(tr("File"), this);
|
||||
fileMenu->addAction(tr("Open"), this, SLOT(loadFile()), QKeySequence::Open);
|
||||
fileMenu->addAction(tr("Open directory recursively"), this, &MainWindow::loadDir);
|
||||
fileMenu->addAction(tr("Save as"), this, SLOT(saveAs()), QKeySequence::Save);
|
||||
fileMenu->addSeparator();
|
||||
fileMenu->addAction(tr("Copy marked files"), this, SLOT(copyMarked()), Qt::Key_F5);
|
||||
@@ -152,11 +154,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
||||
fileMenu->addAction(tr("Index directory"), this, SLOT(indexDir()));
|
||||
fileMenu->addAction(tr("Reindex files"), this, SLOT(reindex()));
|
||||
fileMenu->addAction(tr("Export database to CSV"), this, &MainWindow::exportCSV);
|
||||
/*fileMenu->addAction(tr("Batch processing"), [this](){
|
||||
fileMenu->addAction(tr("Batch processing"), [this](){
|
||||
BatchProcessing *batchProcessing = new BatchProcessing(this);
|
||||
batchProcessing->exec();
|
||||
delete batchProcessing;
|
||||
}, Qt::Key_B | Qt::CTRL);*/
|
||||
}, Qt::Key_B | Qt::CTRL);
|
||||
fileMenu->addSeparator();
|
||||
QAction *liveModeAction = fileMenu->addAction(tr("Live mode"), this, SLOT(liveMode(bool)));
|
||||
liveModeAction->setCheckable(true);
|
||||
@@ -180,10 +182,10 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
||||
QAction *grbgAction = bayerActionGroup->addAction(tr("GRBG"));//1 0
|
||||
QAction *gbrgAction = bayerActionGroup->addAction(tr("GBRG"));//0 1
|
||||
QAction *bggrAction = bayerActionGroup->addAction(tr("BGGR"));//1 1
|
||||
rggbAction->setCheckable(true); rggbAction->setData(0);
|
||||
grbgAction->setCheckable(true); grbgAction->setData(1);
|
||||
gbrgAction->setCheckable(true); gbrgAction->setData(2);
|
||||
bggrAction->setCheckable(true); bggrAction->setData(3);
|
||||
rggbAction->setCheckable(true); rggbAction->setData(0); rggbAction->setIcon(QIcon(":/bayer.png"));
|
||||
grbgAction->setCheckable(true); grbgAction->setData(1); grbgAction->setIcon(QIcon(":/grbg.png"));
|
||||
gbrgAction->setCheckable(true); gbrgAction->setData(2); gbrgAction->setIcon(QIcon(":/gbrg.png"));
|
||||
bggrAction->setCheckable(true); bggrAction->setData(3); bggrAction->setIcon(QIcon(":/bggr.png"));
|
||||
bayerMenu->addActions({rggbAction, grbgAction, gbrgAction, bggrAction});
|
||||
viewMenu->addMenu(bayerMenu);
|
||||
connect(bayerActionGroup, &QActionGroup::triggered, [this](QAction *action){
|
||||
@@ -486,6 +488,20 @@ void MainWindow::loadFile(int row)
|
||||
m_ringList->loadFile(row);
|
||||
}
|
||||
|
||||
void MainWindow::loadDir()
|
||||
{
|
||||
QString dir = QFileDialog::getExistingDirectory(this,
|
||||
tr("Open directory recursively"),
|
||||
_lastDir);
|
||||
if(!dir.isEmpty())
|
||||
{
|
||||
_lastDir = dir;
|
||||
m_ringList->setDir(dir, QString(), true);
|
||||
QSettings settings;
|
||||
settings.setValue("mainwindow/lastdir", _lastDir);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::indexDir()
|
||||
{
|
||||
QString dir = QFileDialog::getExistingDirectory(this, tr("Index directory"), _lastDir, QFileDialog::ShowDirsOnly);
|
||||
|
||||
@@ -48,6 +48,7 @@ protected slots:
|
||||
void loadFile();
|
||||
void loadFile(const QString &path);
|
||||
void loadFile(int row);
|
||||
void loadDir();
|
||||
void indexDir();
|
||||
void indexDir(const QString &dir);
|
||||
void reindex();
|
||||
|
||||
+110
-10
@@ -7,9 +7,12 @@ int THUMB_SIZE = 128;
|
||||
int THUMB_SIZE_BORDER = 138;
|
||||
int THUMB_SIZE_BORDER_Y = 158;
|
||||
double SATURATION = 0.95;
|
||||
bool QUALITY_RESIZE = true;
|
||||
|
||||
#ifdef __SSE2__
|
||||
template<typename T, int ch>
|
||||
void fromPlanarSSE(const void *in, void *out, size_t count);
|
||||
#endif
|
||||
|
||||
size_t RawImage::typeSize(RawImage::DataType type)
|
||||
{
|
||||
@@ -117,7 +120,7 @@ RawImage::RawImage(const QImage &img)
|
||||
m_stats.m_stats = false;
|
||||
}
|
||||
|
||||
const RawImage::Stats& RawImage::imageStats()
|
||||
const RawImage::Stats& RawImage::imageStats() const
|
||||
{
|
||||
return m_stats;
|
||||
}
|
||||
@@ -348,6 +351,11 @@ uint32_t RawImage::norm() const
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t RawImage::widthBytes() const
|
||||
{
|
||||
return m_ch * m_width;
|
||||
}
|
||||
|
||||
void* RawImage::data()
|
||||
{
|
||||
return m_pixels.get();
|
||||
@@ -384,9 +392,18 @@ const void *RawImage::origData(uint32_t row, uint32_t col) const
|
||||
return m_pixels.get() + (m_width * row * m_ch + col * m_ch) * typeSize(m_type);
|
||||
}
|
||||
|
||||
bool RawImage::planar() const
|
||||
{
|
||||
return m_planar;
|
||||
}
|
||||
|
||||
void RawImage::convertToThumbnail()
|
||||
{
|
||||
m_thumbAspect = (float)width() / height();
|
||||
if(!valid())
|
||||
return;
|
||||
|
||||
if(m_thumbAspect == 0.0f)
|
||||
m_thumbAspect = (float)width() / height();
|
||||
std::unique_ptr<PixelType[]> outptr = std::make_unique<PixelType[]>(THUMB_SIZE * THUMB_SIZE * 4 * sizeof(uint16_t));
|
||||
uint16_t *out = reinterpret_cast<uint16_t*>(outptr.get());
|
||||
|
||||
@@ -398,6 +415,7 @@ void RawImage::convertToThumbnail()
|
||||
{
|
||||
int idx = (i*THUMB_SIZE + o)*4;
|
||||
int idx2 = ((i * m_height / THUMB_SIZE * m_width) + (o * m_width / THUMB_SIZE)) * m_ch;
|
||||
|
||||
if(m_channels == 1)
|
||||
{
|
||||
out[idx] = out[idx + 1] = out[idx + 2] = in[idx2] * scale;
|
||||
@@ -557,14 +575,81 @@ bool RawImage::pixel(int x, int y, double &r, double &g, double &b) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void RawImage::downscaleTo(uint32_t size)
|
||||
template<typename T>
|
||||
void boxResample(uint32_t w, uint32_t h, uint32_t ch, uint32_t oldw, uint32_t oldh, const uint8_t *in_, uint8_t *out_)
|
||||
{
|
||||
/*if(size < width() || size < height())
|
||||
if(oldw == 0 || oldh == 0)return;
|
||||
|
||||
const T *in = reinterpret_cast<const T*>(in_);
|
||||
T *out = reinterpret_cast<T*>(out_);
|
||||
float max = 255.0f;
|
||||
if constexpr(std::is_same<T, uint16_t>::value)
|
||||
max = UINT16_MAX;
|
||||
|
||||
float sx = (float)w / oldw;
|
||||
float sy = (float)h / oldh;
|
||||
for(uint32_t y = 0; y < h; y++)//iterate over destination Y
|
||||
{
|
||||
double s = (double)size / std::max(width(), height());
|
||||
cv::Size dsize(std::floor(width() * s), std::floor(height() * s));
|
||||
cv::resize(m_img, m_img, dsize, 0, 0, cv::INTER_AREA);
|
||||
}*/
|
||||
for(uint32_t x = 0; x < w; x++)//iterate over destination X
|
||||
{
|
||||
float p[4] = {0.0f};
|
||||
uint32_t xx = x * oldw / w;//calculate source rect
|
||||
uint32_t yy = y * oldh / h;
|
||||
uint32_t xe = std::min((x + 1) * oldw / w, oldw - 1);
|
||||
uint32_t ye = std::min((y + 1) * oldh / h, oldh - 1);
|
||||
for(uint32_t o = yy; o <= ye; o++)//iterate over source Y
|
||||
{
|
||||
float cy = o * sy - y;
|
||||
if(cy < 0.0f)cy = sy + cy;
|
||||
else if(sy + cy > 1.0f)cy = 1.0f - cy;
|
||||
else cy = sy;
|
||||
if(yy==ye)cy = 1.0f;
|
||||
for(uint32_t i = xx; i <= xe; i++)//iterate over source X
|
||||
{
|
||||
float cx = i * sx - x;
|
||||
if(cx < 0.0f)cx = sx + cx;
|
||||
else if(sx + cx > 1.0f)cx = 1.0f - cx;
|
||||
else cx = sx;
|
||||
if(xx==xe)cx = 1.0f;
|
||||
for(uint32_t z = 0; z < ch; z++)
|
||||
p[z] += in[(o * oldw + i) * ch + z] * cy * cx;
|
||||
}
|
||||
}
|
||||
for(uint32_t z = 0; z < ch; z++)
|
||||
if constexpr(std::is_floating_point<T>::value)
|
||||
out[(y * w + x) * ch + z] = p[z];
|
||||
else
|
||||
out[(y * w + x) * ch + z] = std::clamp(std::round(p[z]), 0.0f, max);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RawImage::resize(uint32_t w, uint32_t h)
|
||||
{
|
||||
if(!valid())return;
|
||||
|
||||
std::unique_ptr<PixelType[]> old_pixels = std::move(m_pixels);
|
||||
uint32_t oldw = m_width;
|
||||
uint32_t oldh = m_height;
|
||||
m_thumbAspect = (float)m_width / m_height;
|
||||
|
||||
allocate(w, h, m_channels, m_type);
|
||||
|
||||
switch(m_type)
|
||||
{
|
||||
case RawImage::UINT8:
|
||||
boxResample<uint8_t>(w, h, m_ch, oldw, oldh, old_pixels.get(), m_pixels.get());
|
||||
break;
|
||||
case RawImage::UINT16:
|
||||
boxResample<uint16_t>(w, h, m_ch, oldw, oldh, old_pixels.get(), m_pixels.get());
|
||||
break;
|
||||
case RawImage::FLOAT32:
|
||||
boxResample<float>(w, h, m_ch, oldw, oldh, old_pixels.get(), m_pixels.get());
|
||||
break;
|
||||
default:
|
||||
qWarning() << "Resizing format not supported";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<float, float> RawImage::unitScale() const
|
||||
@@ -584,6 +669,15 @@ std::pair<float, float> RawImage::unitScale() const
|
||||
return {1.0f, 0.0f};
|
||||
}
|
||||
|
||||
void RawImage::flip()
|
||||
{
|
||||
std::unique_ptr<PixelType[]> tmp = std::move(m_pixels);
|
||||
allocate(m_width, m_height, m_channels, m_type);
|
||||
uint32_t rowSize = m_width * m_ch * typeSize(m_type);
|
||||
for(uint32_t i=0; i<m_height; i++)
|
||||
std::memcpy(m_pixels.get() + rowSize * (m_height - i - 1), tmp.get() + rowSize * i, rowSize);
|
||||
}
|
||||
|
||||
std::shared_ptr<RawImage> RawImage::fromPlanar(const RawImage &img)
|
||||
{
|
||||
return RawImage::fromPlanar(img.data(), img.width(), img.height(), img.channels(), img.type());
|
||||
@@ -651,6 +745,7 @@ std::shared_ptr<RawImage> RawImage::fromPlanar(const void *pixels, uint32_t w, u
|
||||
convert(static_cast<const double*>(pixels), static_cast<double*>(image->data()), 1);
|
||||
break;
|
||||
}
|
||||
image->m_planar = false;
|
||||
return image;
|
||||
}
|
||||
|
||||
@@ -664,11 +759,11 @@ std::vector<RawImage> RawImage::split() const
|
||||
size_t s = size();
|
||||
auto extract = [&](auto *in, auto *out, size_t off)
|
||||
{
|
||||
for(size_t i=0; i < s; i+=m_ch)
|
||||
for(size_t i=0; i < s; i++)
|
||||
out[i] = in[i*m_ch + off];
|
||||
};
|
||||
|
||||
for(uint32_t i=0; i<m_ch; i++)
|
||||
for(uint32_t i=0; i<m_channels; i++)
|
||||
{
|
||||
switch(m_type)
|
||||
{
|
||||
@@ -690,3 +785,8 @@ std::vector<RawImage> RawImage::split() const
|
||||
|
||||
return planes;
|
||||
}
|
||||
|
||||
bool RawImage::valid() const
|
||||
{
|
||||
return m_width > 0 && m_height > 0;
|
||||
}
|
||||
|
||||
+9
-2
@@ -12,6 +12,7 @@
|
||||
extern int THUMB_SIZE;
|
||||
extern int THUMB_SIZE_BORDER;
|
||||
extern int THUMB_SIZE_BORDER_Y;
|
||||
extern bool QUALITY_RESIZE;
|
||||
|
||||
class Peak
|
||||
{
|
||||
@@ -70,6 +71,7 @@ protected:
|
||||
DataType m_origType = UINT8;
|
||||
float m_thumbAspect = 0.0;
|
||||
Stats m_stats;
|
||||
bool m_planar = false;
|
||||
void allocate(uint32_t w, uint32_t h, uint32_t ch, DataType type);
|
||||
public:
|
||||
RawImage();
|
||||
@@ -77,7 +79,7 @@ public:
|
||||
RawImage(const RawImage &d);
|
||||
RawImage(RawImage &&d);
|
||||
RawImage(const QImage &img);
|
||||
const RawImage::Stats& imageStats();
|
||||
const RawImage::Stats& imageStats() const;
|
||||
void calcStats();
|
||||
void rect(int &x, int &y, int w, int h, std::vector<double> &r) const;
|
||||
int findPeaks(double background, double distance, std::vector<Peak> &peaks) const;
|
||||
@@ -87,23 +89,28 @@ public:
|
||||
uint32_t size() const;
|
||||
DataType type() const;
|
||||
uint32_t norm() const;
|
||||
uint32_t widthBytes() const;
|
||||
void* data();
|
||||
const void* data() const;
|
||||
void* data(uint32_t row, uint32_t col = 0);
|
||||
const void* data(uint32_t row, uint32_t col = 0) const;
|
||||
const void *origData() const;
|
||||
const void *origData(uint32_t row, uint32_t col = 0) const;
|
||||
bool planar() const;
|
||||
void setPlanar();
|
||||
void convertToThumbnail();
|
||||
void convertToGLFormat();
|
||||
float thumbAspect() const;
|
||||
bool pixel(int x, int y, double &r, double &g, double &b) const;
|
||||
void downscaleTo(uint32_t size);
|
||||
void resize(uint32_t w, uint32_t h);
|
||||
std::pair<float, float> unitScale() const;
|
||||
void flip();
|
||||
|
||||
static std::shared_ptr<RawImage> fromPlanar(const RawImage &img);
|
||||
static std::shared_ptr<RawImage> fromPlanar(const void *pixels, uint32_t w, uint32_t h, uint32_t ch, DataType type);
|
||||
static size_t typeSize(DataType type);
|
||||
std::vector<RawImage> split() const;
|
||||
bool valid() const;
|
||||
};
|
||||
|
||||
//Q_DECLARE_SMART_POINTER_METATYPE(std::shared_ptr);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include "rawimage.h"
|
||||
|
||||
#ifdef __SSE2__
|
||||
#include <x86intrin.h>
|
||||
|
||||
template<typename T, int ch>
|
||||
@@ -109,3 +111,5 @@ template void fromPlanarSSE<uint32_t, 3>(const void *in, void *out, size_t count
|
||||
template void fromPlanarSSE<uint32_t, 4>(const void *in, void *out, size_t count);
|
||||
template void fromPlanarSSE<float, 3>(const void *in, void *out, size_t count);
|
||||
template void fromPlanarSSE<float, 4>(const void *in, void *out, size_t count);
|
||||
|
||||
#endif
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 380 B After Width: | Height: | Size: 122 B |
Binary file not shown.
|
After Width: | Height: | Size: 316 B |
Binary file not shown.
|
After Width: | Height: | Size: 316 B |
Binary file not shown.
|
After Width: | Height: | Size: 316 B |
@@ -13,6 +13,9 @@
|
||||
<file>../translations/tenmon_fr.qm</file>
|
||||
<file>falsecolor.png</file>
|
||||
<file>link.png</file>
|
||||
<file>bggr.png</file>
|
||||
<file>grbg.png</file>
|
||||
<file>gbrg.png</file>
|
||||
</qresource>
|
||||
<qresource lang="en" prefix="/">
|
||||
<file alias="help">../about/help_en</file>
|
||||
|
||||
+391
-26
@@ -2,21 +2,32 @@
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QDebug>
|
||||
#include <QInputDialog>
|
||||
#include "loadrunable.h"
|
||||
#include "rawimage.h"
|
||||
#include "loadrunable.h"
|
||||
#include "batchprocessing.h"
|
||||
#include <fitsio2.h>
|
||||
#include "libXISF/libxisf.h"
|
||||
|
||||
namespace Script
|
||||
{
|
||||
|
||||
ScriptEngine::ScriptEngine(QObject *parent) : QObject(parent)
|
||||
, _jsEngine(new QJSEngine(this))
|
||||
ScriptEngine::ScriptEngine(BatchProcessing *parent)
|
||||
: _jsEngine(new QJSEngine(this))
|
||||
, _database(new Database(this))
|
||||
, _parent(parent)
|
||||
, _pool(new QThreadPool(this))
|
||||
{
|
||||
QJSValue engine = _jsEngine->newQObject(this);
|
||||
_jsEngine->globalObject().setProperty("engine", engine);
|
||||
QJSValue core = _jsEngine->newQObject(this);
|
||||
_jsEngine->globalObject().setProperty("core", core);
|
||||
QJSValue fitsRecordObject = _jsEngine->newQMetaObject(&FITSRecordModify::staticMetaObject);
|
||||
_jsEngine->globalObject().setProperty("FITSRecordModify", fitsRecordObject);
|
||||
_database->init(QLatin1String("scriptengine"));
|
||||
_semaphore.release(_pool->maxThreadCount());
|
||||
}
|
||||
|
||||
void ScriptEngine::setParams(const QString &scriptPath, const QStringList &paths, const QString &outputDir)
|
||||
void ScriptEngine::setParams(const QString &scriptPath, const QList<QPair<QString, QString>> &paths, const QString &outputDir)
|
||||
{
|
||||
_scriptPath = scriptPath;
|
||||
_paths = paths;
|
||||
@@ -63,23 +74,115 @@ bool ScriptEngine::isMarked(const File *file) const
|
||||
return _database->isMarked(file->absoluteFilePath());
|
||||
}
|
||||
|
||||
void ScriptEngine::setMaxThread(int maxthread)
|
||||
{
|
||||
int newval = std::max(std::min(QThread::idealThreadCount(), maxthread), 1);
|
||||
int oldval = _pool->maxThreadCount();
|
||||
if(newval > oldval)
|
||||
_semaphore.release(newval - oldval);
|
||||
else if(newval < oldval)
|
||||
_semaphore.acquire(oldval - newval);
|
||||
_pool->setMaxThreadCount(newval);
|
||||
}
|
||||
|
||||
void ScriptEngine::sync()
|
||||
{
|
||||
_pool->waitForDone();
|
||||
}
|
||||
|
||||
QJSValue ScriptEngine::getString(const QString &label, const QString &text) const
|
||||
{
|
||||
QJSValue ret;
|
||||
QMetaObject::invokeMethod(_parent, "getString", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QJSValue, ret), Q_ARG(QString, label), Q_ARG(QString, text));
|
||||
return ret;
|
||||
}
|
||||
|
||||
QJSValue ScriptEngine::getInt(const QString &label, int value)
|
||||
{
|
||||
QJSValue ret;
|
||||
QMetaObject::invokeMethod(_parent, "getInt", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QJSValue, ret), Q_ARG(QString, label), Q_ARG(int, value));
|
||||
return ret;
|
||||
}
|
||||
|
||||
QJSValue ScriptEngine::getFloat(const QString &label, double value, int decimals) const
|
||||
{
|
||||
QJSValue ret;
|
||||
QMetaObject::invokeMethod(_parent, "getFloat", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QJSValue, ret), Q_ARG(QString, label), Q_ARG(double, value), Q_ARG(int, decimals));
|
||||
return ret;
|
||||
}
|
||||
|
||||
QJSValue ScriptEngine::getItem(const QStringList &items, const QString &label, int current) const
|
||||
{
|
||||
QJSValue ret;
|
||||
QMetaObject::invokeMethod(_parent, "getItem", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QJSValue, ret), Q_ARG(QStringList, items), Q_ARG(QString, label), Q_ARG(int, current));
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ScriptEngine::convert(File *file, QString &outpath, const QString &format, const QVariantMap ¶ms, bool async)
|
||||
{
|
||||
QString path;
|
||||
QDir dir(_outputDir);
|
||||
QFileInfo info(outpath);
|
||||
QString suffix = info.suffix();
|
||||
if(info.isAbsolute())
|
||||
path = info.absolutePath();
|
||||
else
|
||||
path = dir.absoluteFilePath(outpath);
|
||||
|
||||
QString f = format.toLower();
|
||||
if(f != "xisf" && f != "fits" && f != "png" && f != "bmp" && f != "jpg")
|
||||
{
|
||||
logError("Output format must be one of xisf fits jpg png bmp");
|
||||
return false;
|
||||
}
|
||||
|
||||
info.setFile(path);
|
||||
outpath = info.absolutePath() + "/" + info.completeBaseName() + "." + f;
|
||||
if(async)
|
||||
{
|
||||
_semaphore.acquire();
|
||||
_pool->start(new ConvertRunable(file->absoluteFilePath(), outpath, f, params, &_semaphore));
|
||||
}
|
||||
else
|
||||
{
|
||||
ConvertRunable crun(file->absoluteFilePath(), outpath, f, params, nullptr);
|
||||
crun.run();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QJSValue ScriptEngine::newObject()
|
||||
{
|
||||
return _jsEngine->newObject();
|
||||
}
|
||||
|
||||
QJSValue ScriptEngine::newArray(uint size)
|
||||
{
|
||||
return _jsEngine->newArray(size);
|
||||
}
|
||||
|
||||
void ScriptEngine::run()
|
||||
{
|
||||
QJSValue jsPaths = _jsEngine->newArray(_paths.size());
|
||||
for(qsizetype i=0; i<_paths.size(); i++)
|
||||
jsPaths.setProperty(i, _jsEngine->newQObject(new File(_paths[i], this)));
|
||||
jsPaths.setProperty(i, _jsEngine->newQObject(new File(_paths[i].first, _paths[i].second, this)));
|
||||
|
||||
_jsEngine->globalObject().setProperty("files", jsPaths);
|
||||
|
||||
QFile scriptFile(_scriptPath);
|
||||
if(!scriptFile.open(QIODevice::ReadOnly))
|
||||
{
|
||||
emit newMessage("Failed to open " + _scriptPath, true);
|
||||
emit finished();
|
||||
return;
|
||||
}
|
||||
|
||||
QTextStream stream(&scriptFile);
|
||||
QString contents = stream.readAll();
|
||||
scriptFile.close();
|
||||
QJSValue result = _jsEngine->evaluate(contents, _scriptPath);
|
||||
qDebug() << result.isError() << result.toString();
|
||||
_pool->waitForDone();
|
||||
if(result.isError())
|
||||
{
|
||||
QString error = result.property("name").toString() + " on line " + result.property("lineNumber").toString() + " : " + result.toString();
|
||||
@@ -96,19 +199,20 @@ void File::loadFitsKeywords()
|
||||
{
|
||||
_fitsKeywordsLoaded = true;
|
||||
ImageInfoData info;
|
||||
if(suffix() == "xisf")
|
||||
if(suffix().toLower() == "xisf")
|
||||
{
|
||||
readXISFHeader(_path, info);
|
||||
}
|
||||
else if(suffix() == "fits")
|
||||
else if(suffix().toLower() == "fits" || suffix().toLower() == "fit")
|
||||
{
|
||||
readFITSHeader(_path, info);
|
||||
}
|
||||
else return;
|
||||
|
||||
for(const FITSRecord &record : info.fitsHeader)
|
||||
for(auto &record : info.fitsHeader)
|
||||
{
|
||||
_fitsKeywords[record.key] = record.value.toString();
|
||||
_fitsKeywords.append(record.key);
|
||||
_fitsRecords.insert(record.key, record);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,9 +237,14 @@ bool File::mkpath(const QString &path) const
|
||||
}
|
||||
}
|
||||
|
||||
File::File(const QString &path, Script::ScriptEngine *engine) :
|
||||
File::File(const QString &path, Script::ScriptEngine *engine) : File(path, QString(), engine)
|
||||
{
|
||||
}
|
||||
|
||||
File::File(const QString &path, const QString &root, ScriptEngine *engine) :
|
||||
_engine(engine),
|
||||
_path(path),
|
||||
_root(root),
|
||||
_info(path)
|
||||
{
|
||||
}
|
||||
@@ -155,6 +264,18 @@ QString File::absolutePath() const
|
||||
return _info.absolutePath();
|
||||
}
|
||||
|
||||
QString File::relativeFilePath() const
|
||||
{
|
||||
QDir dir(_root);
|
||||
return dir.relativeFilePath(_info.absoluteFilePath());
|
||||
}
|
||||
|
||||
QString File::relativePath() const
|
||||
{
|
||||
QDir dir(_root);
|
||||
return dir.relativeFilePath(_info.absolutePath());
|
||||
}
|
||||
|
||||
QString File::baseName() const
|
||||
{
|
||||
return _info.baseName();
|
||||
@@ -177,65 +298,293 @@ qint64 File::size() const
|
||||
|
||||
QStringList File::fitsKeywords()
|
||||
{
|
||||
QThread::msleep(500);
|
||||
loadFitsKeywords();
|
||||
return _fitsKeywords.keys();
|
||||
return _fitsKeywords;
|
||||
}
|
||||
|
||||
QString File::fitsValue(const QString &key)
|
||||
{
|
||||
loadFitsKeywords();
|
||||
if(_fitsKeywords.contains(key))
|
||||
return _fitsKeywords[key];
|
||||
if(_fitsRecords.contains(key))
|
||||
return _fitsRecords[key].value.toString();
|
||||
else
|
||||
return QString();
|
||||
}
|
||||
|
||||
QJSValue File::fitsValues(const QString &key)
|
||||
{
|
||||
loadFitsKeywords();
|
||||
if(_fitsRecords.contains(key))
|
||||
{
|
||||
QList<FITSRecord> values = _fitsRecords.values(key);
|
||||
QJSValue array = _engine->newArray(values.size());
|
||||
for(qsizetype i=0; i<values.size(); i++)
|
||||
array.setProperty(i, values[i].value.toString());
|
||||
return array;
|
||||
}
|
||||
else
|
||||
return QString();
|
||||
}
|
||||
|
||||
QJSValue File::fitsRecords()
|
||||
{
|
||||
loadFitsKeywords();
|
||||
|
||||
QJSValue array = _engine->newArray(_fitsRecords.size());
|
||||
uint i = 0;
|
||||
for(auto &record : _fitsRecords)
|
||||
{
|
||||
QJSValue item = _engine->newObject();
|
||||
item.setProperty("key", QString::fromUtf8(record.key));
|
||||
item.setProperty("value", record.value.toString());
|
||||
item.setProperty("comment", QString::fromUtf8(record.comment));
|
||||
item.setProperty("xisf", record.xisf);
|
||||
array.setProperty(i++, item);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
bool File::modifyFITSRecords(const FITSRecordModify *modify)
|
||||
{
|
||||
_fitsKeywordsLoaded = false;
|
||||
_fitsKeywords.clear();
|
||||
|
||||
if(QRegularExpression("fits?", QRegularExpression::CaseInsensitiveOption).match(suffix()).hasMatch())
|
||||
{
|
||||
fitsfile *file;
|
||||
int status = 0;
|
||||
fits_open_diskfile(&file, _path.toLocal8Bit().data(), READWRITE, &status);
|
||||
int num = 0;
|
||||
fits_get_num_hdus(file, &num, &status);
|
||||
if(status)
|
||||
{
|
||||
_engine->newMessage("Failed to open FITS file", true);
|
||||
return false;
|
||||
}
|
||||
int imgtype;
|
||||
int naxis;
|
||||
long naxes[3] = {0};
|
||||
int type = -1;
|
||||
for(int i=1; i <= num; i++)
|
||||
{
|
||||
fits_movabs_hdu(file, i, IMAGE_HDU, &status);
|
||||
fits_get_hdu_type(file, &type, &status);
|
||||
fits_get_img_param(file, 3, &imgtype, &naxis, naxes, &status);
|
||||
if(type == IMAGE_HDU && naxis >= 2 && naxis <= 3 && status == 0)
|
||||
break;
|
||||
if(i == num)return false;
|
||||
}
|
||||
|
||||
for(auto &remove : modify->_remove)
|
||||
{
|
||||
int status = 0;//we ignore errors from here
|
||||
fits_delete_key(file, remove.toLatin1().data(), &status);
|
||||
}
|
||||
for(auto &record : modify->_update)
|
||||
{
|
||||
switch(record.value.typeId())
|
||||
{
|
||||
case QMetaType::Bool:
|
||||
{
|
||||
int val = record.value.toBool();
|
||||
fits_update_key(file, TLOGICAL, record.key.data(), &val, record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
|
||||
break;
|
||||
}
|
||||
case QMetaType::Int:
|
||||
case QMetaType::UInt:
|
||||
{
|
||||
long long val = record.value.toLongLong();
|
||||
fits_update_key(file, TLONGLONG, record.key.data(), &val, record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
|
||||
break;
|
||||
}
|
||||
case QMetaType::QString:
|
||||
{
|
||||
QByteArray val = record.value.toString().toLatin1();
|
||||
fits_update_key(file, TSTRING, record.key.data(), val.isEmpty() ? nullptr : val.data(), record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
|
||||
break;
|
||||
}
|
||||
case QMetaType::Float:
|
||||
case QMetaType::Double:
|
||||
{
|
||||
double val = record.value.toDouble();
|
||||
fits_update_key(file, TDOUBLE, record.key.data(), &val, record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
_engine->newMessage("Unknown type for KEY " + record.key, true);
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
if(status)
|
||||
{
|
||||
char error[100];
|
||||
fits_get_errstatus(status, error);
|
||||
_engine->newMessage(QString("Error when updating KEY %1 %2").arg(record.key).arg(error), true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for(auto &record : modify->_add)
|
||||
{
|
||||
switch(record.value.typeId())
|
||||
{
|
||||
case QMetaType::Bool:
|
||||
{
|
||||
int val = record.value.toBool();
|
||||
fits_write_key(file, TLOGICAL, record.key.data(), &val, record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
|
||||
break;
|
||||
}
|
||||
case QMetaType::Int:
|
||||
case QMetaType::UInt:
|
||||
{
|
||||
long long val = record.value.toLongLong();
|
||||
fits_write_key(file, TLONGLONG, record.key.data(), &val, record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
|
||||
break;
|
||||
}
|
||||
case QMetaType::QString:
|
||||
{
|
||||
QByteArray val = record.value.toString().toLatin1();
|
||||
fits_write_key(file, TSTRING, record.key.data(), val.isEmpty() ? nullptr : val.data(), record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
|
||||
break;
|
||||
}
|
||||
case QMetaType::Float:
|
||||
case QMetaType::Double:
|
||||
{
|
||||
double val = record.value.toDouble();
|
||||
fits_write_key(file, TDOUBLE, record.key.data(), &val, record.comment.isEmpty() ? nullptr : record.comment.data(), &status);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
_engine->newMessage("Unknown type for KEY " + record.key, true);
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
if(status)
|
||||
{
|
||||
char error[100];
|
||||
fits_get_errstatus(status, error);
|
||||
_engine->newMessage(QString("Error when adding KEY {} {}").arg(record.key).arg(error), true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
fits_close_file(file, &status);
|
||||
|
||||
return status == 0;
|
||||
}
|
||||
else if(suffix() == "xisf")
|
||||
{
|
||||
try
|
||||
{
|
||||
LibXISF::XISFModify modifyXISF;
|
||||
modifyXISF.open(_path.toLocal8Bit().data());
|
||||
QFileInfo in(_path);
|
||||
QFileInfo out(_path + "~");
|
||||
|
||||
for(auto &remove : modify->_remove)
|
||||
modifyXISF.removeFITSKeyword(0, remove.toStdString());
|
||||
|
||||
for(auto &record : modify->_update)
|
||||
modifyXISF.updateFITSKeyword(0, {record.key.toStdString(), record.value.toString().toStdString(), record.value.toString().toStdString()}, true);
|
||||
|
||||
for(auto &record : modify->_add)
|
||||
modifyXISF.addFITSKeyword(0, {record.key.toStdString(), record.value.toString().toStdString(), record.value.toString().toStdString()});
|
||||
|
||||
modifyXISF.save(out.absoluteFilePath().toLocal8Bit().toStdString());
|
||||
modifyXISF.close();
|
||||
std::filesystem::rename(out.filesystemAbsoluteFilePath(), in.filesystemAbsoluteFilePath());
|
||||
}
|
||||
catch(LibXISF::Error &err)
|
||||
{
|
||||
_engine->newMessage("Failed to modify file " + _path + " " + err.what(), true);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool File::isMarked() const
|
||||
{
|
||||
return _engine->isMarked(this);
|
||||
}
|
||||
|
||||
bool File::copy(const QString &newpath) const
|
||||
File* File::copy(const QString &newpath) const
|
||||
{
|
||||
if(mkpath(newpath))
|
||||
{
|
||||
if(QFile::copy(_path, _engine->outputDir() + newpath))
|
||||
return true;
|
||||
return new File(_engine->outputDir() + newpath, _engine);
|
||||
_engine->logError("Failed copy to " + newpath);
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool File::move(const QString &newpath) const
|
||||
bool File::move(const QString &newpath)
|
||||
{
|
||||
if(mkpath(newpath))
|
||||
{
|
||||
if(QFile::rename(_path, _engine->outputDir() + newpath))
|
||||
{
|
||||
_path = _engine->outputDir() + newpath;
|
||||
return true;
|
||||
}
|
||||
_engine->logError("Failed move to " + newpath);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool File::convertTo(const QString &format)
|
||||
File* File::convert(const QString &outpath, const QString &format, const QVariantMap ¶ms)
|
||||
{
|
||||
_engine->reportError("Not implemented");
|
||||
return false;
|
||||
QString path = outpath;
|
||||
if(_engine->convert(this, path, format, params, false))
|
||||
return new File(path, _engine);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ScriptEngineThread::ScriptEngineThread(QObject *parent) : QObject(parent)
|
||||
File* File::convertAsync(const QString &outpath, const QString &format, const QVariantMap ¶ms)
|
||||
{
|
||||
QString path = outpath;
|
||||
if(_engine->convert(this, path, format, params, true))
|
||||
return new File(path, _engine);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QJSValue File::stats()
|
||||
{
|
||||
if(_stats.isUndefined())
|
||||
{
|
||||
ImageInfoData info;
|
||||
std::shared_ptr<RawImage> rawImage;
|
||||
loadImage(_path, info, rawImage);
|
||||
rawImage->calcStats();
|
||||
RawImage::Stats stats = rawImage->imageStats();
|
||||
_stats = _engine->newObject();
|
||||
_stats.setProperty("mean", stats.m_mean[0]);
|
||||
_stats.setProperty("stddev", stats.m_stdDev[0]);
|
||||
_stats.setProperty("median", stats.m_median[0]);
|
||||
_stats.setProperty("min", stats.m_min[0]);
|
||||
_stats.setProperty("max", stats.m_max[0]);
|
||||
_stats.setProperty("mad", stats.m_mean[0]);
|
||||
}
|
||||
return _stats;
|
||||
}
|
||||
|
||||
ScriptEngineThread::ScriptEngineThread(BatchProcessing *parent) : QObject(parent)
|
||||
{
|
||||
_thread = new QThread();
|
||||
_thread->setObjectName("ScriptEngine");
|
||||
_engine = new ScriptEngine;
|
||||
_engine = new ScriptEngine(parent);
|
||||
_engine->moveToThread(_thread);
|
||||
connect(_engine, &ScriptEngine::finished, _thread, &QThread::quit);
|
||||
connect(_engine, &ScriptEngine::newMessage, this, &ScriptEngineThread::newMessage);
|
||||
connect(_thread, &QThread::started, _engine, &ScriptEngine::run);
|
||||
connect(_thread, &QThread::finished, _engine, &ScriptEngine::deleteLater);
|
||||
connect(_engine, &ScriptEngine::destroyed, [this](){ _engine = nullptr; });
|
||||
connect(_thread, &QThread::finished, _thread, &QThread::deleteLater);
|
||||
connect(_thread, &QThread::finished, this, &ScriptEngineThread::finished);
|
||||
}
|
||||
@@ -245,7 +594,7 @@ ScriptEngineThread::~ScriptEngineThread()
|
||||
if(_engine)_engine->interrupt();
|
||||
}
|
||||
|
||||
void ScriptEngineThread::setParams(const QString &scriptPath, const QStringList &paths, const QString &outputDir)
|
||||
void ScriptEngineThread::setParams(const QString &scriptPath, const QList<QPair<QString, QString>> &paths, const QString &outputDir)
|
||||
{
|
||||
_engine->setParams(scriptPath, paths, outputDir);
|
||||
}
|
||||
@@ -260,4 +609,20 @@ void ScriptEngineThread::interrupt()
|
||||
if(_engine)_engine->interrupt();
|
||||
}
|
||||
|
||||
void FITSRecordModify::removeKeyword(const QString &key)
|
||||
{
|
||||
if(!_remove.contains(key))
|
||||
_remove.append(key);
|
||||
}
|
||||
|
||||
void FITSRecordModify::updateKeyword(const QString &key, const QVariant &value, const QString &comment)
|
||||
{
|
||||
_update.append({key.toLatin1(), value, comment.toLatin1()});
|
||||
}
|
||||
|
||||
void FITSRecordModify::addKeyword(const QString &key, const QVariant &value, const QString &comment)
|
||||
{
|
||||
_update.append({key.toLatin1(), value, comment.toLatin1()});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+54
-9
@@ -5,7 +5,12 @@
|
||||
#include <QJSEngine>
|
||||
#include <QFileInfo>
|
||||
#include <QThread>
|
||||
#include <QThreadPool>
|
||||
#include <QSemaphore>
|
||||
#include "database.h"
|
||||
#include "imageinfo.h"
|
||||
|
||||
class BatchProcessing;
|
||||
|
||||
namespace Script
|
||||
{
|
||||
@@ -17,12 +22,15 @@ class ScriptEngine : public QObject
|
||||
Q_OBJECT
|
||||
QJSEngine *_jsEngine;
|
||||
Database *_database;
|
||||
BatchProcessing *_parent;
|
||||
QThreadPool *_pool;
|
||||
QSemaphore _semaphore;
|
||||
QString _scriptPath;
|
||||
QString _outputDir;
|
||||
QStringList _paths;
|
||||
QList<QPair<QString, QString>> _paths;
|
||||
public:
|
||||
explicit ScriptEngine(QObject *parent = nullptr);
|
||||
void setParams(const QString &scriptPath, const QStringList &paths, const QString &outputDir);
|
||||
explicit ScriptEngine(BatchProcessing *parent = nullptr);
|
||||
void setParams(const QString &scriptPath, const QList<QPair<QString, QString>> &paths, const QString &outputDir);
|
||||
void reportError(const QString &message);
|
||||
const QString& outputDir() const;
|
||||
void interrupt();
|
||||
@@ -31,6 +39,15 @@ public:
|
||||
Q_INVOKABLE void mark(File *file);
|
||||
Q_INVOKABLE void unmark(File *file);
|
||||
Q_INVOKABLE bool isMarked(const File *file) const;
|
||||
Q_INVOKABLE void setMaxThread(int maxthread);
|
||||
Q_INVOKABLE void sync();
|
||||
Q_INVOKABLE QJSValue getString(const QString &label = QString(), const QString &text = QString()) const;
|
||||
Q_INVOKABLE QJSValue getInt(const QString &label = QString(), int value = 0);
|
||||
Q_INVOKABLE QJSValue getFloat(const QString &label = QString(), double value = 0, int decimals = 3) const;
|
||||
Q_INVOKABLE QJSValue getItem(const QStringList &items, const QString &label = "", int current = 0) const;
|
||||
bool convert(File *file, QString &outpath, const QString &format, const QVariantMap ¶ms, bool async);
|
||||
QJSValue newObject();
|
||||
QJSValue newArray(uint size);
|
||||
public slots:
|
||||
void run();
|
||||
signals:
|
||||
@@ -44,9 +61,9 @@ class ScriptEngineThread : public QObject
|
||||
QThread *_thread;
|
||||
ScriptEngine *_engine;
|
||||
public:
|
||||
ScriptEngineThread(QObject *parent = nullptr);
|
||||
ScriptEngineThread(BatchProcessing *parent = nullptr);
|
||||
~ScriptEngineThread();
|
||||
void setParams(const QString &scriptPath, const QStringList &paths, const QString &outputDir);
|
||||
void setParams(const QString &scriptPath, const QList<QPair<QString, QString>> &paths, const QString &outputDir);
|
||||
void start();
|
||||
void interrupt();
|
||||
signals:
|
||||
@@ -54,31 +71,59 @@ signals:
|
||||
void finished();
|
||||
};
|
||||
|
||||
class FITSRecordModify;
|
||||
|
||||
class File : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
ScriptEngine *_engine;
|
||||
QString _path;
|
||||
QString _root;
|
||||
QFileInfo _info;
|
||||
bool _fitsKeywordsLoaded = false;
|
||||
QMap<QString, QString> _fitsKeywords;
|
||||
QStringList _fitsKeywords;
|
||||
QMultiHash<QString, FITSRecord> _fitsRecords;
|
||||
void loadFitsKeywords();
|
||||
bool mkpath(const QString &path) const;
|
||||
QJSValue _stats;
|
||||
public:
|
||||
explicit File(const QString &path, ScriptEngine *engine);
|
||||
explicit File(const QString &path, const QString &root, ScriptEngine *engine);
|
||||
Q_INVOKABLE QString fileName() const;
|
||||
Q_INVOKABLE QString absoluteFilePath() const;
|
||||
Q_INVOKABLE QString absolutePath() const;
|
||||
Q_INVOKABLE QString relativeFilePath() const;
|
||||
Q_INVOKABLE QString relativePath() const;
|
||||
Q_INVOKABLE QString baseName() const;
|
||||
Q_INVOKABLE QString completeBaseName() const;
|
||||
Q_INVOKABLE QString suffix() const;
|
||||
Q_INVOKABLE qint64 size() const;
|
||||
Q_INVOKABLE QStringList fitsKeywords();
|
||||
Q_INVOKABLE QString fitsValue(const QString &key);
|
||||
Q_INVOKABLE QJSValue fitsValues(const QString &key);
|
||||
Q_INVOKABLE QJSValue fitsRecords();
|
||||
Q_INVOKABLE bool modifyFITSRecords(const FITSRecordModify *modify);
|
||||
Q_INVOKABLE bool isMarked() const;
|
||||
Q_INVOKABLE bool copy(const QString &newpath) const;
|
||||
Q_INVOKABLE bool move(const QString &newpath) const;
|
||||
Q_INVOKABLE bool convertTo(const QString &format);
|
||||
Q_INVOKABLE File* copy(const QString &newpath) const;
|
||||
Q_INVOKABLE bool move(const QString &newpath);
|
||||
Q_INVOKABLE File* convert(const QString &outpath, const QString &format, const QVariantMap ¶ms = QVariantMap());
|
||||
Q_INVOKABLE File* convertAsync(const QString &outpath, const QString &format, const QVariantMap ¶ms = QVariantMap());
|
||||
Q_INVOKABLE QJSValue stats();
|
||||
};
|
||||
|
||||
class FITSRecordModify : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
QStringList _remove;
|
||||
QVector<FITSRecord> _update;
|
||||
QVector<FITSRecord> _add;
|
||||
|
||||
friend class File;
|
||||
public:
|
||||
Q_INVOKABLE FITSRecordModify(){};
|
||||
Q_INVOKABLE void removeKeyword(const QString &key);
|
||||
Q_INVOKABLE void updateKeyword(const QString &key, const QVariant &value, const QString &comment = QString());
|
||||
Q_INVOKABLE void addKeyword(const QString &key, const QVariant &value, const QString &comment = QString());
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+9
-1
@@ -71,11 +71,16 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent)
|
||||
m_filtering->addItems({tr("Nearest"), tr("Linear"), tr("Cubic")});
|
||||
m_filtering->setCurrentIndex(FILTERING);
|
||||
|
||||
m_qualityThumbnail = new QCheckBox(tr("Smooth thumbnails"), this);
|
||||
m_qualityThumbnail->setChecked(QUALITY_RESIZE);
|
||||
m_qualityThumbnail->setToolTip(tr("Use box filter when downsampling thumbnails instead of nearest. Slightly slower."));
|
||||
|
||||
layout->addRow(tr("Image preload count"), m_preloadImages);
|
||||
layout->addRow(tr("Thumbnails size"), m_thumSize);
|
||||
layout->addRow(tr("Saturation"), m_saturation);
|
||||
layout->addRow(tr("Slideshow interval"), m_slideShowTime);
|
||||
layout->addRow(tr("Image filtering"), m_filtering);
|
||||
layout->addRow(tr("Image interpolation"), m_filtering);
|
||||
layout->addRow(m_qualityThumbnail);
|
||||
layout->addRow(m_useNativeDialog);
|
||||
//layout->addRow(new QLabel(tr("Changes in settings will take effect after program restart.")));
|
||||
|
||||
@@ -97,6 +102,7 @@ void SettingsDialog::loadSettings()
|
||||
DEFAULT_WIDTH = settings.value("settings/preloadimagecount", DEFAULT_WIDTH).toInt();
|
||||
SATURATION = settings.value("settings/saturation", 95.0).toDouble() / 100.0;
|
||||
FILTERING = settings.value("settings/filtering", FILTERING).toInt();
|
||||
QUALITY_RESIZE = settings.value("settings/qualitythumbnail", QUALITY_RESIZE).toBool();
|
||||
QApplication::setAttribute(Qt::AA_DontUseNativeDialogs, settings.value("settings/dontusenativedialogs", false).toBool());
|
||||
}
|
||||
|
||||
@@ -118,6 +124,8 @@ void SettingsDialog::saveSettings()
|
||||
settings.setValue("settings/dontusenativedialogs", m_useNativeDialog->isChecked());
|
||||
settings.setValue("settings/saturation", m_saturation->value());
|
||||
settings.setValue("settings/slideshowtime", m_slideShowTime->value());
|
||||
settings.setValue("settings/qualitythumbnail", m_qualityThumbnail->isChecked());
|
||||
QUALITY_RESIZE = m_qualityThumbnail->isChecked();
|
||||
FILTERING = m_filtering->currentIndex();
|
||||
settings.setValue("settings/filtering", FILTERING);
|
||||
SATURATION = m_saturation->value() / 100.0;
|
||||
|
||||
@@ -23,6 +23,7 @@ private:
|
||||
QDoubleSpinBox *m_slideShowTime;
|
||||
QDoubleSpinBox *m_saturation;
|
||||
QCheckBox *m_useNativeDialog;
|
||||
QCheckBox *m_qualityThumbnail;
|
||||
QComboBox *m_filtering;
|
||||
};
|
||||
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
<launchable type="desktop-id">space.nouspiro.tenmon.desktop</launchable>
|
||||
<name>Tenmon</name>
|
||||
<summary>FITS/XISF image viewer, converter, index and search</summary>
|
||||
<developer id="nouspiro.space">
|
||||
<name>Dušan Poizl</name>
|
||||
</developer>
|
||||
<developer_name>Dušan Poizl</developer_name>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-3.0</project_license>
|
||||
<description>
|
||||
@@ -11,7 +15,7 @@
|
||||
<ul>
|
||||
<li>FITS 8, 16, 32 bit integer and 32, 64 bit float</li>
|
||||
<li>XISF 8, 16, 32 bit integer and 32, 64 bit float</li>
|
||||
<li>RAW CR2, DNG, NEF</li>
|
||||
<li>RAW CR2/CR3, DNG, NEF</li>
|
||||
<li>JPEG, PNG, BMP, GIF, PBM, PGM, PPM and SVG images</li>
|
||||
</ul>
|
||||
<p>Features of application:</p>
|
||||
@@ -43,13 +47,34 @@
|
||||
<url type="bugtracker">https://github.com/flathub/space.nouspiro.tenmon/issues</url>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<caption>Main window with image</caption>
|
||||
<image>https://nouspiro.space/wp-content/uploads/2022/04/tenmon-1024x579.png</image>
|
||||
</screenshot>
|
||||
<screenshot type="default">
|
||||
<caption>Thumnail view</caption>
|
||||
<image>https://nouspiro.space/wp-content/uploads/2022/12/tenmon2-1024x645.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<releases>
|
||||
<release version="20240108" date="2023-01-08">
|
||||
<release version="20240610" date="2024-06-10">
|
||||
<description>
|
||||
<ul>
|
||||
<li>Batch processing with JavaScript</li>
|
||||
<li>Opening directory recursively</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="20240201" date="2024-02-01">
|
||||
<description>
|
||||
<ul>
|
||||
<li>Smooth thumbnails</li>
|
||||
<li>Respect ROWORDER</li>
|
||||
<li>Bugfixes</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="20240108" date="2024-01-08">
|
||||
<description>
|
||||
<ul>
|
||||
<li>Update to Qt6</li>
|
||||
|
||||
+7
-4
@@ -120,12 +120,15 @@ void StretchToolbar::stretchImage(Image *img)
|
||||
mad = stats.m_mad[i];
|
||||
max = stats.m_max[i];
|
||||
median /= img->rawImage()->norm();
|
||||
bool a = median > 0.5 ? true : false;
|
||||
mad /= img->rawImage()->norm();
|
||||
max /= img->rawImage()->norm();
|
||||
float bp = median + mad * BLACK_POINT_SIGMA * MAD_TO_SIGMA;
|
||||
float mid = MTF(median - bp, TARGET_BACKGROUND);
|
||||
max = 1.0f;// /= img->rawImage()->norm();
|
||||
float bp = a || mad == 0.0f ? 0.0f : std::clamp(median + mad * BLACK_POINT_SIGMA * MAD_TO_SIGMA, 0.0, 1.0);
|
||||
if(a && mad != 0.0f)
|
||||
max = std::clamp(median - mad * BLACK_POINT_SIGMA * MAD_TO_SIGMA, 0.0, 1.0);
|
||||
float mid = !a ? MTF(median - bp, TARGET_BACKGROUND) : MTF(TARGET_BACKGROUND, max - median);
|
||||
m_mtfParam.blackPoint[i-o] = bp;
|
||||
m_mtfParam.midPoint[i-o] = mid / max;
|
||||
m_mtfParam.midPoint[i-o] = mid;// / max;
|
||||
m_mtfParam.whitePoint[i-o] = max;
|
||||
bp2 += bp;
|
||||
mid2 += mid;
|
||||
|
||||
Binary file not shown.
+412
-1
@@ -1,24 +1,191 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="en_US" sourcelanguage="en">
|
||||
<TS version="2.1" language="en_US" sourcelanguage="en_US">
|
||||
<context>
|
||||
<name>About</name>
|
||||
<message>
|
||||
<location filename="../about.cpp" line="12"/>
|
||||
<source>About Tenmon</source>
|
||||
<translation>About Tenmon</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>BatchProcessing</name>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="14"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="208"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="208"/>
|
||||
<source>Batch Processing</source>
|
||||
<translation>Batch Processing</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="22"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="209"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="209"/>
|
||||
<source>Input files and directories</source>
|
||||
<translation>Input files and directories</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="44"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="210"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="210"/>
|
||||
<source>Add files</source>
|
||||
<translation>Add files</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="51"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="211"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="211"/>
|
||||
<source>Add directories</source>
|
||||
<translation>Add directory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="58"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="212"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="212"/>
|
||||
<source>Remove</source>
|
||||
<translation>Remove</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="65"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="213"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="213"/>
|
||||
<source>Remove all</source>
|
||||
<translation>Remove all</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="78"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="214"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="214"/>
|
||||
<source>Output directory</source>
|
||||
<translation>Output directory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="92"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="215"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="215"/>
|
||||
<source>Browse</source>
|
||||
<translation>Browse</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="103"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="216"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="216"/>
|
||||
<source>Scripts</source>
|
||||
<translation>Scripts</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="123"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="217"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="217"/>
|
||||
<source>Open scripts</source>
|
||||
<translation>Open scripts</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="142"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="218"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="218"/>
|
||||
<source>Log</source>
|
||||
<translation>Log</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="182"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="227"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="219"/>
|
||||
<source>Start script</source>
|
||||
<translation>Start script</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="192"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="228"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="220"/>
|
||||
<source>Stop script</source>
|
||||
<translation>Stop script</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="199"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="229"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="221"/>
|
||||
<source>Close</source>
|
||||
<translation>Close</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="118"/>
|
||||
<source>Interrupt running script?</source>
|
||||
<translation>Interrupt running script?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="138"/>
|
||||
<source>Select files</source>
|
||||
<translation>Select files</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="149"/>
|
||||
<source>Select directory</source>
|
||||
<translation>Select directory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="170"/>
|
||||
<source>Select output directory</source>
|
||||
<translation>Select output directory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="212"/>
|
||||
<source>Invalid output directory</source>
|
||||
<translation>Invalid output directory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="212"/>
|
||||
<source>Output directory path doesn't exist or is not writable</source>
|
||||
<translation>Output directory path doesn't exist or is not writable</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="243"/>
|
||||
<source>Enter text</source>
|
||||
<translation>Enter text</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="250"/>
|
||||
<source>Enter integer number</source>
|
||||
<translation>Enter integer number</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="257"/>
|
||||
<source>Enter float number</source>
|
||||
<translation>Enter real number</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="264"/>
|
||||
<source>Select item</source>
|
||||
<translation>Select item</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="219"/>
|
||||
<source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
hr { height: 1px; border-width: 0; }
|
||||
li.unchecked::marker { content: "\2610"; }
|
||||
li.checked::marker { content: "\2612"; }
|
||||
</style></head><body style=" font-family:'FreeMono'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DataBaseView</name>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="255"/>
|
||||
<source>Select columns</source>
|
||||
<translation>Select columns</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="293"/>
|
||||
<source>Text to search, you can % as wildcard</source>
|
||||
<translation>Text to search, you can % as wildcard</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="309"/>
|
||||
<source>Filter</source>
|
||||
<translation>Filter</translation>
|
||||
</message>
|
||||
@@ -26,10 +193,12 @@
|
||||
<context>
|
||||
<name>DatabaseTableView</name>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="215"/>
|
||||
<source>Mark</source>
|
||||
<translation>Mark</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="216"/>
|
||||
<source>Unmark</source>
|
||||
<translation>Unmark</translation>
|
||||
</message>
|
||||
@@ -37,6 +206,7 @@
|
||||
<context>
|
||||
<name>FITSFileModel</name>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="194"/>
|
||||
<source>File name</source>
|
||||
<translation>File name</translation>
|
||||
</message>
|
||||
@@ -44,22 +214,27 @@
|
||||
<context>
|
||||
<name>FilesystemWidget</name>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="26"/>
|
||||
<source>Sort by filename</source>
|
||||
<translation>Sort by file name</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="27"/>
|
||||
<source>Sort by time</source>
|
||||
<translation>Sort by time</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="28"/>
|
||||
<source>Sort by size</source>
|
||||
<translation>Sort by size</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="29"/>
|
||||
<source>Sort by type</source>
|
||||
<translation>Sort by type</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="30"/>
|
||||
<source>Reverse</source>
|
||||
<translation>Reverse order</translation>
|
||||
</message>
|
||||
@@ -67,34 +242,43 @@
|
||||
<context>
|
||||
<name>Filetree</name>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="90"/>
|
||||
<location filename="../filesystemwidget.cpp" line="94"/>
|
||||
<source>Open</source>
|
||||
<translation>Open</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="96"/>
|
||||
<source>Copy marked files</source>
|
||||
<translation>Copy marked files</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="97"/>
|
||||
<source>Move marked files</source>
|
||||
<translation>Move marked files</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="98"/>
|
||||
<source>Index directory</source>
|
||||
<translation>Index directory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="95"/>
|
||||
<source>Set as root</source>
|
||||
<translation>Set as root directory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="102"/>
|
||||
<source>Reset root</source>
|
||||
<translation>Reset root directory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="103"/>
|
||||
<source>Go up</source>
|
||||
<translation>Go up</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="104"/>
|
||||
<source>Show hidden files</source>
|
||||
<translation>Show hidden files</translation>
|
||||
</message>
|
||||
@@ -102,6 +286,7 @@
|
||||
<context>
|
||||
<name>HelpDialog</name>
|
||||
<message>
|
||||
<location filename="../about.cpp" line="33"/>
|
||||
<source>Help</source>
|
||||
<translation>Help</translation>
|
||||
</message>
|
||||
@@ -109,6 +294,7 @@
|
||||
<context>
|
||||
<name>Histogram</name>
|
||||
<message>
|
||||
<location filename="../histogram.cpp" line="72"/>
|
||||
<source>Logarithmic scale</source>
|
||||
<translation>Logarithmic scale</translation>
|
||||
</message>
|
||||
@@ -116,22 +302,27 @@
|
||||
<context>
|
||||
<name>ImageInfo</name>
|
||||
<message>
|
||||
<location filename="../imageinfo.cpp" line="65"/>
|
||||
<source>Property</source>
|
||||
<translation>Property</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imageinfo.cpp" line="65"/>
|
||||
<source>Value</source>
|
||||
<translation>Value</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imageinfo.cpp" line="65"/>
|
||||
<source>Comment</source>
|
||||
<translation>Comment</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imageinfo.cpp" line="82"/>
|
||||
<source>FITS Header</source>
|
||||
<translation>FITS Header</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imageinfo.cpp" line="91"/>
|
||||
<source>Image info</source>
|
||||
<translation>Image info</translation>
|
||||
</message>
|
||||
@@ -139,6 +330,7 @@
|
||||
<context>
|
||||
<name>ImageRingList</name>
|
||||
<message>
|
||||
<location filename="../imageringlist.cpp" line="375"/>
|
||||
<source>Name</source>
|
||||
<translation>Name</translation>
|
||||
</message>
|
||||
@@ -146,284 +338,410 @@
|
||||
<context>
|
||||
<name>ImageWidget</name>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="78"/>
|
||||
<location filename="../imagescrollareagl.cpp" line="447"/>
|
||||
<source>OpenGL error</source>
|
||||
<translation>OpenGL error</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="78"/>
|
||||
<location filename="../imagescrollareagl.cpp" line="447"/>
|
||||
<source>Could not initialize OpenGL 3.3 context. Ensure that proper GPU driver is installed.</source>
|
||||
<translation>Could not initialize OpenGL 3.3 context. Ensure that proper GPU driver is installed.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="674"/>
|
||||
<source>L:%1</source>
|
||||
<translation>L:%1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="674"/>
|
||||
<location filename="../imagescrollareagl.cpp" line="676"/>
|
||||
<source>X:%3 Y:%4</source>
|
||||
<translation>X:%3 Y:%4</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="676"/>
|
||||
<source>R:%1 G:%2 B:%3</source>
|
||||
<translation>R:%1 G:%2 B:%3</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="99"/>
|
||||
<source>Failed to load image</source>
|
||||
<translation>Failed to load image</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="68"/>
|
||||
<source>Image info</source>
|
||||
<translation>Image info</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="77"/>
|
||||
<source>Can't open DB</source>
|
||||
<translation>Can't open DB</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="77"/>
|
||||
<source>Can't open SQLITE database</source>
|
||||
<translation>Can't open SQLITE database</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="110"/>
|
||||
<source>Filesystem</source>
|
||||
<translation>File system</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="134"/>
|
||||
<source>Tenmon</source>
|
||||
<translation>Tenmon</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="145"/>
|
||||
<source>File</source>
|
||||
<translation>File</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="146"/>
|
||||
<source>Open</source>
|
||||
<translation>Open</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="150"/>
|
||||
<source>Copy marked files</source>
|
||||
<translation>Copy marked files</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="148"/>
|
||||
<location filename="../mainwindow.cpp" line="532"/>
|
||||
<location filename="../mainwindow.cpp" line="694"/>
|
||||
<source>Save as</source>
|
||||
<translation>Save as</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="147"/>
|
||||
<location filename="../mainwindow.cpp" line="494"/>
|
||||
<source>Open directory recursively</source>
|
||||
<translation>Open directory recursively</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="157"/>
|
||||
<source>Batch processing</source>
|
||||
<translation>Batch processing</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="163"/>
|
||||
<source>Live mode</source>
|
||||
<translation>Live mode</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="165"/>
|
||||
<source>Exit</source>
|
||||
<translation>Exit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="173"/>
|
||||
<source>View</source>
|
||||
<translation>View</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="174"/>
|
||||
<source>Zoom In</source>
|
||||
<translation>Zoom In</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="175"/>
|
||||
<source>Zoom Out</source>
|
||||
<translation>Zoom Out</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="176"/>
|
||||
<source>Best Fit</source>
|
||||
<translation>Best Fit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="177"/>
|
||||
<source>100%</source>
|
||||
<translation>100%</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="210"/>
|
||||
<source>Select</source>
|
||||
<translation>Select</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="211"/>
|
||||
<source>Mark</source>
|
||||
<translation>Mark</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="212"/>
|
||||
<source>Unmark</source>
|
||||
<translation>Unmark</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="214"/>
|
||||
<source>Mark and next</source>
|
||||
<translation>Mark and next</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="215"/>
|
||||
<source>Unmark and next</source>
|
||||
<translation>Unmark and next</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="219"/>
|
||||
<source>Analyze</source>
|
||||
<translation>Analyze</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="232"/>
|
||||
<source>Image statistics</source>
|
||||
<translation>Image statistics</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="233"/>
|
||||
<source>Peak finder</source>
|
||||
<translation>Peak finder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="244"/>
|
||||
<source>Docks</source>
|
||||
<translation>Docks</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="464"/>
|
||||
<source>Open file</source>
|
||||
<translation>Open file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="378"/>
|
||||
<source>Select destination</source>
|
||||
<translation>Select destination</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="391"/>
|
||||
<source>Copying</source>
|
||||
<translation>Copying</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="391"/>
|
||||
<location filename="../mainwindow.cpp" line="515"/>
|
||||
<location filename="../mainwindow.cpp" line="523"/>
|
||||
<location filename="../mainwindow.cpp" line="634"/>
|
||||
<source>Cancel</source>
|
||||
<translation>Cancel</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="151"/>
|
||||
<source>Move marked files</source>
|
||||
<translation>Move marked files</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="154"/>
|
||||
<location filename="../mainwindow.cpp" line="507"/>
|
||||
<source>Index directory</source>
|
||||
<translation>Index directory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="198"/>
|
||||
<source>Thumbnails</source>
|
||||
<translation>Thumbnails</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="216"/>
|
||||
<source>Show marked</source>
|
||||
<translation>Show marked</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="253"/>
|
||||
<location filename="../mainwindow.cpp" line="254"/>
|
||||
<source>Help</source>
|
||||
<translation>Help</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="255"/>
|
||||
<source>About Tenmon</source>
|
||||
<translation>About Tenmon</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="256"/>
|
||||
<source>About Qt</source>
|
||||
<translation>About Qt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="391"/>
|
||||
<source>Moving</source>
|
||||
<translation>Moving</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="515"/>
|
||||
<location filename="../mainwindow.cpp" line="523"/>
|
||||
<source>Indexing FITS files</source>
|
||||
<translation>Indexing FITS files</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="155"/>
|
||||
<source>Reindex files</source>
|
||||
<translation>Reindex files</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="115"/>
|
||||
<source>FITS/XISF files database</source>
|
||||
<translation>FITS/XISF files database</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="121"/>
|
||||
<source>File tree</source>
|
||||
<translation>File tree</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="234"/>
|
||||
<source>Star finder</source>
|
||||
<translation>Star finder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="169"/>
|
||||
<source>Edit</source>
|
||||
<translation>Edit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="170"/>
|
||||
<source>Settings</source>
|
||||
<translation>Settings</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="49"/>
|
||||
<source>Images (</source>
|
||||
<translation>Images (</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="48"/>
|
||||
<source>FITS (*.fits *.fit);;XISF (*.xisf);;</source>
|
||||
<translation>FITS image (*.fits *.fit);;XISF image (*.xisf);;</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="431"/>
|
||||
<source>Failed to copy</source>
|
||||
<translation>Failed to copy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="431"/>
|
||||
<source>Failed to move</source>
|
||||
<translation>Failed to move</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="432"/>
|
||||
<source>Failed to move from %1 to %2</source>
|
||||
<translation>Failed to move from %1 to %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="432"/>
|
||||
<source>Failed to copy from %1 to %2</source>
|
||||
<translation>Failed to copy from %1 to %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="63"/>
|
||||
<source>;;All files (*)</source>
|
||||
<translation>;;All files (*)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="631"/>
|
||||
<source>Move files to trash?</source>
|
||||
<translation>Move files to trash?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="631"/>
|
||||
<source>Do you want to move %1 files to trash?</source>
|
||||
<translation>Do you want to move %1 files to trash?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="648"/>
|
||||
<source>Failed to move file to trash</source>
|
||||
<translation>Failed to move file to trash</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="648"/>
|
||||
<source>Failed to move file to trash %1</source>
|
||||
<translation>Failed to move file to trash %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="152"/>
|
||||
<source>Move marked files to trash</source>
|
||||
<translation>Move marked files to trash</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="634"/>
|
||||
<source>Moving marked files to trash</source>
|
||||
<translation>Moving marked files to trash</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="156"/>
|
||||
<source>Export database to CSV</source>
|
||||
<translation>Export database to CSV file</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="696"/>
|
||||
<source>CSV file (*.csv)</source>
|
||||
<translation>CSV files (*.csv)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="128"/>
|
||||
<source>Histogram</source>
|
||||
<translation>Histogram</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="179"/>
|
||||
<source>Bayer mask</source>
|
||||
<translation>Bayer mask</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="181"/>
|
||||
<source>RGGB</source>
|
||||
<translation>RGGB</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="182"/>
|
||||
<source>GRBG</source>
|
||||
<translation>GRBG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="183"/>
|
||||
<source>GBRG</source>
|
||||
<translation>GBRG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="184"/>
|
||||
<source>BGGR</source>
|
||||
<translation>BGGR</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="206"/>
|
||||
<source>Slideshow</source>
|
||||
<translation>Slideshow</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MarkedFiles</name>
|
||||
<message>
|
||||
<location filename="../markedfiles.cpp" line="11"/>
|
||||
<source>Marked files</source>
|
||||
<translation>Marked files</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../markedfiles.cpp" line="22"/>
|
||||
<source>Filename</source>
|
||||
<translation>File name</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../markedfiles.cpp" line="30"/>
|
||||
<source>Clear selected</source>
|
||||
<translation>Clear selected</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../markedfiles.cpp" line="31"/>
|
||||
<source>Clear all</source>
|
||||
<translation>Clear all</translation>
|
||||
</message>
|
||||
@@ -431,58 +749,94 @@
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="125"/>
|
||||
<source>ISO</source>
|
||||
<translation>ISO</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="126"/>
|
||||
<source>Shutter speed</source>
|
||||
<translation>Shutter speed</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="123"/>
|
||||
<location filename="../loadrunable.cpp" line="250"/>
|
||||
<location filename="../loadrunable.cpp" line="325"/>
|
||||
<location filename="../loadrunable.cpp" line="509"/>
|
||||
<source>Width</source>
|
||||
<translation>Width</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="124"/>
|
||||
<location filename="../loadrunable.cpp" line="251"/>
|
||||
<location filename="../loadrunable.cpp" line="326"/>
|
||||
<location filename="../loadrunable.cpp" line="510"/>
|
||||
<source>Height</source>
|
||||
<translation>Height</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="241"/>
|
||||
<location filename="../loadrunable.cpp" line="297"/>
|
||||
<location filename="../loadrunable.cpp" line="363"/>
|
||||
<location filename="../loadrunable.cpp" line="382"/>
|
||||
<source>Error</source>
|
||||
<translation>Error</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="378"/>
|
||||
<source>Filename</source>
|
||||
<translation>File name</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="382"/>
|
||||
<source>Failed to load image</source>
|
||||
<translation>Failed to load image</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="392"/>
|
||||
<location filename="../loadrunable.cpp" line="402"/>
|
||||
<source>Mean</source>
|
||||
<translation>Mean</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="393"/>
|
||||
<location filename="../loadrunable.cpp" line="403"/>
|
||||
<source>Standart deviation</source>
|
||||
<translation>Standart deviation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="394"/>
|
||||
<location filename="../loadrunable.cpp" line="404"/>
|
||||
<source>Median</source>
|
||||
<translation>Median</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="395"/>
|
||||
<location filename="../loadrunable.cpp" line="405"/>
|
||||
<source>Minimum</source>
|
||||
<translation>Minimum</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="396"/>
|
||||
<location filename="../loadrunable.cpp" line="406"/>
|
||||
<source>Maximum</source>
|
||||
<translation>Maximum</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="397"/>
|
||||
<location filename="../loadrunable.cpp" line="407"/>
|
||||
<source>MAD</source>
|
||||
<translation>MAD</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="241"/>
|
||||
<location filename="../loadrunable.cpp" line="363"/>
|
||||
<source>Unsupported sample format</source>
|
||||
<translation>Unsupported sample format</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="398"/>
|
||||
<location filename="../loadrunable.cpp" line="408"/>
|
||||
<source>Saturated</source>
|
||||
<translation>Saturated</translation>
|
||||
</message>
|
||||
@@ -490,6 +844,7 @@
|
||||
<context>
|
||||
<name>STFSlider</name>
|
||||
<message>
|
||||
<location filename="../stfslider.cpp" line="41"/>
|
||||
<source>Press Shift for fine tuning</source>
|
||||
<translation>Press Shift for fine tuning</translation>
|
||||
</message>
|
||||
@@ -497,6 +852,7 @@
|
||||
<context>
|
||||
<name>SelectColumnsDialog</name>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="52"/>
|
||||
<source>Select columns</source>
|
||||
<translation>Select columns</translation>
|
||||
</message>
|
||||
@@ -504,71 +860,126 @@
|
||||
<context>
|
||||
<name>SettingsDialog</name>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="38"/>
|
||||
<source>Settings</source>
|
||||
<translation>Settings</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="45"/>
|
||||
<source>How many images are preloaded before and after current image.</source>
|
||||
<translation>How many images are preloaded before and after current image.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="51"/>
|
||||
<source>Thumbnail size in pixels</source>
|
||||
<translation>Thumbnail size in pixels</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="78"/>
|
||||
<source>Image preload count</source>
|
||||
<translation>Image preload count</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="79"/>
|
||||
<source>Thumbnails size</source>
|
||||
<translation>Thumbnails size</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="67"/>
|
||||
<source>Don't use native file dialog</source>
|
||||
<translation>Don't use native file dialog</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="58"/>
|
||||
<source>Set threshold value that is considered saturated when showing statistics.
|
||||
For RAW files you may set 22%</source>
|
||||
<translation>Set threshold value that is considered saturated when showing statistics.
|
||||
For RAW files you may set 22%</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="80"/>
|
||||
<source>Saturation</source>
|
||||
<translation>Saturated</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="71"/>
|
||||
<source>Nearest</source>
|
||||
<translation>Nearest</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="71"/>
|
||||
<source>Linear</source>
|
||||
<translation>Linear</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="71"/>
|
||||
<source>Cubic</source>
|
||||
<translation>Cubic</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="74"/>
|
||||
<source>Smooth thumbnails</source>
|
||||
<translation>Smooth thumbnails</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="76"/>
|
||||
<source>Use box filter when downsampling thumbnails instead of nearest. Slightly slower.</source>
|
||||
<translation>Use box filter when downsampling thumbnails instead of nearest. Slightly slower.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="81"/>
|
||||
<source>Slideshow interval</source>
|
||||
<translation>Slideshow interval</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Image filtering</source>
|
||||
<translation type="obsolete">Image sampling</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="82"/>
|
||||
<source>Image interpolation</source>
|
||||
<translation>Image interpolation</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>StretchToolbar</name>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="18"/>
|
||||
<source>Stretch toolbar</source>
|
||||
<translation>Stretch toolbar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="72"/>
|
||||
<source>Auto Stretch F12</source>
|
||||
<translation>Auto Stretch F12</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="76"/>
|
||||
<source>Reset Screen Transfer Function F11</source>
|
||||
<translation>Reset Screen Transfer Function F11</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="80"/>
|
||||
<source>Invert colors</source>
|
||||
<translation>Invert colors</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="92"/>
|
||||
<source>Apply auto stretch on load</source>
|
||||
<translation>Apply auto stretch on load</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="88"/>
|
||||
<source>Debayer CFA</source>
|
||||
<translation>Debayer CFA</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="84"/>
|
||||
<source>False colors</source>
|
||||
<translation>False colors</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="67"/>
|
||||
<source>Linked channels</source>
|
||||
<translation>Linked channels</translation>
|
||||
</message>
|
||||
|
||||
Binary file not shown.
+413
-2
@@ -1,24 +1,191 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="fr_FR" sourcelanguage="en">
|
||||
<TS version="2.1" language="fr_FR" sourcelanguage="en_US">
|
||||
<context>
|
||||
<name>About</name>
|
||||
<message>
|
||||
<location filename="../about.cpp" line="12"/>
|
||||
<source>About Tenmon</source>
|
||||
<translation>A propos de Tenmon</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>BatchProcessing</name>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="14"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="208"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="208"/>
|
||||
<source>Batch Processing</source>
|
||||
<translation>Traitement par lot</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="22"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="209"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="209"/>
|
||||
<source>Input files and directories</source>
|
||||
<translation>Fichiers et répertoires d'entrée</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="44"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="210"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="210"/>
|
||||
<source>Add files</source>
|
||||
<translation>Ajout de fichiers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="51"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="211"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="211"/>
|
||||
<source>Add directories</source>
|
||||
<translation>Ajout de répertoires</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="58"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="212"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="212"/>
|
||||
<source>Remove</source>
|
||||
<translation>Supprimer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="65"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="213"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="213"/>
|
||||
<source>Remove all</source>
|
||||
<translation>Supprimer tout</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="78"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="214"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="214"/>
|
||||
<source>Output directory</source>
|
||||
<translation>Répertoire de sortie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="92"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="215"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="215"/>
|
||||
<source>Browse</source>
|
||||
<translation>Naviger</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="103"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="216"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="216"/>
|
||||
<source>Scripts</source>
|
||||
<translation>Scripts</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="123"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="217"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="217"/>
|
||||
<source>Open scripts</source>
|
||||
<translation>Ouvrir les scripts</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="142"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="218"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="218"/>
|
||||
<source>Log</source>
|
||||
<translation>Journal</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="182"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="227"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="219"/>
|
||||
<source>Start script</source>
|
||||
<translation>Lancer le script</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="192"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="228"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="220"/>
|
||||
<source>Stop script</source>
|
||||
<translation>Arrêter le script</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="199"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="229"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="221"/>
|
||||
<source>Close</source>
|
||||
<translation>Fermer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="118"/>
|
||||
<source>Interrupt running script?</source>
|
||||
<translation>Interrompre l'execution du script?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="138"/>
|
||||
<source>Select files</source>
|
||||
<translation>Choisir les fichiers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="149"/>
|
||||
<source>Select directory</source>
|
||||
<translation>Choisir le répertoire</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="170"/>
|
||||
<source>Select output directory</source>
|
||||
<translation>Choisir le répertoire de sortie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="212"/>
|
||||
<source>Invalid output directory</source>
|
||||
<translation>Répertoire invalide</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="212"/>
|
||||
<source>Output directory path doesn't exist or is not writable</source>
|
||||
<translation>Le répertoire de sortie n'existe pas ou ne peut pas être écrit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="243"/>
|
||||
<source>Enter text</source>
|
||||
<translation>Entrer le texte</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="250"/>
|
||||
<source>Enter integer number</source>
|
||||
<translation>Entrer un nombre entier</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="257"/>
|
||||
<source>Enter float number</source>
|
||||
<translation>Entrer un nombre flottant</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="264"/>
|
||||
<source>Select item</source>
|
||||
<translation>Choisir l'élément</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="219"/>
|
||||
<source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
hr { height: 1px; border-width: 0; }
|
||||
li.unchecked::marker { content: "\2610"; }
|
||||
li.checked::marker { content: "\2612"; }
|
||||
</style></head><body style=" font-family:'FreeMono'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DataBaseView</name>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="255"/>
|
||||
<source>Select columns</source>
|
||||
<translation>Choix des colonnes</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="293"/>
|
||||
<source>Text to search, you can % as wildcard</source>
|
||||
<translation>Texte à chercher, utilisez % comme caractère générique</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="309"/>
|
||||
<source>Filter</source>
|
||||
<translation>Filtre</translation>
|
||||
</message>
|
||||
@@ -26,10 +193,12 @@
|
||||
<context>
|
||||
<name>DatabaseTableView</name>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="215"/>
|
||||
<source>Mark</source>
|
||||
<translation>Marquer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="216"/>
|
||||
<source>Unmark</source>
|
||||
<translation>Décocher</translation>
|
||||
</message>
|
||||
@@ -37,6 +206,7 @@
|
||||
<context>
|
||||
<name>FITSFileModel</name>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="194"/>
|
||||
<source>File name</source>
|
||||
<translation>Nom de fichier</translation>
|
||||
</message>
|
||||
@@ -44,22 +214,27 @@
|
||||
<context>
|
||||
<name>FilesystemWidget</name>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="26"/>
|
||||
<source>Sort by filename</source>
|
||||
<translation>Trier par nom de fichier</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="27"/>
|
||||
<source>Sort by time</source>
|
||||
<translation>Trier par heure</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="28"/>
|
||||
<source>Sort by size</source>
|
||||
<translation>Trier par taille</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="29"/>
|
||||
<source>Sort by type</source>
|
||||
<translation>Trier par type</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="30"/>
|
||||
<source>Reverse</source>
|
||||
<translation>Ordre inverse</translation>
|
||||
</message>
|
||||
@@ -67,34 +242,43 @@
|
||||
<context>
|
||||
<name>Filetree</name>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="90"/>
|
||||
<location filename="../filesystemwidget.cpp" line="94"/>
|
||||
<source>Open</source>
|
||||
<translation>Ouvrir</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="96"/>
|
||||
<source>Copy marked files</source>
|
||||
<translation>Copier les fichiers marqués</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="97"/>
|
||||
<source>Move marked files</source>
|
||||
<translation>Déplacer les fichiers marqués</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="98"/>
|
||||
<source>Index directory</source>
|
||||
<translation>Indexer le répertoire</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="95"/>
|
||||
<source>Set as root</source>
|
||||
<translation>Définir comme répertoire racine</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="102"/>
|
||||
<source>Reset root</source>
|
||||
<translation>Réinitialiser la racine</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="103"/>
|
||||
<source>Go up</source>
|
||||
<translation>Monter</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="104"/>
|
||||
<source>Show hidden files</source>
|
||||
<translation>Afficher les fichiers cachés</translation>
|
||||
</message>
|
||||
@@ -102,6 +286,7 @@
|
||||
<context>
|
||||
<name>HelpDialog</name>
|
||||
<message>
|
||||
<location filename="../about.cpp" line="33"/>
|
||||
<source>Help</source>
|
||||
<translation>Aide</translation>
|
||||
</message>
|
||||
@@ -109,6 +294,7 @@
|
||||
<context>
|
||||
<name>Histogram</name>
|
||||
<message>
|
||||
<location filename="../histogram.cpp" line="72"/>
|
||||
<source>Logarithmic scale</source>
|
||||
<translation>Échelle logarithmique</translation>
|
||||
</message>
|
||||
@@ -116,22 +302,27 @@
|
||||
<context>
|
||||
<name>ImageInfo</name>
|
||||
<message>
|
||||
<location filename="../imageinfo.cpp" line="65"/>
|
||||
<source>Property</source>
|
||||
<translation>Propriété</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imageinfo.cpp" line="65"/>
|
||||
<source>Value</source>
|
||||
<translation>Valeur</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imageinfo.cpp" line="65"/>
|
||||
<source>Comment</source>
|
||||
<translation>Commentaire</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imageinfo.cpp" line="82"/>
|
||||
<source>FITS Header</source>
|
||||
<translation>En-tête FITS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imageinfo.cpp" line="91"/>
|
||||
<source>Image info</source>
|
||||
<translation>Informations sur l'image</translation>
|
||||
</message>
|
||||
@@ -139,6 +330,7 @@
|
||||
<context>
|
||||
<name>ImageRingList</name>
|
||||
<message>
|
||||
<location filename="../imageringlist.cpp" line="375"/>
|
||||
<source>Name</source>
|
||||
<translation>Nom</translation>
|
||||
</message>
|
||||
@@ -146,284 +338,410 @@
|
||||
<context>
|
||||
<name>ImageWidget</name>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="78"/>
|
||||
<location filename="../imagescrollareagl.cpp" line="447"/>
|
||||
<source>OpenGL error</source>
|
||||
<translation>Erreur OpenGL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="78"/>
|
||||
<location filename="../imagescrollareagl.cpp" line="447"/>
|
||||
<source>Could not initialize OpenGL 3.3 context. Ensure that proper GPU driver is installed.</source>
|
||||
<translation>Impossible d'initialiser le contexte OpenGL 3.3. Assurez-vous que le pilote GPU approprié est installé.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="674"/>
|
||||
<source>L:%1</source>
|
||||
<translation>L:%1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="674"/>
|
||||
<location filename="../imagescrollareagl.cpp" line="676"/>
|
||||
<source>X:%3 Y:%4</source>
|
||||
<translation>X:%3 Y:%4</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="676"/>
|
||||
<source>R:%1 G:%2 B:%3</source>
|
||||
<translation>R:%1 G:%2 B:%3</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="99"/>
|
||||
<source>Failed to load image</source>
|
||||
<translation>Échec du chargement de l'image</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="68"/>
|
||||
<source>Image info</source>
|
||||
<translation>Information sur l'image</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="77"/>
|
||||
<source>Can't open DB</source>
|
||||
<translation>Ne peut ouvrir la base de donnée</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="77"/>
|
||||
<source>Can't open SQLITE database</source>
|
||||
<translation>Ne peut ouvrir la base de donnée SQLITE</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="110"/>
|
||||
<source>Filesystem</source>
|
||||
<translation>Système de fichier</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="134"/>
|
||||
<source>Tenmon</source>
|
||||
<translation>Tenmon</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="145"/>
|
||||
<source>File</source>
|
||||
<translation>Fichier</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="146"/>
|
||||
<source>Open</source>
|
||||
<translation>Ouvrir</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="150"/>
|
||||
<source>Copy marked files</source>
|
||||
<translation>Copier les fichiers marqués</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="148"/>
|
||||
<location filename="../mainwindow.cpp" line="532"/>
|
||||
<location filename="../mainwindow.cpp" line="694"/>
|
||||
<source>Save as</source>
|
||||
<translation>Enregistrer sous</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="147"/>
|
||||
<location filename="../mainwindow.cpp" line="494"/>
|
||||
<source>Open directory recursively</source>
|
||||
<translation>Ouvrir le répertoire de manière récursive</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="157"/>
|
||||
<source>Batch processing</source>
|
||||
<translation>Traitement par lot</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="163"/>
|
||||
<source>Live mode</source>
|
||||
<translation>Mode temps réel</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="165"/>
|
||||
<source>Exit</source>
|
||||
<translation>Sortir</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="173"/>
|
||||
<source>View</source>
|
||||
<translation>Voir</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="174"/>
|
||||
<source>Zoom In</source>
|
||||
<translation>Zoom avant</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="175"/>
|
||||
<source>Zoom Out</source>
|
||||
<translation>Zoom arrière</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="176"/>
|
||||
<source>Best Fit</source>
|
||||
<translation>Meilleur ajustement</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="177"/>
|
||||
<source>100%</source>
|
||||
<translation>100%</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="210"/>
|
||||
<source>Select</source>
|
||||
<translation>Sélectionner</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="211"/>
|
||||
<source>Mark</source>
|
||||
<translation>Marquer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="212"/>
|
||||
<source>Unmark</source>
|
||||
<translation>Décocher</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="214"/>
|
||||
<source>Mark and next</source>
|
||||
<translation>Marquer et suivant</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="215"/>
|
||||
<source>Unmark and next</source>
|
||||
<translation>Décocher et suivant</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="219"/>
|
||||
<source>Analyze</source>
|
||||
<translation>Analyse</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="232"/>
|
||||
<source>Image statistics</source>
|
||||
<translation>Statistiques de l'image</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="233"/>
|
||||
<source>Peak finder</source>
|
||||
<translation>Détecteur de pic</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="244"/>
|
||||
<source>Docks</source>
|
||||
<translation>Fenêtres encrables</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="464"/>
|
||||
<source>Open file</source>
|
||||
<translation>Ouvrir le ficher</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="378"/>
|
||||
<source>Select destination</source>
|
||||
<translation>Choisir la destination</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="391"/>
|
||||
<source>Copying</source>
|
||||
<translation>Copier</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="391"/>
|
||||
<location filename="../mainwindow.cpp" line="515"/>
|
||||
<location filename="../mainwindow.cpp" line="523"/>
|
||||
<location filename="../mainwindow.cpp" line="634"/>
|
||||
<source>Cancel</source>
|
||||
<translation>Abandon</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="151"/>
|
||||
<source>Move marked files</source>
|
||||
<translation>Déplacer les fichiers marqués</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="154"/>
|
||||
<location filename="../mainwindow.cpp" line="507"/>
|
||||
<source>Index directory</source>
|
||||
<translation>Indexer le répertoire</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="198"/>
|
||||
<source>Thumbnails</source>
|
||||
<translation>Vignettes</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="216"/>
|
||||
<source>Show marked</source>
|
||||
<translation>Afficher marqué</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="253"/>
|
||||
<location filename="../mainwindow.cpp" line="254"/>
|
||||
<source>Help</source>
|
||||
<translation>Aide</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="255"/>
|
||||
<source>About Tenmon</source>
|
||||
<translation>A propos de Tenmon</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="256"/>
|
||||
<source>About Qt</source>
|
||||
<translation>A propos de Qt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="391"/>
|
||||
<source>Moving</source>
|
||||
<translation>Déplacement</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="515"/>
|
||||
<location filename="../mainwindow.cpp" line="523"/>
|
||||
<source>Indexing FITS files</source>
|
||||
<translation>Indexation des fichiers FITS</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="155"/>
|
||||
<source>Reindex files</source>
|
||||
<translation>Ré-indexer les fichiers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="115"/>
|
||||
<source>FITS/XISF files database</source>
|
||||
<translation>Base de donnée FITS/XISF</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="121"/>
|
||||
<source>File tree</source>
|
||||
<translation>Arborescence de fichiers</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="234"/>
|
||||
<source>Star finder</source>
|
||||
<translation>Détecteur d'étoiles</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="169"/>
|
||||
<source>Edit</source>
|
||||
<translation>Éditer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="170"/>
|
||||
<source>Settings</source>
|
||||
<translation>Réglages</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="49"/>
|
||||
<source>Images (</source>
|
||||
<translation>Images (</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="48"/>
|
||||
<source>FITS (*.fits *.fit);;XISF (*.xisf);;</source>
|
||||
<translation>FITS image (*.fits *.fit);;XISF image (*.xisf);;</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="431"/>
|
||||
<source>Failed to copy</source>
|
||||
<translation>Échec de la copie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="431"/>
|
||||
<source>Failed to move</source>
|
||||
<translation>Échec du déplacement</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="432"/>
|
||||
<source>Failed to move from %1 to %2</source>
|
||||
<translation>Échec du déplacement de %1 vers %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="432"/>
|
||||
<source>Failed to copy from %1 to %2</source>
|
||||
<translation>Échec de la copie de %1 vers %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="63"/>
|
||||
<source>;;All files (*)</source>
|
||||
<translation>;;Tout les fichiers (*)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="631"/>
|
||||
<source>Move files to trash?</source>
|
||||
<translation>Déplacer les fichiers dans la corbeille?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="631"/>
|
||||
<source>Do you want to move %1 files to trash?</source>
|
||||
<translation>Voulez-vous déplacer le fichier %1 dans la corbeille?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="648"/>
|
||||
<source>Failed to move file to trash</source>
|
||||
<translation>Echec du déplacement dans la corbeille</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="648"/>
|
||||
<source>Failed to move file to trash %1</source>
|
||||
<translation>Echec du déplacement de %1 dans la corbeille</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="152"/>
|
||||
<source>Move marked files to trash</source>
|
||||
<translation>Déplacer les fichiers marqués dans la corbeille</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="634"/>
|
||||
<source>Moving marked files to trash</source>
|
||||
<translation>Déplacement des fichiers marqués dans la corbeille</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="156"/>
|
||||
<source>Export database to CSV</source>
|
||||
<translation>Exporter la base de données vers un fichier CSV</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="696"/>
|
||||
<source>CSV file (*.csv)</source>
|
||||
<translation>Fichiers CSV (*.csv)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="128"/>
|
||||
<source>Histogram</source>
|
||||
<translation>Histogramme</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="179"/>
|
||||
<source>Bayer mask</source>
|
||||
<translation>Masque Bayer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="181"/>
|
||||
<source>RGGB</source>
|
||||
<translation>RGGB</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="182"/>
|
||||
<source>GRBG</source>
|
||||
<translation>GRBG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="183"/>
|
||||
<source>GBRG</source>
|
||||
<translation>GBRG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="184"/>
|
||||
<source>BGGR</source>
|
||||
<translation>BGGR</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="206"/>
|
||||
<source>Slideshow</source>
|
||||
<translation>Diaporama</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MarkedFiles</name>
|
||||
<message>
|
||||
<location filename="../markedfiles.cpp" line="11"/>
|
||||
<source>Marked files</source>
|
||||
<translation>Fichiers marqués</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../markedfiles.cpp" line="22"/>
|
||||
<source>Filename</source>
|
||||
<translation>Nom de fichier</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../markedfiles.cpp" line="30"/>
|
||||
<source>Clear selected</source>
|
||||
<translation>Effacer la sélection</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../markedfiles.cpp" line="31"/>
|
||||
<source>Clear all</source>
|
||||
<translation>Effacer tout</translation>
|
||||
</message>
|
||||
@@ -431,58 +749,94 @@
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="125"/>
|
||||
<source>ISO</source>
|
||||
<translation>ISO</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="126"/>
|
||||
<source>Shutter speed</source>
|
||||
<translation>Vitesse d'obturation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="123"/>
|
||||
<location filename="../loadrunable.cpp" line="250"/>
|
||||
<location filename="../loadrunable.cpp" line="325"/>
|
||||
<location filename="../loadrunable.cpp" line="509"/>
|
||||
<source>Width</source>
|
||||
<translation>Largeur</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="124"/>
|
||||
<location filename="../loadrunable.cpp" line="251"/>
|
||||
<location filename="../loadrunable.cpp" line="326"/>
|
||||
<location filename="../loadrunable.cpp" line="510"/>
|
||||
<source>Height</source>
|
||||
<translation>Hauteur</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="241"/>
|
||||
<location filename="../loadrunable.cpp" line="297"/>
|
||||
<location filename="../loadrunable.cpp" line="363"/>
|
||||
<location filename="../loadrunable.cpp" line="382"/>
|
||||
<source>Error</source>
|
||||
<translation>Erreur</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="378"/>
|
||||
<source>Filename</source>
|
||||
<translation>Nom de fichier</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="382"/>
|
||||
<source>Failed to load image</source>
|
||||
<translation>Échec du chargement de l'image</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="392"/>
|
||||
<location filename="../loadrunable.cpp" line="402"/>
|
||||
<source>Mean</source>
|
||||
<translation>Moyenne</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="393"/>
|
||||
<location filename="../loadrunable.cpp" line="403"/>
|
||||
<source>Standart deviation</source>
|
||||
<translation>Écart-type</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="394"/>
|
||||
<location filename="../loadrunable.cpp" line="404"/>
|
||||
<source>Median</source>
|
||||
<translation>Médiane</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="395"/>
|
||||
<location filename="../loadrunable.cpp" line="405"/>
|
||||
<source>Minimum</source>
|
||||
<translation>Minimum</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="396"/>
|
||||
<location filename="../loadrunable.cpp" line="406"/>
|
||||
<source>Maximum</source>
|
||||
<translation>Maximum</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="397"/>
|
||||
<location filename="../loadrunable.cpp" line="407"/>
|
||||
<source>MAD</source>
|
||||
<translation>MAD</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="241"/>
|
||||
<location filename="../loadrunable.cpp" line="363"/>
|
||||
<source>Unsupported sample format</source>
|
||||
<translation>Format non pris en charge</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="398"/>
|
||||
<location filename="../loadrunable.cpp" line="408"/>
|
||||
<source>Saturated</source>
|
||||
<translation>Saturé</translation>
|
||||
</message>
|
||||
@@ -490,6 +844,7 @@
|
||||
<context>
|
||||
<name>STFSlider</name>
|
||||
<message>
|
||||
<location filename="../stfslider.cpp" line="41"/>
|
||||
<source>Press Shift for fine tuning</source>
|
||||
<translation>Appuyez sur Shift pour un réglage fin</translation>
|
||||
</message>
|
||||
@@ -497,6 +852,7 @@
|
||||
<context>
|
||||
<name>SelectColumnsDialog</name>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="52"/>
|
||||
<source>Select columns</source>
|
||||
<translation>Choix des colonnes</translation>
|
||||
</message>
|
||||
@@ -504,73 +860,128 @@
|
||||
<context>
|
||||
<name>SettingsDialog</name>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="38"/>
|
||||
<source>Settings</source>
|
||||
<translation>Réglages</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="45"/>
|
||||
<source>How many images are preloaded before and after current image.</source>
|
||||
<translation>Combien d'images sont préchargées avant et après l'image courante.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="51"/>
|
||||
<source>Thumbnail size in pixels</source>
|
||||
<translation>Taille des vignettes en pixels</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="78"/>
|
||||
<source>Image preload count</source>
|
||||
<translation>Nombre d'images préchargées</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="79"/>
|
||||
<source>Thumbnails size</source>
|
||||
<translation>Taille des vignette</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="67"/>
|
||||
<source>Don't use native file dialog</source>
|
||||
<translation>N'utilisez pas la boîte de dialogue de fichier natif</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="58"/>
|
||||
<source>Set threshold value that is considered saturated when showing statistics.
|
||||
For RAW files you may set 22%</source>
|
||||
<translation>Définissez la valeur seuil qui est considérée comme saturée lors de l'affichage des statistiques.
|
||||
Pour les fichiers RAW, vous pouvez définir 22 %</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="80"/>
|
||||
<source>Saturation</source>
|
||||
<translation>Saturé</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="71"/>
|
||||
<source>Nearest</source>
|
||||
<translation>Voisin le plus proche</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="71"/>
|
||||
<source>Linear</source>
|
||||
<translation>Linéaire</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="71"/>
|
||||
<source>Cubic</source>
|
||||
<translation>Cubique</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="74"/>
|
||||
<source>Smooth thumbnails</source>
|
||||
<translation>Miniatures fluides</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="76"/>
|
||||
<source>Use box filter when downsampling thumbnails instead of nearest. Slightly slower.</source>
|
||||
<translation>Utilisez un filtre boîte lors du sous-échantillonnage des vignettes au lieu des plus proches. Un peu plus lent.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="81"/>
|
||||
<source>Slideshow interval</source>
|
||||
<translation>Intervalle du diaporama</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Image filtering</source>
|
||||
<translation type="obsolete">Échantillonnage d'images</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="82"/>
|
||||
<source>Image interpolation</source>
|
||||
<translation>Interpolation d'images</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>StretchToolbar</name>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="18"/>
|
||||
<source>Stretch toolbar</source>
|
||||
<translation>Réglage de la luminosité</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="72"/>
|
||||
<source>Auto Stretch F12</source>
|
||||
<translation>Luminosité automatique F12</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="76"/>
|
||||
<source>Reset Screen Transfer Function F11</source>
|
||||
<translation>Réinitialiser la fonction de transfert d'écran F11</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="80"/>
|
||||
<source>Invert colors</source>
|
||||
<translation>Inverser les couleurs</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="92"/>
|
||||
<source>Apply auto stretch on load</source>
|
||||
<translation>Appliquer la luminosité automatiquement au chargement</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="88"/>
|
||||
<source>Debayer CFA</source>
|
||||
<translation>Débayeriser CFA</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="84"/>
|
||||
<source>False colors</source>
|
||||
<translation>Fausses couleurs</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="67"/>
|
||||
<source>Linked channels</source>
|
||||
<translation>Chaînes liées</translation>
|
||||
<translation>Canaux liés</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
||||
Binary file not shown.
+408
-1
@@ -1,24 +1,191 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="sk_SK" sourcelanguage="en">
|
||||
<TS version="2.1" language="sk_SK" sourcelanguage="en_US">
|
||||
<context>
|
||||
<name>About</name>
|
||||
<message>
|
||||
<location filename="../about.cpp" line="12"/>
|
||||
<source>About Tenmon</source>
|
||||
<translation>O Tenmon</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>BatchProcessing</name>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="14"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="208"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="208"/>
|
||||
<source>Batch Processing</source>
|
||||
<translation>Hromadné spracovanie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="22"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="209"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="209"/>
|
||||
<source>Input files and directories</source>
|
||||
<translation>Vstupné súbory a adresáry</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="44"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="210"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="210"/>
|
||||
<source>Add files</source>
|
||||
<translation>Pridať súbory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="51"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="211"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="211"/>
|
||||
<source>Add directories</source>
|
||||
<translation>Pridať adresár</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="58"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="212"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="212"/>
|
||||
<source>Remove</source>
|
||||
<translation>Odstrániť</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="65"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="213"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="213"/>
|
||||
<source>Remove all</source>
|
||||
<translation>Odstrániť všetko</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="78"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="214"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="214"/>
|
||||
<source>Output directory</source>
|
||||
<translation>Výstupný adresár</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="92"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="215"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="215"/>
|
||||
<source>Browse</source>
|
||||
<translation>Vybrať adresár</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="103"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="216"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="216"/>
|
||||
<source>Scripts</source>
|
||||
<translation>Skripty</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="123"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="217"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="217"/>
|
||||
<source>Open scripts</source>
|
||||
<translation>Otvoriť scripty</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="142"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="218"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="218"/>
|
||||
<source>Log</source>
|
||||
<translation>Záznam</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="182"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="227"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="219"/>
|
||||
<source>Start script</source>
|
||||
<translation>Spustiť script</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="192"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="228"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="220"/>
|
||||
<source>Stop script</source>
|
||||
<translation>Zastaviť script</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.ui" line="199"/>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="229"/>
|
||||
<location filename="../build-release/tenmon_autogen/include/ui_batchprocessing.h" line="221"/>
|
||||
<source>Close</source>
|
||||
<translation>Zatvoriť</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="118"/>
|
||||
<source>Interrupt running script?</source>
|
||||
<translation>Prerušiť bežiaci script?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="138"/>
|
||||
<source>Select files</source>
|
||||
<translation>Vybrať súbory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="149"/>
|
||||
<source>Select directory</source>
|
||||
<translation>Vybrať adresár</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="170"/>
|
||||
<source>Select output directory</source>
|
||||
<translation>Vybrať výstupný adresár</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="212"/>
|
||||
<source>Invalid output directory</source>
|
||||
<translation>Neplatný výstupný adresár</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="212"/>
|
||||
<source>Output directory path doesn't exist or is not writable</source>
|
||||
<translation>Vystupný adresár neexistuje alebo sa doňho nedá zapisovať</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="243"/>
|
||||
<source>Enter text</source>
|
||||
<translation>Zadajte text</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="250"/>
|
||||
<source>Enter integer number</source>
|
||||
<translation>Zadajte celé číslo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="257"/>
|
||||
<source>Enter float number</source>
|
||||
<translation>Zadajte reálne číslo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../batchprocessing.cpp" line="264"/>
|
||||
<source>Select item</source>
|
||||
<translation>Vyberte položku</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../build-debug/tenmon_autogen/include/ui_batchprocessing.h" line="219"/>
|
||||
<source><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
hr { height: 1px; border-width: 0; }
|
||||
li.unchecked::marker { content: "\2610"; }
|
||||
li.checked::marker { content: "\2612"; }
|
||||
</style></head><body style=" font-family:'FreeMono'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DataBaseView</name>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="255"/>
|
||||
<source>Select columns</source>
|
||||
<translation>Vyber stĺpce</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="293"/>
|
||||
<source>Text to search, you can % as wildcard</source>
|
||||
<translation>Text na vyhľadanie, môžete použit % ako zástupný znak</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="309"/>
|
||||
<source>Filter</source>
|
||||
<translatorcomment>Meno súboru</translatorcomment>
|
||||
<translation>Filter</translation>
|
||||
@@ -27,10 +194,12 @@
|
||||
<context>
|
||||
<name>DatabaseTableView</name>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="215"/>
|
||||
<source>Mark</source>
|
||||
<translation>Označiť</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="216"/>
|
||||
<source>Unmark</source>
|
||||
<translation>Odznačiť</translation>
|
||||
</message>
|
||||
@@ -38,6 +207,7 @@
|
||||
<context>
|
||||
<name>FITSFileModel</name>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="194"/>
|
||||
<source>File name</source>
|
||||
<translation>Meno súboru</translation>
|
||||
</message>
|
||||
@@ -45,22 +215,27 @@
|
||||
<context>
|
||||
<name>FilesystemWidget</name>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="26"/>
|
||||
<source>Sort by filename</source>
|
||||
<translation>Zoradiť podľa názvu súboru</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="27"/>
|
||||
<source>Sort by time</source>
|
||||
<translation>Zoradiť podľa času</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="28"/>
|
||||
<source>Sort by size</source>
|
||||
<translation>Zoradiť podľa veľkosti</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="29"/>
|
||||
<source>Sort by type</source>
|
||||
<translation>Zoradiť podľa typu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="30"/>
|
||||
<source>Reverse</source>
|
||||
<translation>Otočit poradie</translation>
|
||||
</message>
|
||||
@@ -68,34 +243,43 @@
|
||||
<context>
|
||||
<name>Filetree</name>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="90"/>
|
||||
<location filename="../filesystemwidget.cpp" line="94"/>
|
||||
<source>Open</source>
|
||||
<translation>Otvoriť</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="96"/>
|
||||
<source>Copy marked files</source>
|
||||
<translation>Skopírovať označené súbory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="97"/>
|
||||
<source>Move marked files</source>
|
||||
<translation>Presunúť označené súbory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="98"/>
|
||||
<source>Index directory</source>
|
||||
<translation>Indexovať adresár</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="95"/>
|
||||
<source>Set as root</source>
|
||||
<translation>Nastav koreňový adresár</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="102"/>
|
||||
<source>Reset root</source>
|
||||
<translation>Resetuj koreňový adresár</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="103"/>
|
||||
<source>Go up</source>
|
||||
<translation>O úroveň vyššie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../filesystemwidget.cpp" line="104"/>
|
||||
<source>Show hidden files</source>
|
||||
<translation>Zobraz skryté súbory</translation>
|
||||
</message>
|
||||
@@ -103,6 +287,7 @@
|
||||
<context>
|
||||
<name>HelpDialog</name>
|
||||
<message>
|
||||
<location filename="../about.cpp" line="33"/>
|
||||
<source>Help</source>
|
||||
<translation>Pomoc</translation>
|
||||
</message>
|
||||
@@ -110,6 +295,7 @@
|
||||
<context>
|
||||
<name>Histogram</name>
|
||||
<message>
|
||||
<location filename="../histogram.cpp" line="72"/>
|
||||
<source>Logarithmic scale</source>
|
||||
<translation>Logaritmická stupnica</translation>
|
||||
</message>
|
||||
@@ -117,22 +303,27 @@
|
||||
<context>
|
||||
<name>ImageInfo</name>
|
||||
<message>
|
||||
<location filename="../imageinfo.cpp" line="65"/>
|
||||
<source>Property</source>
|
||||
<translation>Vlastnosť</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imageinfo.cpp" line="65"/>
|
||||
<source>Value</source>
|
||||
<translation>Hodnota</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imageinfo.cpp" line="65"/>
|
||||
<source>Comment</source>
|
||||
<translation>Komentár</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imageinfo.cpp" line="82"/>
|
||||
<source>FITS Header</source>
|
||||
<translation>FITS hlavička</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imageinfo.cpp" line="91"/>
|
||||
<source>Image info</source>
|
||||
<translation>Informácie o obrázku</translation>
|
||||
</message>
|
||||
@@ -140,6 +331,7 @@
|
||||
<context>
|
||||
<name>ImageRingList</name>
|
||||
<message>
|
||||
<location filename="../imageringlist.cpp" line="375"/>
|
||||
<source>Name</source>
|
||||
<translation>Meno</translation>
|
||||
</message>
|
||||
@@ -147,284 +339,410 @@
|
||||
<context>
|
||||
<name>ImageWidget</name>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="78"/>
|
||||
<location filename="../imagescrollareagl.cpp" line="447"/>
|
||||
<source>OpenGL error</source>
|
||||
<translation>OpenGL chyba</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="78"/>
|
||||
<location filename="../imagescrollareagl.cpp" line="447"/>
|
||||
<source>Could not initialize OpenGL 3.3 context. Ensure that proper GPU driver is installed.</source>
|
||||
<translation>Nepodarilo sa incializovať OpenGL 3.3 context. Ubezpečte sa že sú nainštalované ovládače pre GPU.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="674"/>
|
||||
<source>L:%1</source>
|
||||
<translation>L:%1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="674"/>
|
||||
<location filename="../imagescrollareagl.cpp" line="676"/>
|
||||
<source>X:%3 Y:%4</source>
|
||||
<translation>X:%3 Y:%4</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="676"/>
|
||||
<source>R:%1 G:%2 B:%3</source>
|
||||
<translation>R:%1 G:%2 B:%3</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../imagescrollareagl.cpp" line="99"/>
|
||||
<source>Failed to load image</source>
|
||||
<translation>Zlyhalo načítanie obrázka</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="68"/>
|
||||
<source>Image info</source>
|
||||
<translation>Informácie o obrázku</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="77"/>
|
||||
<source>Can't open DB</source>
|
||||
<translation>Nie je možné otvoriť DB</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="77"/>
|
||||
<source>Can't open SQLITE database</source>
|
||||
<translation>Nie je možné otvoriť SQLITE databázu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="110"/>
|
||||
<source>Filesystem</source>
|
||||
<translation>Zoznam súborov</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="134"/>
|
||||
<source>Tenmon</source>
|
||||
<translation>Tenmon</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="145"/>
|
||||
<source>File</source>
|
||||
<translation>Súbor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="146"/>
|
||||
<source>Open</source>
|
||||
<translation>Otvoriť</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="150"/>
|
||||
<source>Copy marked files</source>
|
||||
<translation>Skopírovať označené súbory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="148"/>
|
||||
<location filename="../mainwindow.cpp" line="532"/>
|
||||
<location filename="../mainwindow.cpp" line="694"/>
|
||||
<source>Save as</source>
|
||||
<translation>Uložiť ako</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="147"/>
|
||||
<location filename="../mainwindow.cpp" line="494"/>
|
||||
<source>Open directory recursively</source>
|
||||
<translation>Otvoriť adresár rekurzívne</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="157"/>
|
||||
<source>Batch processing</source>
|
||||
<translation>Hromadné spracovanie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="165"/>
|
||||
<source>Exit</source>
|
||||
<translation>Ukončiť</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="173"/>
|
||||
<source>View</source>
|
||||
<translation>Zobrazenie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="174"/>
|
||||
<source>Zoom In</source>
|
||||
<translation>Priblížiť</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="175"/>
|
||||
<source>Zoom Out</source>
|
||||
<translation>Oddialiť</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="176"/>
|
||||
<source>Best Fit</source>
|
||||
<translation>Najlepšia veľkosť</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="177"/>
|
||||
<source>100%</source>
|
||||
<translation>100%</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="210"/>
|
||||
<source>Select</source>
|
||||
<translation>Výber</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="211"/>
|
||||
<source>Mark</source>
|
||||
<translation>Označiť</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="212"/>
|
||||
<source>Unmark</source>
|
||||
<translation>Odznačiť</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="214"/>
|
||||
<source>Mark and next</source>
|
||||
<translation>Označiť a ďaľší</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="215"/>
|
||||
<source>Unmark and next</source>
|
||||
<translation>Odznačiť a ďaľší</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="219"/>
|
||||
<source>Analyze</source>
|
||||
<translation>Analýza</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="232"/>
|
||||
<source>Image statistics</source>
|
||||
<translation>Štatistiky obrázka</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="244"/>
|
||||
<source>Docks</source>
|
||||
<translation>Dokovacie panely</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="464"/>
|
||||
<source>Open file</source>
|
||||
<translation>Otvoriť súbor</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="378"/>
|
||||
<source>Select destination</source>
|
||||
<translation>Vybrať cieľ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="391"/>
|
||||
<source>Copying</source>
|
||||
<translation>Kopírovanie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="391"/>
|
||||
<location filename="../mainwindow.cpp" line="515"/>
|
||||
<location filename="../mainwindow.cpp" line="523"/>
|
||||
<location filename="../mainwindow.cpp" line="634"/>
|
||||
<source>Cancel</source>
|
||||
<translation>Zrušiť</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="151"/>
|
||||
<source>Move marked files</source>
|
||||
<translation>Presunúť označené súbory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="154"/>
|
||||
<location filename="../mainwindow.cpp" line="507"/>
|
||||
<source>Index directory</source>
|
||||
<translation>Indexovať adresár</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="163"/>
|
||||
<source>Live mode</source>
|
||||
<translation>Živý mód</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="198"/>
|
||||
<source>Thumbnails</source>
|
||||
<translation>Náhľady</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="216"/>
|
||||
<source>Show marked</source>
|
||||
<translation>Ukázať označené</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="233"/>
|
||||
<source>Peak finder</source>
|
||||
<translation>Vyhľadávač vrcholov</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="253"/>
|
||||
<location filename="../mainwindow.cpp" line="254"/>
|
||||
<source>Help</source>
|
||||
<translation>Pomoc</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="255"/>
|
||||
<source>About Tenmon</source>
|
||||
<translation>O Tenmon</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="256"/>
|
||||
<source>About Qt</source>
|
||||
<translation>O Qt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="391"/>
|
||||
<source>Moving</source>
|
||||
<translation>Presúvanie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="515"/>
|
||||
<location filename="../mainwindow.cpp" line="523"/>
|
||||
<source>Indexing FITS files</source>
|
||||
<translation>Indexovanie FITS/XISF súborov</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="155"/>
|
||||
<source>Reindex files</source>
|
||||
<translation>Reindexuj súbory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="115"/>
|
||||
<source>FITS/XISF files database</source>
|
||||
<translation>Databáza FITS/XISF súborov</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="121"/>
|
||||
<source>File tree</source>
|
||||
<translation>Strom súborov</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="234"/>
|
||||
<source>Star finder</source>
|
||||
<translation>Vyhľadávač hviezd</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="169"/>
|
||||
<source>Edit</source>
|
||||
<translation>Upraviť</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="170"/>
|
||||
<source>Settings</source>
|
||||
<translation>Nastavenia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="49"/>
|
||||
<source>Images (</source>
|
||||
<translation>Obrázky (</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="48"/>
|
||||
<source>FITS (*.fits *.fit);;XISF (*.xisf);;</source>
|
||||
<translation>Obrázok FITS (*.fits *.fit);;Obrázok XISF (*.xisf);;</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="431"/>
|
||||
<source>Failed to copy</source>
|
||||
<translation>Zlyhalo kopírovanie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="431"/>
|
||||
<source>Failed to move</source>
|
||||
<translation>Zlyhalo presúvanie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="432"/>
|
||||
<source>Failed to move from %1 to %2</source>
|
||||
<translation>Zlyhalo presúvanie z %1 do %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="432"/>
|
||||
<source>Failed to copy from %1 to %2</source>
|
||||
<translation>Zlyhalo kopírovanie z %1 do %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="63"/>
|
||||
<source>;;All files (*)</source>
|
||||
<translation>;;Všetky súbory (*)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="631"/>
|
||||
<source>Move files to trash?</source>
|
||||
<translation>Presunúť súbory do koša?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="631"/>
|
||||
<source>Do you want to move %1 files to trash?</source>
|
||||
<translation>Presunúť %1 súborov do koša?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="648"/>
|
||||
<source>Failed to move file to trash</source>
|
||||
<translation>Zlyhalo presunutie súbora do koša</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="648"/>
|
||||
<source>Failed to move file to trash %1</source>
|
||||
<translation>Zlyhalo presunutie súbora do koša %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="152"/>
|
||||
<source>Move marked files to trash</source>
|
||||
<translation>Presunúť označené súbory do koša</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="634"/>
|
||||
<source>Moving marked files to trash</source>
|
||||
<translation>Presúvanie do koša</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="156"/>
|
||||
<source>Export database to CSV</source>
|
||||
<translation>Exportovať databázu do CSV súboru</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="696"/>
|
||||
<source>CSV file (*.csv)</source>
|
||||
<translation>Súbory CSV (*.csv)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="128"/>
|
||||
<source>Histogram</source>
|
||||
<translation>Histogram</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="179"/>
|
||||
<source>Bayer mask</source>
|
||||
<translation>Bayerova maska</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="181"/>
|
||||
<source>RGGB</source>
|
||||
<translation>RGGB</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="182"/>
|
||||
<source>GRBG</source>
|
||||
<translation>GRBG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="183"/>
|
||||
<source>GBRG</source>
|
||||
<translation>GBRG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="184"/>
|
||||
<source>BGGR</source>
|
||||
<translation>BGGR</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../mainwindow.cpp" line="206"/>
|
||||
<source>Slideshow</source>
|
||||
<translation>Prezentácia</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MarkedFiles</name>
|
||||
<message>
|
||||
<location filename="../markedfiles.cpp" line="11"/>
|
||||
<source>Marked files</source>
|
||||
<translation>Označené súbory</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../markedfiles.cpp" line="22"/>
|
||||
<source>Filename</source>
|
||||
<translation>Meno súboru</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../markedfiles.cpp" line="30"/>
|
||||
<source>Clear selected</source>
|
||||
<translation>Zrušiť vybrané</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../markedfiles.cpp" line="31"/>
|
||||
<source>Clear all</source>
|
||||
<translation>Zrušiť všetky</translation>
|
||||
</message>
|
||||
@@ -432,58 +750,94 @@
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="125"/>
|
||||
<source>ISO</source>
|
||||
<translation>ISO</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="126"/>
|
||||
<source>Shutter speed</source>
|
||||
<translation>Rýchlosť uzávierky</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="241"/>
|
||||
<location filename="../loadrunable.cpp" line="297"/>
|
||||
<location filename="../loadrunable.cpp" line="363"/>
|
||||
<location filename="../loadrunable.cpp" line="382"/>
|
||||
<source>Error</source>
|
||||
<translation>Chyba</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="241"/>
|
||||
<location filename="../loadrunable.cpp" line="363"/>
|
||||
<source>Unsupported sample format</source>
|
||||
<translation>Nepodporovaný formát</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="123"/>
|
||||
<location filename="../loadrunable.cpp" line="250"/>
|
||||
<location filename="../loadrunable.cpp" line="325"/>
|
||||
<location filename="../loadrunable.cpp" line="509"/>
|
||||
<source>Width</source>
|
||||
<translation>Šírka</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="124"/>
|
||||
<location filename="../loadrunable.cpp" line="251"/>
|
||||
<location filename="../loadrunable.cpp" line="326"/>
|
||||
<location filename="../loadrunable.cpp" line="510"/>
|
||||
<source>Height</source>
|
||||
<translation>Výška</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="378"/>
|
||||
<source>Filename</source>
|
||||
<translation>Meno súboru</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="382"/>
|
||||
<source>Failed to load image</source>
|
||||
<translation>Zlyhalo načítanie obrázka</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="392"/>
|
||||
<location filename="../loadrunable.cpp" line="402"/>
|
||||
<source>Mean</source>
|
||||
<translation>Priemer</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="393"/>
|
||||
<location filename="../loadrunable.cpp" line="403"/>
|
||||
<source>Standart deviation</source>
|
||||
<translation>Štandardná odchýlka</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="394"/>
|
||||
<location filename="../loadrunable.cpp" line="404"/>
|
||||
<source>Median</source>
|
||||
<translation>Medián</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="395"/>
|
||||
<location filename="../loadrunable.cpp" line="405"/>
|
||||
<source>Minimum</source>
|
||||
<translation>Minimum</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="396"/>
|
||||
<location filename="../loadrunable.cpp" line="406"/>
|
||||
<source>Maximum</source>
|
||||
<translation>Maximum</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="397"/>
|
||||
<location filename="../loadrunable.cpp" line="407"/>
|
||||
<source>MAD</source>
|
||||
<translation>MAD</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../loadrunable.cpp" line="398"/>
|
||||
<location filename="../loadrunable.cpp" line="408"/>
|
||||
<source>Saturated</source>
|
||||
<translation>Saturované</translation>
|
||||
</message>
|
||||
@@ -491,6 +845,7 @@
|
||||
<context>
|
||||
<name>STFSlider</name>
|
||||
<message>
|
||||
<location filename="../stfslider.cpp" line="41"/>
|
||||
<source>Press Shift for fine tuning</source>
|
||||
<translation>Stlačte Shift pre jemné ladenie</translation>
|
||||
</message>
|
||||
@@ -498,6 +853,7 @@
|
||||
<context>
|
||||
<name>SelectColumnsDialog</name>
|
||||
<message>
|
||||
<location filename="../databaseview.cpp" line="52"/>
|
||||
<source>Select columns</source>
|
||||
<translation>Výber stĺpcov</translation>
|
||||
</message>
|
||||
@@ -505,71 +861,122 @@
|
||||
<context>
|
||||
<name>SettingsDialog</name>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="38"/>
|
||||
<source>Settings</source>
|
||||
<translation>Nastavenia</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="45"/>
|
||||
<source>How many images are preloaded before and after current image.</source>
|
||||
<translation>Koľko obrázkov sa prednačíta pred a za aktuálnym obrázkom.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="51"/>
|
||||
<source>Thumbnail size in pixels</source>
|
||||
<translation>Veľkosť náhľadu v pixeloch</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="78"/>
|
||||
<source>Image preload count</source>
|
||||
<translation>Počet prednačítaných obrázkov</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="79"/>
|
||||
<source>Thumbnails size</source>
|
||||
<translation>Veľkosť náhľadu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="67"/>
|
||||
<source>Don't use native file dialog</source>
|
||||
<translation>Nepoužívať natívny súborový dialóg</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="58"/>
|
||||
<source>Set threshold value that is considered saturated when showing statistics.
|
||||
For RAW files you may set 22%</source>
|
||||
<translation>Nastavuje prahovú hodnotu ktorá sa považuje za saturovanú.
|
||||
Pre RAW súbory možno treba nastaviť 22%</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="80"/>
|
||||
<source>Saturation</source>
|
||||
<translation>Saturované</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="71"/>
|
||||
<source>Nearest</source>
|
||||
<translation>Žiadna</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="71"/>
|
||||
<source>Linear</source>
|
||||
<translation>Lineárna</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="71"/>
|
||||
<source>Cubic</source>
|
||||
<translation>Kubická</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="74"/>
|
||||
<source>Smooth thumbnails</source>
|
||||
<translation>Hladké náhľady</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="76"/>
|
||||
<source>Use box filter when downsampling thumbnails instead of nearest. Slightly slower.</source>
|
||||
<translation>Pri zemnšovaní obrázkov na náhľady sa pixely spriemerujú namiesto najblžšej hodnoty. Trocha pomalšie.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="81"/>
|
||||
<source>Slideshow interval</source>
|
||||
<translation>Interval medzi obrázkami</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settingsdialog.cpp" line="82"/>
|
||||
<source>Image interpolation</source>
|
||||
<translation>Interpolácia obrázku</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>StretchToolbar</name>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="18"/>
|
||||
<source>Stretch toolbar</source>
|
||||
<translation>Panel úrovní</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="72"/>
|
||||
<source>Auto Stretch F12</source>
|
||||
<translation>Automatické natiahnutie F12</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="76"/>
|
||||
<source>Reset Screen Transfer Function F11</source>
|
||||
<translation>Resetuj funkciu prevodu na obrazovku F11</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="80"/>
|
||||
<source>Invert colors</source>
|
||||
<translation>Invertuj farby</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="92"/>
|
||||
<source>Apply auto stretch on load</source>
|
||||
<translation>Aplikuj automatické natiahnutie pri načítaní</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="88"/>
|
||||
<source>Debayer CFA</source>
|
||||
<translation>Preveď CFA na farbu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="84"/>
|
||||
<source>False colors</source>
|
||||
<translation>Falošné farby</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../stretchtoolbar.cpp" line="67"/>
|
||||
<source>Linked channels</source>
|
||||
<translation>Prepojené kanály</translation>
|
||||
</message>
|
||||
|
||||
Reference in New Issue
Block a user