CoderCastrov logo
CoderCastrov
Программирование

googleimagesdownload мертв. Да здравствует bingimagesdownload...

googleimagesdownload мертв. Да здравствует bingimagesdownload...
просмотров
8 мин чтение
#Программирование

Как скачать сотни изображений с помощью скрипта одновременно + включить их в ваш проект iOS

Довольно долгое время я использовал очень удобный инструмент, созданный Хардиком Васой, называемый [googleimagesdownload](https://google-images-download.readthedocs.io/en/latest/index.html). Этот инструмент позволяет загружать несколько изображений из Google одновременно через командную строку. Например, следующая команда загрузит 10 изображений кошек.

% googleimagesdownload -k cat -l 10

Но это было... до месяца назад, к сожалению 😢 (Сейчас 1 марта 2020 года, в момент написания). Оказывается, Google изменил формат страницы результатов поиска изображений, и скрапинг стал сложным. Теперь вышеуказанная команда беспощадно завершается одной строкой:

К сожалению, не удалось загрузить все 10 изображений, потому что некоторые изображения невозможно загрузить. 0 - это все, что мы получили для этого фильтра поиска!

Однако, к счастью, член сообщества быстро создал аналогичный инструмент, который загружает изображения с Bing, вместо Google. Сегодня я расскажу

  • о том, как использовать новую версию инструмента, и
  • объясню, как вы можете редактировать загруженные изображения в формате, подходящем для iOS, в нескольких шагах.

Вторая часть относится только к разработчикам iOS, но идея может быть применима к любой разработке программного обеспечения, которая обрабатывает несколько изображений. Кроме того, техника проверена только на Mac OS X, но должна работать на любых системах на основе Linux.


Скачивание и использование скрипта

Перейдите на gist и скачайте скрипт. Разместите его в удобном месте.

Теперь вы должны подумать, что вы можете просто использовать его так:

% python ${ПУТЬ_К_СКРИПТУ}/bing_images_download.py -k cat -l 10

но это не так просто... (по крайней мере, на данный момент)

Сначала вам нужно перейти на Bing и выполнить поиск.

Поиск 'cat' на bing.com/images

Затем скопируйте URL из адресной строки.

Адресная строка после поиска

Затем мы можем указать скопированный URL в качестве параметра для скрипта вот так:

% python ${ПУТЬ_К_СКРИПТУ}/bing_images_download.py **-u "**[**https://www.bing.com/images/search?q=cat&search=&scope=images&form=QBLH&sp=-1&pq=ca&sc=8-2&qs=n&sk=&cvid=7D17745015D14FA3A9AEB35EE4248448**](https://www.bing.com/images/search?q=cat&search=&scope=images&form=QBLH&sp=-1&pq=ca&sc=8-2&qs=n&sk=&cvid=7D17745015D14FA3A9AEB35EE4248448)**"** -l 10

Скачивание более 100 элементов

Если вы хотите скачать более 100 элементов, вам необходимо использовать chromedriver. Скачайте его отсюда здесь и поместите в удобное место. Затем вы можете указать этот исполняемый файл с помощью параметра "-cd" следующим образом:

% python ${ПУТЬ_К_СКРИПТУ}/bing_images_download.py -u "[https://www.bing.com/images/search?q=cat&search=&scope=images&form=QBLH&sp=-1&pq=ca&sc=8-2&qs=n&sk=&cvid=7D17745015D14FA3A9AEB35EE4248448](https://www.bing.com/images/search?q=cat&search=&scope=images&form=QBLH&sp=-1&pq=ca&sc=8-2&qs=n&sk=&cvid=7D17745015D14FA3A9AEB35EE4248448)" -l 300 **-cd ${ПУТЬ_К_CHROMEDRIVER}**

Теперь вы можете получить точно такие же результаты из Bing, какие вы получали раньше из Google с помощью googleimagesdownload.

Использование изображений для разработки

Хорошо, первая часть завершена. Далее идет часть, где мы форматируем имена файлов для удобства разработки под iOS.

googleimagesdownload и bing_images_download.py сохраняют оригинальные имена файлов загруженных изображений, просто добавляя перед ними порядковый номер, например:

1.Animals_Cats_Small_cat_005241_.jpg
2.funny-cat-pictures-047-001.jpg
3.Cat-05.jpg
4.o-CAT-ATTACK-facebook.jpg
5.Beautiful+Cats+Hd+Wallpapers_7.jpg
...

Это уже достаточно хорошо для многих ситуаций, таких как использование изображений для обучения/тестирования машинного обучения и т.д. Однако, если вы используете эти изображения для разработки программного обеспечения, во многих случаях вам будет удобно обращаться к ним с помощью шаблона, например:

for i in 0..<100 {
    let imageName = **String(format: "%d", i)**
    let image = UIImage(named: imageName)
    ...
}

Чтобы это сделать, нам нужно немного изменить имена файлов.

Кроме того, загруженные изображения имеют разные размеры. Вы можете указать одну и ту же группу размеров в поиске Bing, но это не гарантирует точно одинаковые размеры.

Во многих случаях, когда мы хотим показывать изображения в одном и том же месте в списке или сетке, будет наиболее удобно иметь набор изображений с точно одинаковыми размерами.

Переименование имен файлов

Сначала давайте преобразуем имена файлов из

1.Animals_Cats_Small_cat_005241_.jpg
2.funny-cat-pictures-047-001.jpg
3.Cat-05.jpg
4.o-CAT-ATTACK-facebook.jpg
5.Beautiful+Cats+Hd+Wallpapers_7.jpg
...

в

1.jpg
2.jpg
3.jpg
4.jpg
5.jpg
...

Мы можем достичь этого, выполнив команду оболочки с использованием конвейера в каталоге с изображениями:

ls | sed -E 'p;s/([0-9]*)\..*\.(jpg|jpeg|png|JPG|JPEG|PNG)/\1.\2/' | xargs -n2 mv

При выполнении в каталоге с загруженными изображениями ls выводит имена изображений, а команда sed выводит список строк после применения замены подстрок. Часть команды sed выглядит немного сложной, поэтому давайте разберем ее.

  • Опция -E говорит sed использовать современные регулярные выражения.
  • p; внутри одинарных кавычек означает вывод оригинальной строки (означает 'p'еред заменой?). Таким образом, это выводит исходную строку перед замененной строкой.
  • Часть s/XXX/YYY/ является стандартным форматом в sed. Она означает, что если она находит XXX в исходной строке, она заменяет совпадающую часть на YYY. \1 и \2 называются обратными ссылками. Они являются переменными, которые относятся к совпавшим частям, обозначенным скобками (...). Таким образом, в данном случае \1 соответствует части [0-9]*, а \2 соответствует части jpg|jpeg|png|JPG|JPEG|PNG.

Исходя из этой информации, надеюсь, вы понимаете, что первая часть скрипта

ls | sed -E 'p;s/([0-9]*)\..*\.(jpg|jpeg|png|JPG|JPEG|PNG)/\1.\2/'

выводит что-то вроде этого:

1.Animals_Cats_Small_cat_005241_.jpg
1.jpg
10.cats.jpg
10.jpg
11.shocked_cat.jpg
11.jpg
...

Поскольку передача списка через | xargs -n2 означает брать по два элемента, ... | xargs -n2 mv означает генерацию последовательности следующих команд:

% mv 1.Animals_Cats_Small_cat_005241_.jpg 1.jpg
% mv 10.cats.jpg 10.jpg
% mv 11.shocked_cat.jpg 11.jpg
...

В результате мы получаем желаемый вывод:

1.jpg
2.jpg
3.jpg
4.jpg
5.jpg
...

Изменение размера изображений

Для работы с изображениями из командной строки вам необходимо установить imagemagick. Это очень мощный и широко используемый инструмент для редактирования изображений из командной строки. Если вы еще не знакомы с ним, рекомендую начать использовать его уже сегодня! Инструкции по установке для разных операционных систем можно найти на официальном веб-сайте.

После установки imagemagick создайте директорию для сохранения измененных изображений, чтобы не затереть оригиналы.

% mkdir output

Предположим, что мы хотим получить миниатюры изображений размером 80px*80px. Мы можем использовать следующую команду для создания изображений в 3 раза большего размера:

ls -p | grep -v / | while read file; do convert $file -resize 240x240 -size 240x240 xc:none +swap -gravity center -composite "output/${file/./@3x.}"; done

Если вы не привыкли к такому сложному виду скрипта на языке командной строки, давайте разберем его по частям.

ls -p | grep -v / - это хитрый способ вывести список файлов в директории, исключая (под)директории. Опция -p добавляет / в конец имени директории, а grep -v / исключает все строки, содержащие /. Таким образом, мы получаем список файлов, исключая директории.

while read file; do ...; done

означает, что мы выполняем итерацию по списку и записываем каждый элемент списка в переменную file. Часть ... - это основная часть скрипта, в которой мы выполняем операции с изображениями для каждого файла:

convert $file -resize 240x240 -size 240x240 xc:none +swap -gravity center -composite "output/${file/./@3x.}"

Команда convert - это команда imagemagick для работы с изображениями. Каждая опция имеет следующее значение.

  • Опции -resize и -size говорят сами за себя, но зачем нам нужны обе? Опция -resize изменяет размер самого изображения. Опция -size создает изображение заданного размера с черным/прозрачным фоном. Поскольку не все изображения имеют такое же соотношение сторон, как указанный размер, нам нужно добавить отступы. Для этого imagemagick создает отдельное изображение фона заданного размера.
  • xc:none означает прозрачный цвет фона для созданного ранее фонового изображения. С опцией +swap будет применено заполнение (отступ) в виде черных полос в области с прозрачным фоном. Вот так:
Вверху/внизу изображения есть черные полосы, чтобы соответствовать указанному размеру
  • Опция -gravity center определяет расположение исходного изображения при наличии черных полос. Например, если указать -gravity north, получится следующее:
С опцией -gravity north исходное изображение будет расположено вверху.
  • Опция -composite необходима. В противном случае convert будет создавать фоновое (черное) и переднее изображение отдельно. В большинстве случаев нам это не нужно.
  • Часть "output/${file/./@3x.}" - это функциональность командной строки, с помощью которой можно создавать строки на основе указанной переменной. ${var/str1/str2} означает, что если вы найдете str1 в $var, замените его на str2. Таким образом, когда $file указывает на "1.jpg", "output/${file/./@3x.}" выводит "output/1@3x.jpg"

Теперь, я надеюсь, вы понимаете, что команда

ls -p | grep -v / | while read file; do convert $file -resize 240x240 -size 240x240 xc:none +swap -gravity center -composite "output/${file/./@3x.}"; done

выведет

output/1@3x.jpg
output/2@3x.jpg
output/3@3x.jpg
...

и все эти файлы будут иметь размер 240px * 240px.

Остается только создать изображения @2x/@1x. Для этого просто повторите тот же шаблон с другими размерами и путями назначения.

ls -p | grep -v / | while read file; do convert $file -resize 160x160 -size 160x160 xc:none +swap -gravity center -composite "output/${file/./@2x.}"; done

и

ls -p | grep -v / | while read file; do convert $file -resize 80x80 -size 80x80 xc:none +swap -gravity center -composite "output/${file}"; done

Копирование изображений в каталог ресурсов

Остальное просто. Просто перетащите все изображения из папки output в каталог ресурсов Xcode! Вы должны автоматически увидеть что-то вроде этого:

Asset catalog after copying all the images (I didn’t generate 1x image for this)

Summary

Шаги для использования bing_images_download.py:

% python ${PATH_TO_THE_SCRIPT}/bing_images_download.py **-u "**[**https://www.bing.com/images/search?q=cat&search=&scope=images&form=QBLH&sp=-1&pq=ca&sc=8-2&qs=n&sk=&cvid=7D17745015D14FA3A9AEB35EE4248448**](https://www.bing.com/images/search?q=cat&search=&scope=images&form=QBLH&sp=-1&pq=ca&sc=8-2&qs=n&sk=&cvid=7D17745015D14FA3A9AEB35EE4248448)**"** -l 10
  1. Если вам нужно загрузить более 100 изображений, то загрузите chromedriver и укажите его с помощью опции -cd.
% python ${PATH_TO_THE_SCRIPT}/bing_images_download.py -u "[https://www.bing.com/images/search?q=cat&search=&scope=images&form=QBLH&sp=-1&pq=ca&sc=8-2&qs=n&sk=&cvid=7D17745015D14FA3A9AEB35EE4248448](https://www.bing.com/images/search?q=cat&search=&scope=images&form=QBLH&sp=-1&pq=ca&sc=8-2&qs=n&sk=&cvid=7D17745015D14FA3A9AEB35EE4248448)" -l 300 **-cd ${PATH_TO_THE_CHROMEDRIVER}**

Шаги для переформатирования загруженных файлов:

% ls | sed -E 'p;s/([0-9]*)\..*\.(jpg|jpeg|png|JPG|JPEG|PNG)/\1.\2/' | xargs -n2 mv
  1. Создайте директорию для выходных изображений
% mkdir output
  1. Запустите imagemagick для создания измененных изображений
% ls -p | grep -v / | while read file; do convert $file -resize 240x240 -size 240x240 xc:none +swap -gravity center -composite "output/${file/./@3x.}"; done% ls -p | grep -v / | while read file; do convert $file -resize 160x160 -size 160x160 xc:none +swap -gravity center -composite "output/${file/./@2x.}"; done% ls -p | grep -v / | while read file; do convert $file -resize 80x80 -size 80x80 xc:none +swap -gravity center -composite "output/${file}"; done

Вот и все, надеюсь, вам понравилось!! Счастливого кодирования!!