TL;DR: https://github.com/yaroslaff/smugglerjpg . Из фото делаем слайдшоу видео и его заливаем (можно unlisted/private, чтобы никто не видел). Затем, если надо — скачиваем видео и извлекаем фото.

На картинке два изображения, оригинальное (слева) и после запаковки-загрузки-скачивания-извлечения (справа). Второе изображение имеет меньшее разрешение, поэтому для сравнения разрешения подогнаны по высоте
Казалось бы, сервисов, где можно хранить фотки (особенно за деньги) — достаточно. И тут я никого не агитирую — если вам что-то нравится и удобно — то и ладушки. Но почему мне это не очень подходит:
-
Ну, во первых — я люблю халяву! Настолько, что ради халявы — не жалко никаких сил и никаких денег!
-
Отечественные сервисы как-то неоднократно дискредитировали себя в моих глазах тем, что на долгой дистанции склонны менять правила игры, как технические, так и тарифы (в том числе обещания, которые дают “навечно”). А фотки — они ведь как заложники. Ты уже не можешь так легко куда-то переехать — они тяжелые, сам переезд будет очень трудоемким.
-
С зарубежными — и этот же аспект остается (хоть и не в такой мере, но все-таки, я еще помню, как хранение на Google Photos было безлимитным и бесплатным). А сейчас, в дополнение, есть сложности с оплатой и санкциями. Нет, я конечно, имею зарубежную карту, но ведь сами понимаете. Сегодня она работает, завтра не работает. Или продлить не получится или пополнить или антифрод не пройдет. Или все пройдет, но скажут, пацан, ты с какого района, мы тут таким не рады — и все.
-
Не храните все яйца в одной корзине! Хоть мы храним, конечно, не яйца (а лишь иногда фото яиц), тем не менее. Но оплачивать 2-3 платных фотохостинга уж точно обидно, а два-три бесплатных — да почему бы и нет?
Сервисов, куда можно заливать фотки (тот же Телеграм или Макс) — достаточно. Однако, вот приехал я с отпуска, привез несколько сотен фото… Во-первых, заливать их тяжело. А во-вторых — если потребуется обратно, то будет ведь еще тяжелее скачивать.
Решение: делаем из фоток — слайдшоу, причем таким образом, чтобы потом было удобно нарезать на фотки обратно (либо без потери в качестве, либо с небольшой потерей).
Ты должен сделать добро из зла, потому что его больше не из чего делать
Раз уж у нас есть Макс и Рутуб и мы все равно их оплатили налогами — почему бы не использовать их как фотохостинги? Хоть на что-то сгодятся.
SmugglerJPG — пакуем галерею в одно видео
Будем использовать вот этот мой проектик — smugglerjpg.
Ставим
pipx install smugglerjpg
Если нет pipx — apt install pipx. Если вы на Windows — наверное, тоже как-то можно поставить. Не пробовал. Еще потребуется ffmpeg на линуксе.
Делаем видео
smugglerjpg create /tmp/testgallery/ -a ~/tmp/bgmusic/ -o out.mp4
-a — можно добавить музыку (тогда можно будет даже самому смотреть и почти не скучно)
-d — продолжительность каждого слайда. (по-умолчанию, 5 секунд)
Если хотите чтобы фото шли в определенном порядке, можно указать либо --sort name / --sort mtime , либо -f filelist.txt
Дальше заливаем его куда хотим.
Распаковываем нашу контрабанду обратно
Скачиваем наше видео, или из студии, или прямо через yt-dlp . Распаковываем:
smugglerjpg extract out-ytdlp.webm -o /tmp/extracted/
И у нас снова те же картинки (с небольшой потерей в качестве, на мой глаз — не заметно).
Контроль качества
Исходное фото для примера:
mediainfo testgallery/IMG20260513193409.jpg
$ mediainfo testgallery/IMG20260513193409.jpgGeneralComplete name : testgallery/IMG20260513193409.jpgFormat : JPEGFile size : 10.8 MiBImageFormat : JPEGWidth : 3 072 pixelsHeight : 4 096 pixelsColor space : YUVChroma subsampling : 4:2:0Bit depth : 8 bitsCompression mode : LossyStream size : 10.8 MiB (100%)ColorSpace_ICC : RGB
Наш локальный видеофайл:
mediainfo out.mp4
$ mediainfo out.mp4 GeneralComplete name : out.mp4Format : MPEG-4Format profile : Base MediaCodec ID : isom (isom/iso2/avc1/mp41)File size : 18.8 MiBDuration : 35 s 0 msOverall bit rate : 4 517 kb/sFrame rate : 30.000 FPSWriting application : Lavf61.7.103VideoID : 1Format : AVCFormat/Info : Advanced Video CodecFormat profile : Constrained Baseline@L5.1Format settings : 1 Ref FramesFormat settings, CABAC : NoFormat settings, Reference frames : 1 frameCodec ID : avc1Codec ID/Info : Advanced Video CodingDuration : 35 s 0 msBit rate : 4 378 kb/sWidth : 3 840 pixelsHeight : 2 160 pixelsDisplay aspect ratio : 16:9Frame rate mode : ConstantFrame rate : 30.000 FPSColor space : YUVChroma subsampling : 4:2:0Bit depth : 8 bitsScan type : ProgressiveBits/(Pixel*Frame) : 0.018Stream size : 18.3 MiB (97%)Writing library : x264 core 165Encoding settings : cabac=0 / ref=1 / deblock=0:0:0 / analyse=0:0 / me=dia / subme=0 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=0 / me_range=16 / chroma_me=1 / trellis=0 / 8x8dct=0 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=0 / threads=6 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=0 / weightp=0 / keyint=250 / keyint_min=25 / scenecut=0 / intra_refresh=0 / rc=crf / mbtree=0 / crf=23.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=0Codec configuration box : avcCAudioID : 2Format : AAC LCFormat/Info : Advanced Audio Codec Low ComplexityCodec ID : mp4a-40-2Duration : 34 s 993 msSource duration : 35 s 16 msBit rate mode : ConstantBit rate : 132 kb/sChannel(s) : 2 channelsChannel layout : L RSampling rate : 44.1 kHzFrame rate : 43.066 FPS (1024 SPF)Compression mode : LossyStream size : 564 KiB (3%)Source stream size : 565 KiB (3%)Default : YesAlternate group : 1
Файл после yt-dlp с youtube:
mediainfo out-ytdlp.webm
$ mediainfo out-ytdlp.webm GeneralComplete name : out-ytdlp.webmFormat : WebMFormat version : Version 4File size : 12.3 MiBDuration : 35 s 48 msOverall bit rate : 2 941 kb/sFrame rate : 30.000 FPSWriting application : Lavf61.7.103Writing library : Lavf61.7.103VideoID : 1Format : AV1Format/Info : AOMedia Video 1Format profile : Main@L5.0Codec ID : V_AV1Duration : 35 s 0 msWidth : 3 840 pixelsHeight : 2 160 pixelsDisplay aspect ratio : 16:9Frame rate mode : ConstantFrame rate : 30.000 FPSColor space : YUVChroma subsampling : 4:2:0Bit depth : 8 bitsTitle : ISO Media file produced by Google Inc.Default : YesForced : NoColor range : LimitedColor primaries : BT.709Transfer characteristics : BT.709Matrix coefficients : BT.709VENDOR_ID : [0][0][0][0]AudioID : 2Format : OpusCodec ID : A_OPUSDuration : 35 s 41 msChannel(s) : 2 channelsChannel layout : L RSampling rate : 48.0 kHzBit depth : 32 bitsCompression mode : LossyDelay relative to video : 7 msLanguage : EnglishDefault : YesForced : No
Параметры извлеченной картинки:
mediainfo /tmp/extracted/extracted_slide_003.jpg
$ mediainfo /tmp/extracted/extracted_slide_003.jpg GeneralComplete name : /tmp/extracted/extracted_slide_003.jpgFormat : JPEGFile size : 967 KiBImageFormat : JPEGWidth : 1 620 pixelsHeight : 2 160 pixelsColor space : YUVChroma subsampling : 4:2:0Bit depth : 8 bitsCompression mode : LossyStream size : 967 KiB (100%)
Замечания, советы
-
Видео на ютубе можно хранить как unlisted или private. Или вообще как Draft!
-
Разрешение видео на практике — все-таки одно на всю продолжительность видео. Таким образом, если мы в видео держим одновременно и вертикальные и горизонтальные фотки — потери качества будут выше. С другой стороны, сейчас в телефонах столько мегапикселей что я после этой процедуры не замечаю разницы.
-
Делалось LLM’кой, так что, сами понимаете.
Пользуйтесь, и храните свои приятные воспоминания!
ссылка на оригинал статьи https://habr.com/ru/articles/1051454/