Русский · English
Готовые примеры работы с API анализа изображения на шести языках: Python, TypeScript (Node.js), Go, Java, C#, PHP.
Модерация пользовательского контента: классификация содержимого (нагота, откровенность, насилие), метки предметов и распознавание текста НА изображении — плюс сводное решение allow / review / block.
Каждый пример запускается сразу — без регистрации, без ключа, без карты. В коде зашит публичный демо-ключ и два образца изображений.
git clone https://github.com/atlorium-api/image-moderation-api-client
cd image-moderation-api-client/python && pip install -r requirements.txt && python main.pysample-banner.jpg · JPEG, 445 КБ
Решение: review · списано единиц: 2
Классификация содержимого: для взрослых: very_unlikely, откровенность: very_unlikely, насилие: very_unlikely, медицинское: very_unlikely, подделка: very_unlikely
Метки предметов: Font (0.93), Poster (0.85), Advertising (0.71)
Текст на изображении:
| ФРИСПИНЫ КАЖДЫЙ ДЕНЬ
| бонус за депозит 200%
| пиши: +7 900 000-00-00
НА МОДЕРАЦИЮ: нужен человек.
Очередь: очередь модератора
[!] Азартные игры [текст на изображении]: бонус за депозит → review
[!] Контакты для увода сделки [текст на изображении]: +7 900 000-00-00 → review
[i] Поиск в вебе не заказан: заимствованное чужое изображение не будет опознано
Обратите внимание на этот вывод: классификация содержимого и метки предметов не увидели ничего. Ни наготы, ни насилия, ни запрещённых предметов — обычный баннер. Поймал только текстовый слой. Ровно так выглядит значительная доля того, что подлежит удалению.
Демо-ключ отвечает моками: изображение никуда не отправляется и не анализируется. Ветку ответа задаёт размер присланного файла — так все четыре исхода воспроизводятся в тесте, а не выпадают случайно. Подставьте боевой ключ — тот же код начнёт возвращать настоящий разбор.
Это главное, что нужно понять перед интеграцией. Слои не дублируют друг друга и не «проверяют одно и то же надёжнее» — каждый ловит класс материала, невидимый для двух остальных:
| Слой | Что ловит | Что при этом молчит |
|---|---|---|
| Классификация содержимого | Откровенное фото — без надписей и распознаваемых предметов | Метки и текст |
| Метки предметов | Шприц, оружие, игральные фишки, бутылку | Классификация: наготы и насилия на такой картинке нет |
| Текст НА изображении | Телефон продавца, баннер казино, объявление о поддельных документах | Оба предыдущих: там просто буквы |
Выключенный слой — это не «проверка чуть слабее», а целая категория материала, проходящая насквозь и незаметно. В российских реалиях дороже всего обходится отключение текстового слоя: значительная доля того, что подлежит удалению, — не картинка, а надпись поверх нейтральной картинки, и ловит её только он.
Поэтому в примерах функция moderateUpload() не просто маршрутизирует загрузку, но и считает покрытие: если слой не заказывался, об этом печатается отдельная строка, а вердикт «опубликовать», полученный не по всем слоям, помечается как более слабый, чем выглядит.
Модерация объявлений и фотографий товаров. Проверка аватаров и обложек. Отсев рекламы и контактов «мимо площадки» в пользовательских изображениях. Предварительный фильтр перед ручной модерацией — он сокращает её объём, оставляя человеку спорные случаи.
Решение принимаете вы. decision — рекомендация, а не приговор: allow, review (нужен человек) или block. Промежуточное review существует потому, что автоматическое удаление по одному машинному признаку даёт ложные срабатывания на медицинских, исторических и новостных материалах.
| Язык | Запуск | Требуется |
|---|---|---|
| Python | pip install -r requirements.txt && python main.py |
Python 3.10+ |
| TypeScript / Node.js | npm install && npm start |
Node.js 20+ |
| Go | go run . |
Go 1.22+ |
| Java | java Main.java |
JDK 17+ (без зависимостей) |
| C# | dotnet run |
.NET 8+ |
| PHP | php main.php |
PHP 8.1+ |
Передать свой файл: python main.py /путь/к/картинке.jpg
В корне репозитория лежат два готовых образца:
| Файл | Размер | Что показывает |
|---|---|---|
sample-banner.jpg |
~445 КБ | Срабатывание текстового слоя: review, два флага |
sample-photo.jpg |
~16 КБ | Чистый кадр: allow, флагов нет |
Ветку ответа в песочнице задаёт размер изображения в декодированном виде. Своими файлами можно воспроизвести все четыре исхода:
| Размер файла | Что вернёт демо-ключ |
|---|---|
| меньше 100 КБ | allow — срабатываний нет |
| 100 КБ – 400 КБ | review по метке предмета (классификация при этом молчит) |
| 400 КБ – 1 МБ | review по тексту на изображении (молчат оба остальных слоя) |
| больше 1 МБ | block по классификации содержимого |
Приём неочевидный, но воспроизводимый и целиком в ваших руках: достаточно закрепить в тестах четыре файла разной величины. Границы разнесены на сотни килобайт, чтобы случайное пересжатие не «переехало» в соседний сценарий.
Ключ передаётся в заголовке Authorization:
Authorization: Bearer ВАШ_КЛЮЧ
| Ключ | Что делает |
|---|---|
ak_sandbox_demo_mockdata_v1 |
Демо-ключ. Публичный, один на всех. Возвращает моки, денег не списывает, регистрации не требует. Ответы детерминированы — на них можно писать стабильные тесты. |
| Боевой ключ | Настоящий анализ изображения. Получить в личном кабинете: atlorium.com |
Переход на боевой ключ не требует правок в коде — все примеры читают переменную окружения:
export ATLORIUM_API_KEY="ak_ваш_боевой_ключ"Каждый ответ песочницы помечен заголовком X-Atlorium-Sandbox: true — перепутать мок с настоящим разбором невозможно.
Базовый адрес: https://atlorium.com
| Метод | Путь | Назначение |
|---|---|---|
POST |
/api/imagecheck |
Анализ изображения и решение модерации |
Пакетного режима нет намеренно: изображение — это мегабайты в теле запроса, и пакет превратился бы в стомегабайтный POST с таймаутами на промежуточных узлах. Поток модерируется параллельными одиночными запросами: они независимы, повторяются поштучно и не теряют весь пакет из-за одной битой картинки.
{
"image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ...",
"includeText": true,
"includeWebSearch": false
}| Параметр | Тип | Описание |
|---|---|---|
image |
string | Изображение в Base64 — «голым» или в виде data-URL. Предел 7 МБ в декодированном виде. Принимаются JPEG, PNG, WEBP, BMP, GIF. PDF и видео на вход не подаются |
includeText |
bool | Читать текст НА изображении. По умолчанию true — и отключать его дороже всего (см. таблицу слоёв) |
includeWebSearch |
bool | Искать изображение в вебе. По умолчанию false |
| Поле | Тип | Что содержит |
|---|---|---|
decision |
string | Сводное решение: allow, review или block. Рекомендация, а не приговор |
flags |
array | Сработавшие фильтры — почему принято такое решение, см. ниже |
safeSearch |
object | Классификация содержимого, см. ниже |
labels |
array | Распознанные предметы: { name, nameRu, score }. nameRu заполнено не у всех меток |
text |
string | Текст, распознанный на изображении. Пустая строка — не ошибка |
webSearch |
object | Результат поиска в вебе. null, если поиск не заказывался |
billedUnits |
number | Фактически списанное число единиц работы: от 1 до 3 |
elapsedMs |
number | Длительность анализа, мс |
message |
string | Пояснение для человека |
| Поле | Тип | Что содержит |
|---|---|---|
category |
string | Категория стоп-листа, например gambling, adult, contacts |
title |
string | Человекочитаемое название категории |
source |
string | Слой-источник: safe_search, label или text. Показывайте его модератору — без него непонятно, почему нейтральная на вид картинка попала в очередь |
evidence |
string | Конкретное доказательство: найденная метка, выражение из текста или категория классификации со степенью |
severity |
string | Вклад этого срабатывания: review или block |
Пять категорий: adult, racy, violence, medical, spoof. Значение каждой — степень уверенности: unknown, very_unlikely, unlikely, possible, likely, very_likely.
fullMatchCount, partialMatchCount, bestGuess, matches[] (pageUrl, fullMatch). Приходит только если поиск заказан. Поиск, не давший совпадений, не тарифицируется.
Он означает одно из двух: читаемого текста на картинке нет, либо слой не заказывался. Какой это случай, видно по billedUnits. В примерах эта развилка разобрана явно — смотрите ветку вокруг includeText.
Сырые слои (safeSearch, labels, text) отдаются намеренно, а не только итоговое решение: в модерации ошибка стоит дорого в обе стороны, и решение, которое нельзя перепроверить, доверия не заслуживает.
| Код | Причина | Что делать |
|---|---|---|
400 |
Изображение не передано, повреждено, больше 7 МБ или в неподдерживаемом формате | Проверьте формат и размер до отправки — во всех примерах это делается по сигнатуре файла |
401 |
Ключ отсутствует, просрочен или недействителен | Проверьте заголовок Authorization |
402 |
Недостаточно кредитов на балансе | Пополнить на atlorium.com |
429 |
Превышен rate-limit | Повторить с задержкой. Ставьте потолок ожидания — сервер может честно попросить подождать десятки минут |
503 |
Анализ выполнить не удалось | Повторить позже. За сбой на нашей стороне деньги не списываются |
Во всех шести примерах коды разложены в человекочитаемые причины — смотрите класс AtloriumError.
Оплата pay-as-you-go, без подписки. Единиц работы от 1 до 3:
| Единица | За что |
|---|---|
| 1 | Базовый слой: метки предметов вместе с классификацией содержимого. Обязателен |
| +1 | Чтение текста на изображении (includeText, по умолчанию включено) |
| +1 | Поиск изображения в вебе (includeWebSearch, по умолчанию выключено) — и только если поиск вернул совпадения |
Фактически списанное число всегда приходит в ответе полем billedUnits. Анализ, который не выполнен, не тарифицируется вовсе.
Актуальные цены и лимиты: atlorium.com/pricing
- Не распознаёт лица и не устанавливает личность.
- Не хранит присланные изображения.
- Не заменяет ручную модерацию — он сокращает её объём, оставляя человеку спорные случаи.
Стоит ли экономить на текстовом слое? Почти никогда. Он включён по умолчанию именно поэтому: надпись поверх нейтральной картинки не видят ни классификация, ни метки, а в российском UGC это очень частый случай.
Можно ли настроить, что считать нарушением? Да. Сводное решение считается по вашим стоп-листам, редактируемым без перезапуска.
Почему decision — «рекомендация»? Потому что автоматическое удаление по одному машинному признаку даёт ложные срабатывания на медицинских, исторических и новостных материалах. Для этого и существует промежуточное review.
Почему нет пакетного режима? Изображение — это мегабайты в теле запроса. Пакет превратился бы в огромный POST, который рвётся по таймауту, и одна битая картинка теряла бы весь пакет. Параллельные одиночные запросы надёжнее.
Какие форматы принимаются? JPEG, PNG, WEBP, BMP, GIF, до 7 МБ в декодированном виде. PDF и видео — нет.
Что делать с flags, если решение всё равно allow? Такого не бывает: сработавший флаг всегда поднимает решение минимум до review. Пустой flags при allow — нормальный исход, но проверьте покрытие: заказаны ли были все слои.
Модерация изображения редко бывает единственной проверкой пользовательского контента. Из того же аккаунта и тем же ключом доступны:
- Распознавание текста с картинки — полный OCR документа в Markdown, когда нужен весь текст, а не факт нарушения
- Проверка ссылки — репутация URL: фишинг, вредонос, нежелательное ПО
- Проверка почты — синтаксис, MX-записи, одноразовые адреса и спам-ловушки
- Валидация телефона — приведение к E.164, тип номера, отсев премиум-номеров
- ИИ-чат — модели, сессии, суммаризация текста жалоб и обращений
- AML-скоринг криптокошелька — риск-балл, санкции и PEP для комплаенс-решений
Полный каталог — atlorium.com
- Документация API (Swagger): atlorium.com/imgAPI
- Описание сервиса: atlorium.com/imgDescription
- Веб-интерфейс: atlorium.com/imgGUI
- OpenAPI-спецификация: imagecheck_ru.json
- Поддержка: support@atlorium.com
MIT — берите код и используйте как хотите, в том числе в коммерческих проектах.