Фабрика картинок — как оно работает? Часть 2

в 5:03, , рубрики: web-разработка, архитектура, Веб-разработка, обработка изображений, метки: ,

Наконец собрался написать вторую часть как и обещал в первой. В этой части хочется рассказать о клиентской стороне проекта.

Что используется:

Как говорил раньше проект полностью написан на Python (со вставками Cython'а). Вся информация о изображениях, пользователях, статистики — хранится в БД MySQL.

Для поиска (основного) и фильтра используется Sphinx-сервер. Клиент написанный для twisted txsphinx.

Для «лайков», кол-во просмотров изображения и кол-во скачиваний используется Redis. Так-же в Redis-е хранится топ-изображений (главная страница) и «похожие изображения» (страница самого изображения). Для twisted клиент txredis, найденный на просторах и немного доработанный под себя (пока не в паблике).

Веб: TwistedWeb с шаблонизатором Jinja2, рисуется все Bootsrap'ом и Jquery. Конец цепочки это Nginx.

Интересная часть:

Первое (и самое интересное) это было сделать фильтр изображений. Для начала был составлен список полей для поиска:

  • Категории
  • Минимальное разрешение изображения
  • Ключевые слова
  • Цвета

Фильтр решено было сделать с помощью Sphinx'а. Индексирование происходит через xmlpipe. Определение в sphinx очень простое:

source images {
	type					= xmlpipe2
	xmlpipe_command				= bin/sphinx.py --indexer=images
}

index images {
	source					= images
	path					= /var/lib/sphinx/data/images
	morphology         			= stem_enru
	charset_type				= utf-8

	min_word_len        			= 2
	min_infix_len 				= 3
	enable_star				= 1

	docinfo 				= extern

	html_strip = 1
	index_exact_words			= 1
	expand_keywords				= 0

	wordforms = images_wordforms.txt
}

Категории: MVA-атрибут, список ID. Так-же текстовый атрибут список названий категорий (для правильного поиска, прибавления веса результатам).

Минимальное разрешение изображения: Два атрибута width и height. Тут так-же все просто, поиск по диапазону каждого атрибута, от заданного пользователем до максимального (магическое число 10000).

Ключевые слова: Три текстовых атрибута title tags keywords. Title — заголовок изображения, результатам дается максимальный вес при попадании. Tags — список тегов изображения, средний вес. Keywords — набор ключевых слов (пользователь их не видит), взяты на странице изображения, могут содержать мусор. Маленький вес.

Цвета: Было самое сложное, расскажу подробней. Была создана палитра цветов {ID => RGB}. При добавлении изображения в базу, получаем список доминирующих цветов и приравниваем их к нашей палитре. Цвета изображения хранятся в БД с двумя значениями: ID цвета и процент занимаемый на изображении. В индексе десять MVA-атрибутов «c_X» где X — это номер от 0 до 9. В c_0 попадают все цвета изображения, в с_1 цвета с процентом >= 10, в c_2 цвета с процентом >= 20 и т.д.

Фильтр по цветам: При поиске изображений по цвету берутся все изображения у которых цвет находится в индексе c_1, далее считается вес цвета. При поиске по цвету с ID 2 (псевдокод):

setSelect('(IN(c_1,2)*1) + (IN(c_2,2)*1) + (IN(c_3,2)*1) + (IN(c_4,2)*1) + (IN(c_5,2)*1) + (IN(c_6,2)*1) + (IN(c_7,2)*1) + (IN(c_8,2)*1) + (IN(c_9,2)*1) AS colors_weight')
setOrder('colors_weight DESC')

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

Итог:

Скорость фильтра меня радует, сейчас это примерно 50-80 миллисекунд при 70 000 изображений. Если что-то еще интересно по проекту, пожалуйста спрашивайте, я буду рад рассказать. Опять же сам проект: http://picsfab.com

Автор: p0is0n

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js