Avant d’utiliser Digikam, il est plus facile de supprimer les images identiques via un simple script :
find Images/ -type f -exec md5sum '{}' ';' | sort | uniq --all-repeated=separate -w 15 > dupes.txt
awk '/^$/{getline;print;}' dupes.txt | awk '{print $2 " " $3 " " $4}' | xargs gvfs-trash {}
Il est aussi possible d’utiliser :
fdupes -rSm Images
L’option -d permet la suppression.
Ensuite on peut utiliser Digikam, qui lui permet de reconnaitre des images identiques mais n’ayant pas la même taille.
J’ai amélorié ( voir : https://www.cyber-neurones.org/2020/03/thunderbird-mbox-to-influxdb-and-postgresql-to-grafana-in-python/ ) le programme afin d’injecter sur MySQL ( MariaDB en vérité ). Le plus facile a manipuler sur Grafana c’est MariaDB.
Pour se connecter de Grafana à MariaDB :
SELECT
UNIX_TIMESTAMP(date) AS time_sec,
domain as ‘metric’,
count(domain) as value
FROM thunderbird
WHERE
$__timeFilter(date)
GROUP BY DAY(date),MONTH(date),YEAR(date)
ORDER BY date
Par mois :SELECT
UNIX_TIMESTAMP(date) AS time_sec,
domain as ‘metric’,
count(domain) as value
FROM thunderbird
WHERE
$__timeFilter(date)
GROUP BY MONTH(date),YEAR(date)
ORDER BY date
Par années :SELECT
UNIX_TIMESTAMP(date) AS time_sec,
domain as ‘metric’,
count(domain) as value
FROM thunderbird
WHERE
$__timeFilter(date)
GROUP BY YEAR(date)
ORDER BY date
( Source sur : https://github.com/farias06/Python/blob/master/parse_email_v2.py )
J’ai donc fait un programme en python afin de faire un export des données de Thunderbird ( fichier mbox contenant les emails) vers Influxdb et Postgresql (dans un premier temps).
Le but du programme est de maitriser le python afin de faire ensuite des exports vers Grafana. Sur mes exemples j’ai mis en login/password arias/arias (je sais c’est pas secure mais c’est un exemple …).
( Source disponible ici : https://github.com/farias06/Python/blob/master/parse_email.py )
J’ai donc installé le soft :
$ uname -r
5.3.0-40-generic
$ sudo apt-get install garmin-forerunner-tools
...
$ sudo dpkg-query -l | grep garmin-forerunner-tools
ii garmin-forerunner-tools 0.10repacked-10 amd64 retrieve data from Garmin Forerunner/Edge GPS devices
Ensuite j’ai connecté ma montre :
$ lsusb
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 04f2:b649 Chicony Electronics Co., Ltd
Bus 001 Device 009: ID 091e:4c29 Garmin International
Bus 001 Device 004: ID 8087:0025 Intel Corp.
Bus 001 Device 006: ID 062a:4106 Creative Labs
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Par contre les commandes ne fonctionnent pas :
Michel, je te sais tout patraque depuis que tu as vu une série d’articles indiquant que Débian avait plus de faille que Windows:
La liste des failles de Débian est ici : https://www.cvedetails.com/vendor/23/Debian.html .
J’ai donc testé le script suivant : https://github.com/myspaghetti/macos-guest-virtualbox : macos-guest-virtualbox . Le but du script est de faire une machine Virtuel sous Ubuntu. A noter que le déroulement du script est très long, je pense qu’il faut compter 4 heures.
Voici tous le process d’installation :
# wget -q https://www.virtualbox.org/download/oracle_vbox_2016.asc -O- | sudo apt-key add -
# wget -q https://www.virtualbox.org/download/oracle_vbox.asc -O- | sudo apt-key add -
# sudo add-apt-repository "deb http://download.virtualbox.org/virtualbox/debian bionic contrib"
# sudo apt update
# sudo apt install virtualbox-6.1 virtualbox-dkms
# sudo apt install libcanberra-gtk-module libcanberra-gtk3-module
# sudo apt-get install dmg2img
Il est impératif d’avoir une version de virtualbox > 6.1. Par défaut sur Ubuntu on a la version 5.0 …
Je ne comprends pas pourquoi j’ai autant de SWAP avec ma configuration de swappiness :
$ swapon -s
Filename Type Size Used Priority
/dev/sda3 partition 8388604 924672 -2
$ cat /proc/sys/vm/swappiness
1
$ cat /proc/sys/vm/vfs_cache_pressure
100
$ getconf PAGESIZE
4096
$ cat /etc/os-release | grep "PRETTY_NAME"
PRETTY_NAME="Ubuntu 18.04.3 LTS"
$ free -m
total used free shared buff/cache available
Mem: 64081 4045 8756 506 51279 58818
Swap: 8191 903 7288
Quand je regarde la documentation, vu que j’ai 64 Go de RAM je ne devrais pas avoir de SWAP :
J’ai fait une petite lecture des tables de Dikikam afin de faire un export des images similaires avec un taux à 1.0 :
$ sqlite3
SQLite version 3.22.0 2018-01-22 18:45:57
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .open similarity.db
sqlite> .tables
ImageHaarMatrix ImageSimilarity SimilaritySettings
sqlite> .schema ImageSimilarity
CREATE TABLE ImageSimilarity
(imageid1 INTEGER NOT NULL,
imageid2 INTEGER NOT NULL,
algorithm INTEGER,
value DOUBLE,
CONSTRAINT Similar UNIQUE(imageid1, imageid2, algorithm));
sqlite> .schema ImageHaarMatrix
CREATE TABLE ImageHaarMatrix
(imageid INTEGER PRIMARY KEY,
modificationDate DATETIME,
uniqueHash TEXT,
matrix BLOB);
CREATE TRIGGER delete_similarities DELETE ON ImageHaarMatrix
BEGIN
DELETE FROM ImageSimilarity
WHERE ( ImageSimilarity.imageid1=OLD.imageid OR ImageSimilarity.imageid2=OLD.imageid )
AND ( ImageSimilarity.algorithm=1 );
END;
sqlite> .schema SimilaritySettings
CREATE TABLE SimilaritySettings
(keyword TEXT NOT NULL UNIQUE,
value TEXT);
sqlite> .open digikam4.db
sqlite> .tables
AlbumRoots ImageHistory ImageRelations Settings
Albums ImageInformation ImageTagProperties TagProperties
DownloadHistory ImageMetadata ImageTags Tags
ImageComments ImagePositions Images TagsTree
ImageCopyright ImageProperties Searches VideoMetadata
sqlite> .schema Images
CREATE TABLE Images
(id INTEGER PRIMARY KEY,
album INTEGER,
name TEXT NOT NULL,
status INTEGER NOT NULL,
category INTEGER NOT NULL,
modificationDate DATETIME,
fileSize INTEGER,
uniqueHash TEXT,
manualOrder INTEGER,
UNIQUE (album, name));
CREATE INDEX dir_index ON Images (album);
CREATE INDEX hash_index ON Images (uniqueHash);
CREATE INDEX image_name_index ON Images (name);
CREATE TRIGGER delete_image DELETE ON Images
BEGIN
DELETE FROM ImageTags WHERE imageid=OLD.id;
DELETE From ImageInformation WHERE imageid=OLD.id;
DELETE From ImageMetadata WHERE imageid=OLD.id;
DELETE From VideoMetadata WHERE imageid=OLD.id;
DELETE From ImagePositions WHERE imageid=OLD.id;
DELETE From ImageComments WHERE imageid=OLD.id;
DELETE From ImageCopyright WHERE imageid=OLD.id;
DELETE From ImageProperties WHERE imageid=OLD.id;
DELETE From ImageHistory WHERE imageid=OLD.id;
DELETE FROM ImageRelations WHERE subject=OLD.id OR object=OLD.id;
DELETE FROM ImageTagProperties WHERE imageid=OLD.id;
UPDATE Albums SET icon=null WHERE icon=OLD.id;
UPDATE Tags SET icon=null WHERE icon=OLD.id;
END;
sqlite> .schema ImageInformation
CREATE TABLE ImageInformation
(imageid INTEGER PRIMARY KEY,
rating INTEGER,
creationDate DATETIME,
digitizationDate DATETIME,
orientation INTEGER,
width INTEGER,
height INTEGER,
format TEXT,
colorDepth INTEGER,
colorModel INTEGER);
CREATE INDEX creationdate_index ON ImageInformation (creationDate);
sqlite> .schema Albums
CREATE TABLE Albums
(id INTEGER PRIMARY KEY,
albumRoot INTEGER NOT NULL,
relativePath TEXT NOT NULL,
date DATE,
caption TEXT,
collection TEXT,
icon INTEGER,
UNIQUE(albumRoot, relativePath));
CREATE TRIGGER delete_album DELETE ON Albums
BEGIN
DELETE FROM Images
WHERE Images.album = OLD.id;
END;
sqlite> attach 'digikam4.db' as db1;
sqlite> attach 'similarity.db' as db2;
sqlite> select count(*) from db1.Images as A, db2.ImageSimilarity as B, db1.Albums as C where B.imageid2 = A.id and B.algorithm = 1.0 and A.album = C.id;
36796
sqlite> select relativePath || '/' || name from db1.Images as A, db2.ImageSimilarity as B, db1.Albums as C where B.imageid2 = A.id and B.algorithm = 1.0 and A.album = C.id group by relativePath;
...
sqlite> .output file_duplicate.txt
sqlite> select '.' || relativePath || '/' || name from db1.Images as A, db2.ImageSimilarity as B, db1.Albums as C where B.imageid2 = A.id and B.algorithm = 1.0 and A.album = C.id group by relativePath;
sqlite> select count(*) from db1.Images as A, db2.ImageSimilarity as B, db1.Albums as C where B.imageid2 = A.id and A.album = C.id and relativePath = '/2019/11/28';
654
sqlite> select count(*) from db1.Images as A, db2.ImageSimilarity as B, db1.Albums as C where B.imageid1 = A.id and A.album = C.id and relativePath = '/2019/11/28';
2545
sqlite> .output file_duplicate_2.txt
sqlite> select '.' || relativePath || '/' || name from db1.Images as A, db2.ImageSimilarity as B, db1.Albums as C where B.imageid2 = A.id and B.algorithm > 0.96 and A.album = C.id;
sqlite> .output file_duplicate_3.txt
sqlite> select '.' || relativePath || '/' || name from db1.Images as A, db2.ImageSimilarity as B, db1.Albums as C where B.imageid1 = A.id and B.algorithm > 0.96 and A.album = C.id;
sqlite> .quit
Ensuite pour la suppression j’ai fait :
Sous Mac OS j’avais fait plusieurs articles …Mais sous Ubuntu c’est plus simple, voici les commandes que j’utilise :
$ du -sh Images/
$ find Images/ -iname '*.jpg' -exec mogrify \{} -verbose -resize 1920x1080\> \{} \;
$
Je considère que la résolution max est 1920x1080 (on peut aussi prendre 2048x1536). Il est vivement conseillé d’avoir un backup avant de lancer les commandes. Et je vous conseille cette lecture : https://fr.wikipedia.org/wiki/Impression_photo_num%C3%A9rique
A noter aussi que je déplace toutes les vidéos avant de lancer la commandes :
Suite à la compression via Digikam, toutes les nouvelles images compressées ont eu une mauvaise date. Ce qui donne sur le timeline ceci :
Le pic de 2019, n’a pas lieu d’être … j’ai donc essayer de lancer une ligne de commande pour changer la date de modification et de création des images.
$ time exiftool -v -r "-filemodifydate<datetimeoriginal" "-filecreateddate<datetimeoriginal" Images/
...
3214 directories scanned
119812 image files updated
15783 image files unchanged
203 files weren't updated due to errors
real 22m59,695s
user 22m0,499s
sys 0m21,394s
Ensuite j’ai refait un scan avec Digikam :
Je n’ai pas remarqué de changement sur la courbe … misère.