powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Вторничный фотографЪ
19 сообщений из 69, страница 3 из 3
Вторничный фотографЪ
    #40091765
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что такое tag?

Код: sql
1.
 "{album, location, event}/{ymd}{hm}_{crc32} [{tag}] ({device} {model})"
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40091768
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton

Для себя проблему дедубликации решил утилитой fdupes
https://ru.wikipedia.org/wiki/Fdupes

Если бы все было так просто, то и CRC бы не потребовался.
В том же Total Commander тоже есть побайтовое сравнение.
Проблема в том, что изменения могут быть внесены в метаинформацию — собственно изображение будет тем же, но fdupes будет считать файлы разными.
И изменения иногда могут быть внесены вообще незаметно для пользователя. Например при просмотре фотографий на ПК если фотографию повернуть на 90 градусов, некоторые просмотрщики изменяют тэг ориентации в EXIF.
Или иногда я копирую часть фотографий для публикации, убираю в них EXIF, иногда еще и уменьшаю размеры — фактически это дубли, а при бинарном сравнении они найдены не будут.
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40091770
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tag это какие-то специальные режимы фотографирования.
Например при серийной съемке добавляется тэг burst, при склейке панорам добавляется тэг pano и т.п.
В обычных фотографиях этого тэга нет (вместе с обрамляющими квадратными скобками).
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40091800
s62
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,
привет, разбираете exif-теги полностью своим кодом, или пользуетесь какой-то готовой библиотекой? Если своим, то нет ли ссылки на понятное описание формата? Я, после того, как вы задачу озвучили (в теме про страницу с фотками), почитал, но так толком и не разобрался, как найти начало тега.
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40091810
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
s62
mayton,
привет, разбираете exif-теги полностью своим кодом, или пользуетесь какой-то готовой библиотекой? Если своим, то нет ли ссылки на понятное описание формата? Я, после того, как вы задачу озвучили (в теме про страницу с фотками), почитал, но так толком и не разобрался, как найти начало тега.

Использую готовую библиотеку Apache Commons Imaging https://commons.apache.org/proper/commons-imaging/

Собственно всё мясо реализовано здесь. Остальное - это обертки. Консольное приложение и FileVizitor
который обходит файловую систему в сборе картинок.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
    
import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.Imaging;
import org.apache.commons.imaging.common.ImageMetadata;
import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata;
import org.apache.commons.imaging.formats.tiff.TiffField;
import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;
import org.apache.commons.imaging.formats.tiff.fieldtypes.FieldType;


public Optional<String> safeGetValue(TiffField tiffField) {
        try {
            return Optional.of(tiffField.getStringValue());
        } catch (ImageReadException e) {
            return Optional.empty();
        }
    }

    public Optional<LocalDateTime> tryigToApplyDatePattern(String dateTimeVal, List<String> datePatterns) {
        for(String datePattern : datePatterns) {
            try {
                DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(datePattern);
                LocalDateTime localDateTime = LocalDateTime.parse(dateTimeVal, dateTimeFormatter);
                return Optional.of(localDateTime);
            } catch (DateTimeParseException ex) {
                // Nothing to do
            }
        }
        return Optional.empty();
    }

    public Optional<LocalDateTime> fromFile(InputStream inputStream) {
        return fromFile(inputStream, asList("DateTime", "DateTimeOriginal", "DateTimeDigitized"), asList("yyyy:MM:dd HH:mm:ss"));
    }

    public Optional<LocalDateTime> fromFile(InputStream inputStream, List<String> exifTags, List<String> datePatterns) {
        ImageMetadata metadata;
        Optional<String> value = Optional.empty();
        try {
            metadata = Imaging.getMetadata(inputStream, null);
            if (metadata != null) {
                TiffImageMetadata items = ((JpegImageMetadata) metadata).getExif();
                if (items != null) {
                    for (TiffField field : items.getAllFields()) {
                        if (field.getFieldType() == FieldType.ASCII) {
                            String tagName = field.getTagName();
                            for(String tag : exifTags) {
                                if (tag.equals(tagName)) {
                                    value = safeGetValue(field);
                                    if (value.isPresent()) {
                                        return tryigToApplyDatePattern(value.get(), datePatterns);
                                    }
                                }
                            }
                        }
                    }
                } else {
                    logger.warn("No tiff fields detected!");
                }
            } else {
                logger.warn("No TiffImageMetadata detected!");
            }
            //JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
        } catch (ImageReadException e) {
            logger.error("ImageReadException", e);
        } catch (IOException e) {
            logger.error("IOException", e);
        } catch (DateTimeParseException e) {
            logger.warn("DateTimeParseException during parse " + value.get(), e);
        }
        return Optional.empty();
    }


Все это в статусе опенсорца и я выложу когда доведу до ума.
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40091811
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.
mayton

Для себя проблему дедубликации решил утилитой fdupes
https://ru.wikipedia.org/wiki/Fdupes

Если бы все было так просто, то и CRC бы не потребовался.
В том же Total Commander тоже есть побайтовое сравнение.
Проблема в том, что изменения могут быть внесены в метаинформацию — собственно изображение будет тем же, но fdupes будет считать файлы разными.
И изменения иногда могут быть внесены вообще незаметно для пользователя. Например при просмотре фотографий на ПК если фотографию повернуть на 90 градусов, некоторые просмотрщики изменяют тэг ориентации в EXIF.
Или иногда я копирую часть фотографий для публикации, убираю в них EXIF, иногда еще и уменьшаю размеры — фактически это дубли, а при бинарном сравнении они найдены не будут.

Дедубликация - это все таки отдельная задача. И она - более сложная и интересная.
Я-бы хотел ее реализовать не через контрольные суммы а через персептивный хеш.
Все как выше по топику. Только к этому хешу я добавлю еще 4 проверки на поворот
фотографии.

И это будет отдельная утилита. Я хочу следовать принципам unix. Каждая тулза - простая
и решает узкую задачу. Если надо будет их соединить в цепочку или конвейер - то такая
возможность думаю будет.
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40091850
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, отдельная утилита будет логичным решением.
Но лично для меня наличие CRC в имени файла оказалось удобным.
Он решает две задачи.
Во-первых, помогает для поиска дублей/оригиналов (как я описал выше).
Во-вторых, обеспечивает уникальность имен файлов в альбоме, (почти) не нарушая очередности и не слишком загромождая имя файла. Если называть файлы по маске hhmmss (до секунды), то это все равно не гарантирует уникальности имени, потому что даже обычные фотографии иногда могут быть сняты в пределах одной секунды (не говоря уж о серийных фото). То есть в имя файла все равно нужно будет добавлять счетчик для уникальности: hhmmss_nnnn. А еще этот счетчик сильно мозолит глаза, если в нем есть пропуски, возникает желание его перенумеровать (что впоследствии чревато коллизиями). Я же именую файлы по маске hhmm_crc (где crc это 8 шестнадцатиричных символов). Всего на два символа длиннее, чем hhmmss_nnnn, однако позволяет забыть про неуникальность или коллизии имен файлов (у меня более 60 ТБ фото и ни разу не было коллизий). Есть некоторый минус в том, что в пределах одной минуты возможно нарушение очередности фотографий, но на практике это неудобство незначительное, обычно в подряд снимаемых фотографиях по сюжету легко восстановить хронологию (ну и в EXIF и атрибутах в любом случае сохраняется полная дата и время).
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40091853
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А, еще.
Если смартфон или фотоаппарат подключаются к ПК как MTP-устройство, а не как USB Mass Storage, то при копировании файлов возникает крайне неприятный баг, дата и время файлов не сохраняются (заменяются на текущие). Это нарушает порядок отображения галереи, да и вообще несет много неудобств. Поэтому я и пришел к тому, что дата и время должны присутствовать в имени файла.
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40091872
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да. Согласен. Любое перекидывание фоток через соцсети или портативные диски может как-то повлиять на дату
создания обновления.

Для меня - это уже технически решенная задача. Можно просто год и месяц добавить в файл.

Код: sql
1.
'yyyy/MM/dd/yyyy-MM-dd-HHmmss'



Кстати. Я вот думаю что из коробки уже готов и другой механизм. Читабельные названия месяцев.

Код: sql
1.
2021/AUG/8/2021-AUG-8-16-35-00.jpg



Удобно ли это для человека?
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40091879
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И август будет перед мартом?
В имени файла должны быть только цифры.
И лишние разделители не нужны, я бы 'yyyy/MM/dd/yyyy-MM-dd-HHmmss' заменил на 'yyyy/yyyy-MM-dd/yyyyMMddHHmmss'.
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40091881
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кому-то удобно. В реферальных топиках (выше) я делал индексирование фоток в статичный HTML.

И для публикации людям иногда удобнее кликать не на 09 и 10 месяцы (ссылки)
а именно на символические названия AUG, SEP.

Просто мы люди так устроены. Ассоциацию вспоминаем. Например были крестины или свадьба в августе.
Сразу ясно куда кликать.
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40091893
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так в HTML-файле список можно вывести в любом удобном порядке.
А список файлов (в файл-менеджере или диалоговом окне) обычно упорядочивается по названию файла.
И там буквенные наименования месяцев будут неудобны.
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40091899
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мда... это мысль. Разделить контент и отображение. Месяцы - можно символами но при сохранении стабильного
неубывающего порядка. JAN,FEB,MAR.....e.t.c.
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40092441
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Альфа версия

https://github.com/mayton-nosql/photo-time-sort/releases/tag/1.0-alpha

Бинари под Windows/Linux еще не собрал. Поэтому для исполнения нужен Java11.
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40092453
exp98
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Просто мы люди так устроены. Ассоциацию вспоминаем. Например были крестины или свадьба в августе.
Сразу ясно куда кликать.
Мне теперь всегда на Авг кликать?
Хотелось бы ассоциирующихся подсказок, какой текуший месяц. Например в виде 08 или 03 и т.д.
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40092455
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я-бы не хотел здесь обсуждать вопросы дизайна и публикации.

Это пожалуй лучше здесь спрашивать в старом топике который я спецом создавал
по дизайну https://www.sql.ru/forum/1337955-6/kartinki-lentoy-tablicy-ili-divs
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40092464
d7i
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Читабельные названия месяцев.
Код: sql
1.
2021/AUG/8/2021-AUG-8-16-35-00.jpg


А вы что, не знаете что, по-крайней мере в Windows, вышеуказанное имя создаст три вложенные папки
2021
AUG
8
и в последней из них файл 2021-AUG-8-16-35-00.jpg.
Символ "/" в имени файла трактуется как папка.
Попробуйте, сами увидите...
Или так и задумано?
Тогда 2021-AUG-8 в имени файла совсем излишне...
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40092471
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Вторничный фотографЪ
    #40092474
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
d7i
А вы что, не знаете
Знает, конечно.Тогда 2021-AUG-8 в имени файла совсем излишне...А если файл перемещается/копируется за пределы исходной иерархии, то получается, что хреновый из вас дизайнер.
...
Рейтинг: 0 / 0
19 сообщений из 69, страница 3 из 3
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Вторничный фотографЪ
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]