вторник, 19 января 2021 г.

Python в тестировании. Соединить или склеить пару картинок для ручного сравнения.

    Brief: Понадобилось проверить на сходство два набора картинок путем "склеивания" их в одну и последующее "ручное" сравнение просмотром глазами 👀. В целом такая потребность возникает часто. Применений этому масса. Да и развить это можно до полной автоматизации. Я решил поделиться базовым вариантом, что будет полезно прояснить в начале реализации такого подхода.

    User story: Недавно у меня появилась такая потребность ввиду проверки интересного функционала, который ищет на стоке старые товары аналогичные с уже имеющимся в заказах(но со стоком =0). Разные они лишь в названиях артикулов(поставках). Обнаружив такие позиции код в заказах подтягивает те артикулы, которые есть в наличии. Своеобразная рокировка. Польза огромная, стоки освобождаются, клиенты получают свои покупки не ожидая их от поставщика. Быстро проверить корректность хотелось не только вручную, так как это подразумевает малое количество случаев. Для этого я вытащил из базы данных два списка ссылок на картинки у схожих позиций. Списки были заранее в базе отсортированы по id order item из таблицы заказа. Сомнения оставались в правильности работы алгоритма поиска аналогов. Визуальный контроль результатов был кстати. 

    TO BE: Сразу решил использовать очевидный подход , - склеить, объединить в одно изображение две "соответствующих" фотографии. Потом просмотреть их в вручную.

Алгоритм:

  1. создаём папку для набора будущих объединённых картинок
  2. создаём шаблонную пустую картинку для вставки
  3. забираем из первого списка ссылку на первую картинку
  4. далее запрашиваем по url всё что там есть
  5. переводим этот набор данных в байты и преобразуем в картинку 1
  6. вставляем в начало шаблонной картинки
  7. забираем вторую ссылку из второго списка 
  8. запрашиваем по url все данные
  9. конвертируем полученный набор данных в байты и преобразуем в картинку 2
  10. вставляем, со смещением на примерную длину картинки 1, в шаблонную картинку
  11. сохраняем получившуюся склейку в папку
Relate: Вот список модулей:
import requests
from io import BytesIO
from PIL import Image
import os
Для всех эти задач нам понадобится установить в python библиотеки: 
  • requests  -  для установки нужно использовать следующую команду
    • pip install requests
  • pillow - также "подушка", библиотека для работы с изображениями
    • pip install Pillow
  • библиотека io и os уже предустановлены в Python, в любом случае найти команду на их установку не составит труда.
Code:
import requests
from io import BytesIO
from PIL import Image
import os

#создаем папку для сохранения
path = 'C:\\tmp\\'
try:
os.mkdir(path)
except OSError:
print ("Creation of the directory %s failed" % path)
else:
print ("Successfully created the directory %s " % path)
# объявляем два списка ссылок на картинки
list_im = ['https://bipbap.ru/wp-content/uploads/2018/01/01labgvli1288681954.jpg']
list_im2 = ['https://memax.club/wp-content/uploads/2019/06/1-436.jpg']
# формируем шаблон для склеивания/объединения
new_im = Image.new('RGB', (1240,400))
# разбираем списки ссылок в цикле
for i in range(0, len(list_im)):
# запрашиваем данные по ссылке
response = requests.get(list_im[i])
# преобразуем в байты и формируем картинку
im = Image.open(BytesIO(response.content))
# вставляем в шаблон получившееся
new_im.paste(im, (0, 0))
response2 = requests.get(list_im2[i])
im2 = Image.open(BytesIO(response2.content))
# вставляем вторую картинку со смешением по ширине
new_im.paste(im2, (600, 0))
# сохраняем склейку картинок в папку
new_im.save('C:\\tmp\\test'+str(i)+'.jpg')

Result: Для примера ссылки на картинки взял первые попавшиеся в Google поиске. Результат работы приведён ниже:


Объединяет всё достаточно быстро. У меня было от сотни случаев. Единственный минус придётся вручную проконтролировать соответствие, - просмотрев полученное. 

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