Личный кабинет

Главная → Документация → Замазать лицо на фото

Как замазать или размыть лицо на фото

Находит лица людей на фото и закрывает их: замазывает цветом, размывает или закрывает мозаикой. Не нужно обводить каждое лицо вручную: несколько кликов в личном кабинете (с компьютера или телефона) или один запрос к API, до 10 фото за раз. Мелкие лица на дальнем плане и групповых снимках тоже находятся, фото остаётся в своём размере, метаданные (координаты съёмки, модель телефона) удаляются.

Хост api.avtovincod.ruМетод POST /face-hideДо 10 фото за запросСписание за фото с найденными лицами

Для чего

Определяется только, где на фото лицо, чтобы его закрыть. Лица не распознаются, не сравниваются и никуда не сохраняются.

Как замазать лицо на фото онлайн

  1. Зарегистрируйтесь в личном кабинете и пополните баланс.
  2. Откройте "Скрыть номер и лица на фото", выберите "Лица" и способ: размыть, мозаика или цвет.
  3. Загрузите фото (можно сразу несколько), нажмите "Скрыть лица" и скачайте готовые снимки по одному или архивом.

На iPhone и Android всё то же в браузере телефона: фото выбираются из галереи, приложение ставить не нужно, готовое фото сохраняется обратно в галерею.

Как закрыть лицо ребёнка на фото

Выберите "Лица" и способ "Заливка цветом" или "Размытие" с силой "сильнее": лица детей станут неузнаваемыми, а остальное фото останется как было. Так публикуют снимки школы, секции и лагеря, а родители - фото с праздников в общих чатах и соцсетях: лицо ребёнка не попадает в чужие руки и в поиск по фото. Если на снимке много детей, проверьте готовое фото глазами: лица в профиль или прикрытые рукой могут не найтись.

Чем закрыть лицо: размытие, мозаика или цвет

modeКак выглядит
blurразмытие (по умолчанию): лицо становится мягким пятном, черты не различить; сила - strength
pixelмозаика крупными блоками
fillовал цветом color поверх лица, например чёрный (color=000000) или фирменный

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

Аутентификация

Токен передаётся заголовком Authorization: Bearer <токен> либо параметром ?token=. Токен один для всех API, он выдаётся в личном кабинете сразу после регистрации.

Эндпоинт

POST https://api.avtovincod.ru/face-hide

Это тот же метод, что скрытие номера (/plate-hide), с target=faces по умолчанию: один токен, одна цена, одна история запросов.

Как передать фото

СпособКак
multipart/form-dataполе photo с файлом; несколько фото - поле photos[]
image/jpegодно фото в теле запроса как есть, заголовок Content-Type: image/jpeg (или image/png, image/webp)
application/json{"image": "<base64>"} или {"images": ["<base64>", ...]}; параметры можно передать в том же JSON

Параметры

ПараметрОписание
modeblur, pixel, fill; по умолчанию blur (можно передать и как faceMode)
colorцвет для fill, RRGGBB без решётки: 000000, 2b2b2b
strengthсила размытия и мозаики: 1 (по умолчанию), 2, 3
qualityкачество JPEG готового фото, 60-95 (по умолчанию 90)
formatimage - готовое фото в ответе (по умолчанию для одного фото); json - сведения и ссылка на фото; zip - архив с фото и result.json
inline1: в JSON вместе со ссылкой положить фото в base64 (поле image.base64)
targetна этом адресе по умолчанию faces; all - закрыть и госномера машин
test1: бесплатная проба - фото обрабатывается, но приходит уменьшенным (до 800 точек) и с пометкой TEST

Пример запроса

# одно фото: в ответе готовое фото с размытыми лицами
curl -X POST "https://api.avtovincod.ru/face-hide" \
  -H "Authorization: Bearer $TOKEN" \
  -F "photo=@photo.jpg" -o photo_hidden.jpg

# мозаика, несколько фото: JSON со ссылками на готовые фото
curl -X POST "https://api.avtovincod.ru/face-hide?mode=pixel&strength=2" \
  -H "Authorization: Bearer $TOKEN" \
  -F "photos[]=@1.jpg" -F "photos[]=@2.jpg" -F "photos[]=@3.jpg"

# лица и госномера машин одним запросом
curl -X POST "https://api.avtovincod.ru/plate-hide?target=all" \
  -H "Authorization: Bearer $TOKEN" \
  -F "photo=@street.jpg" -o street_hidden.jpg

Ответ

По умолчанию для одного фото в ответе само готовое фото, сведения - в заголовках.

HTTP/1.1 200 OK
Content-Type: image/jpeg
Content-Disposition: inline; filename="photo_hidden.jpg"
X-Plates-Found: 0
X-Faces-Found: 3
X-Charged: 0.5
X-Balance: 999.5
X-Request-Id: 1234567
X-Result-Url: https://api.avtovincod.ru/plate-hide/file?id=1234567&until=...&sig=...

<байты готового фото>

С format=json приходят сведения и ссылка на фото:

{
  "success": 1,
  "name": "photo",
  "found": 1,
  "target": "faces",
  "platesCount": 0,
  "facesCount": 3,
  "needsReview": false,
  "plates": [],
  "faces": [
    { "box": [812, 240, 904, 351], "confidence": 0.92 },
    { "box": [1210, 288, 1281, 374], "confidence": 0.88 },
    { "box": [355, 610, 391, 655], "confidence": 0.74 }
  ],
  "image": {
    "contentType": "image/jpeg",
    "width": 1600,
    "height": 1200,
    "bytes": 301245,
    "url": "https://api.avtovincod.ru/plate-hide/file?id=1234567&until=1792400000&sig=...",
    "urlExpiresAt": "2026-10-19T12:00:00+03:00"
  },
  "requestId": 1234567,
  "charged": 0.5,
  "billing": { "charged": 0.5, "currency": "RUB", "billed": true, "balance": 999.5, "requestId": 1234567 }
}

Поля ответа

ПолеЗначение
found1: закрыто хотя бы одно лицо (фото платное), 0: лиц не найдено
facesCount / facesсколько лиц закрыто и где: box - рамка [x1, y1, x2, y2] в точках фото (после поворота по EXIF), confidence - уверенность 0-1
targetfaces
platesCount / plates0 и пустой список: номера на этом адресе не ищутся
imageготовое фото: тип, размер, байты, url для скачивания (24 часа) и urlExpiresAt; base64 при inline=1
requestId / chargedномер в истории запросов и сколько списано за это фото

Несколько фото (photos[], до 10) - ответ JSON со списком results в том же виде и общим блоком billing, с format=zip - архив. Каждое фото оплачивается отдельно, ошибка одного не мешает остальным. Формат такой же, как у скрытия номера.

Какое фото подходит

Коды ошибок

КодЗначение
NO_TOKENтокен не передан
TOKEN_INVALIDтокен недействителен или деактивирован
NOT_ALLOWEDметод не подключён вашему токену
API_DISABLEDметод временно отключён
IP_NOT_ALLOWEDзапрос с IP вне вашего белого списка
METHOD_POSTзапрос не POST
NO_PHOTOфото не передано или пустое
BAD_PHOTOфайл не удалось прочитать как фото (JPEG, PNG, WebP)
PHOTO_TOO_SMALLфото меньше 64 на 64 точки
PHOTO_TOO_BIGфайл больше 20 МБ, фото больше 40 мегапикселей или запрос больше допустимого (HTTP 413)
TOO_MANY_PHOTOSбольше 10 фото в одном запросе
BAD_MODEmode=logo вместе с target=faces: логотип ставится только на номер
INSUFFICIENT_BALANCEнедостаточно средств на все фото запроса
RATE_LIMITпревышен лимит запросов в минуту
SERVICE_UNAVAILABLEобработка временно недоступна, повторите позже (HTTP 503)
TIMEOUTфото пакета не успело обработаться за время запроса, отправьте его ещё раз
LINK_INVALID / FILE_GONEссылка на готовое фото неверная или её срок (24 часа) вышел
BAD_MODEmode=logo: логотип ставится только на номер, для лиц - blur, pixel или fill

Ошибка приходит в виде {"success": 0, "error": "...", "code": "..."} и не тарифицируется.

Примеры кода: PHP, Python, JavaScript, Go, Java, C#, Ruby, 1С

Примеры готовы к запуску: токен из переменной окружения AVC_TOKEN, фото из файла photo.jpg, результат в photo_hidden.jpg. В адресе стоит test=1: фото обрабатывается бесплатно, но приходит уменьшенным и с пометкой TEST. Уберите test=1 для настоящей обработки.

curl -s --max-time 45 -X POST "https://api.avtovincod.ru/face-hide?test=1&mode=blur" \
  -H "Authorization: Bearer $AVC_TOKEN" \
  -F "photo=@photo.jpg" -o photo_hidden.jpg
<?php
$ch = curl_init('https://api.avtovincod.ru/face-hide?test=1&mode=blur');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => ['photo' => new CURLFile('photo.jpg', 'image/jpeg')],
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . getenv('AVC_TOKEN')],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 45,
]);
$img = curl_exec($ch);
$type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
if (strpos((string)$type, 'image/') === 0) {
    file_put_contents('photo_hidden.jpg', $img);       // лица закрыты
} else {
    echo json_decode($img, true)['error'] ?? 'ошибка', PHP_EOL;
}
import os, requests

with open("photo.jpg", "rb") as f:
    r = requests.post("https://api.avtovincod.ru/face-hide", params={"test": 1, "mode": "blur"},
                      headers={"Authorization": "Bearer " + os.environ["AVC_TOKEN"]},
                      files={"photo": ("photo.jpg", f, "image/jpeg")}, timeout=45)
if r.headers.get("Content-Type", "").startswith("image/"):
    open("photo_hidden.jpg", "wb").write(r.content)
    print("лиц закрыто:", r.headers.get("X-Faces-Found"))
else:
    print(r.json().get("error"))
// Node.js 18+
import { readFile, writeFile } from "node:fs/promises";

const form = new FormData();
form.append("photo", new Blob([await readFile("photo.jpg")], { type: "image/jpeg" }), "photo.jpg");
const res = await fetch("https://api.avtovincod.ru/face-hide?test=1&mode=blur", {
  method: "POST",
  headers: { Authorization: "Bearer " + process.env.AVC_TOKEN },
  body: form,
  signal: AbortSignal.timeout(45000),
});
if ((res.headers.get("content-type") || "").startsWith("image/")) {
  await writeFile("photo_hidden.jpg", Buffer.from(await res.arrayBuffer()));
  console.log("лиц закрыто:", res.headers.get("x-faces-found"));
} else {
  console.log((await res.json()).error);
}
package main

import (
	"bytes"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"os"
	"time"
)

func main() {
	var buf bytes.Buffer
	w := multipart.NewWriter(&buf)
	part, _ := w.CreateFormFile("photo", "photo.jpg")
	f, err := os.Open("photo.jpg")
	if err != nil {
		panic(err)
	}
	io.Copy(part, f)
	f.Close()
	w.Close()

	req, _ := http.NewRequest("POST", "https://api.avtovincod.ru/face-hide?test=1&mode=blur", &buf)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("AVC_TOKEN"))
	req.Header.Set("Content-Type", w.FormDataContentType())
	res, err := (&http.Client{Timeout: 45 * time.Second}).Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	os.WriteFile("photo_hidden.jpg", body, 0644)
	fmt.Println("лиц закрыто:", res.Header.Get("X-Faces-Found"))
}
// Java 11+: фото в теле запроса как есть (Content-Type: image/jpeg)
import java.net.URI;
import java.net.http.*;
import java.nio.file.Path;
import java.time.Duration;

public class Main {
    public static void main(String[] args) throws Exception {
        HttpRequest req = HttpRequest.newBuilder(URI.create("https://api.avtovincod.ru/face-hide?test=1&mode=blur"))
            .header("Authorization", "Bearer " + System.getenv("AVC_TOKEN"))
            .header("Content-Type", "image/jpeg")
            .timeout(Duration.ofSeconds(45))
            .POST(HttpRequest.BodyPublishers.ofFile(Path.of("photo.jpg")))
            .build();
        HttpResponse<Path> res = HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofFile(Path.of("photo_hidden.jpg")));
        System.out.println("лиц закрыто: " + res.headers().firstValue("X-Faces-Found").orElse("?"));
    }
}
using System.Net.Http.Headers;

using var http = new HttpClient { Timeout = TimeSpan.FromSeconds(45) };
http.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("AVC_TOKEN"));
var body = new ByteArrayContent(await File.ReadAllBytesAsync("photo.jpg"));
body.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
var res = await http.PostAsync("https://api.avtovincod.ru/face-hide?test=1&mode=blur", body);
if (res.Content.Headers.ContentType?.MediaType?.StartsWith("image/") == true)
    await File.WriteAllBytesAsync("photo_hidden.jpg", await res.Content.ReadAsByteArrayAsync());
else
    Console.WriteLine(await res.Content.ReadAsStringAsync());
require "net/http"

uri = URI("https://api.avtovincod.ru/face-hide?test=1&mode=blur")
req = Net::HTTP::Post.new(uri, "Authorization" => "Bearer #{ENV['AVC_TOKEN']}", "Content-Type" => "image/jpeg")
req.body = File.binread("photo.jpg")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true, read_timeout: 45) { |h| h.request(req) }
if res["Content-Type"].to_s.start_with?("image/")
  File.binwrite("photo_hidden.jpg", res.body)
else
  puts res.body
end
Токен = "ВАШ_ТОКЕН";
Соединение = Новый HTTPСоединение("api.avtovincod.ru", , , , , 45, Новый ЗащищенноеСоединениеOpenSSL);
Запрос = Новый HTTPЗапрос("/face-hide?test=1&mode=blur");
Запрос.Заголовки.Вставить("Authorization", "Bearer " + Токен);
Запрос.Заголовки.Вставить("Content-Type", "image/jpeg");
Запрос.УстановитьТелоИзДвоичныхДанных(Новый ДвоичныеДанные("C:\Фото\photo.jpg"));
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Если СтрНачинаетсяС(Ответ.Заголовки.Получить("Content-Type"), "image/") Тогда
    Ответ.ПолучитьТелоКакДвоичныеДанные().Записать("C:\Фото\photo_hidden.jpg");
Иначе
    Сообщить(Ответ.ПолучитьТелоКакСтроку("UTF-8"));
КонецЕсли;

Бесплатных тестовых периодов и долгих согласований нет: пополните баланс в личном кабинете и сразу обрабатывайте реальные фото.

Тарификация

Оплата за каждое фото, на котором найдено и закрыто хотя бы одно лицо. Лиц нет, ошибка, сервис недоступен: бесплатно. Перед обработкой проверяется, что баланса хватает на все фото запроса. Актуальная цена в личном кабинете.

В ответе JSON есть блок billing, те же данные в заголовках X-Charged, X-Balance, X-Request-Id. Подробнее о блоке billing.

Хранение фото

Исходный файл не хранится нигде: он используется только для ответа на ваш запрос. Готовое фото (лица уже закрыты, метаданных нет) хранится 24 часа, чтобы его можно было скачать по ссылке из ответа, затем удаляется автоматически. Ссылка подписана и действует только до указанного в ней срока.

Смежные методы

Частые вопросы

Как размыть лицо на фото автоматически?

Отправьте фото POST-запросом на https://api.avtovincod.ru/face-hide с токеном (поле photo в multipart/form-data). В ответ придёт то же фото, на котором все найденные лица размыты. Без программиста: в личном кабинете откройте "Скрыть номер и лица на фото", выберите "Лица" и загрузите снимки.

Как замазать лицо на фото на айфоне или андроиде?

Откройте личный кабинет avtovincod.ru/lk в браузере телефона, раздел "Скрыть номер и лица на фото", выберите "Лица", загрузите снимки из галереи и скачайте готовые. Приложение ставить не нужно, лица находятся сами, обводить их пальцем не надо.

Можно ли не размыть, а замазать лицо цветом или мозаикой?

Да: mode=pixel - мозаика, mode=fill - овал цветом color (например color=000000), mode=blur - размытие (по умолчанию). Сила размытия и мозаики - strength от 1 до 3.

Найдутся ли мелкие лица на групповом фото?

Да, большие фото проверяются по частям почти в натуральную величину, а небольшие дополнительно в увеличенном виде, поэтому находятся и лица на дальнем плане. Лица в профиль, сильно закрытые (маска, капюшон, рука) или совсем крошечные могут не найтись: если это важно, смотрите facesCount и само фото.

Сколько стоит и за что списываются деньги?

За каждое фото, на котором найдено и закрыто хотя бы одно лицо, по цене метода в личном кабинете. Лиц нет, ошибка, сервис недоступен: бесплатно.

Можно ли закрыть сразу и лица, и номера машин?

Да: target=all на адресе /plate-hide закрывает и госномера, и лица одним запросом. Подробно о номерах: Скрыть номер машины на фото.

Храните ли вы фото людей?

Исходный файл не хранится нигде. Готовое фото (лица уже закрыты, метаданных нет) держим 24 часа, чтобы его можно было скачать по ссылке из ответа, затем оно удаляется автоматически. Лица не сравниваются и не распознаются: определяется только, где на фото лицо, чтобы его закрыть.

Попробовать без программиста

В личном кабинете откройте "Скрыть номер и лица на фото", выберите "Лица", загрузите сразу несколько снимков и скачайте всё архивом.

Открыть кабинет