Как искать, отличать, перемещать, "измерять" файлы JPEG в директориях Linux используя C
Требуется организовать следующий алгоритм (C, linux):
- Пройти по всем подпапкам директории, найти все JPG файлы (они переименованы, на расширение в названии посмотреть нельзя) и переместить те из них, что имеют самую часто встречающуюся ширину, в нововую папку.
- Там их нужно отсортировать по высоте и переименовать соответствующим образом.
P.S. Понимаю, что запрос не совсем в духе сайта, но жизненно необходимы наброски решений/советы по библиотекам и методам, которые потребуются/ссылки на учебники (источники) где об этом говорится.
Ответы (2 шт):
Эту задачу можно решить и на баше. но если сильно нужно именно с, никто не мешает.
На баше это будет так
find .
что бы найти все файлы в каталоге и вложенных. На си это делается через readdir (пример).
Дальше понадобится identify (часть пакета ImageMagick/GraphickMagick) или file (которая по факту использует identify) он умеет возвращать размер. Если Вы делаете на си, то можно прочитать первые 3 байта и если они ff d8 ff, то скорее всего это jpeg. А если посмотреть на формат заголовка то можно даже вытянуть размер. А можно не заморачиваться и подлинковать себе imagemagick и там скорее всего понадобится функция MagickPingImageFile - она максимально быстро проверяет валидность файла и получает его тип и размеры.
Скопировать/переместить в новую папку не должно быть проблемой, а вот отсортировать в папке... это сложновато. Можно отсортировать при выводе, но в папке - я не знаю.
Пройти по всем подпапкам директории
Проще всего воспользоваться функцией nftw(..):
nftw() walks through the directory tree that is located under the directory dirpath, and calls fn() once for each entry in the tree. By default, directories are handled before the files and subdirectories they contain (preorder traversal).
fn() - будет функцией, которая ищет "все JPG файлы" по их сигнатуре. Читаете первые два байта файла. Любой JPEG начинается с сигнатуры 0xFF 0xD8. Если там эти значения, считываете заголовок файла.
Для этого лучше всего использовать библиотеку libjpeg. Там есть функция jpeg_read_header (). Она возвращает объект JPEG, который содержит поля
- JDIMENSION image_width
- JDIMENSION image_height
Ну а дальше уже - копируйте файлы и давайте им имена с помощью
system("cp <исходный файл> <новый файл>");