PerfectVector
Автор: Jay

Векторизация изображения в Python через API

Отправьте PNG, JPEG или WebP в API векторизации из Python. Сохраните SVG, проверьте тестовый ответ и восстановите ту же конвертацию при обрыве связи.

5 мин чтения
На этой странице

Скрипт Python может отправить растровое изображение в PerfectVector API и сохранить полученный SVG рядом с исходником. Пример ниже выводит ID конвертации до скачивания. Если связь оборвётся, по этому ID или выбранному вами ключу запроса можно восстановить результат.

Попробуйте на своём изображении
Открыть полный инструмент
Бесплатно и без регистрации: перетащите изображение, чтобы увидеть превью своего вектора.

Получите тестовый ключ и подготовьте изображение

Создайте тестовый ключ на странице Developer API. Задайте его в терминале в переменной PERFECTVECTOR_API_KEY и не добавляйте в скрипт или систему контроля версий. Установите Requests в окружение Python своего проекта командой python -m pip install requests.

Для первого запуска возьмите однофреймовый PNG, JPEG или WebP. Подойдёт логотип logo.png размером 512 × 512 пикселей. API принимает файлы до 5 МиБ и изображения от 100 до 4096 пикселей по каждой стороне. В тестовом режиме API проверяет загрузку и бесплатно возвращает фиксированный SVG с надписью «TEST MODE». Файл позволяет проверить запрос и скачивание. Для оценки трассировки своего изображения выполните рабочую конвертацию. Тестовый режим PerfectVector API

Мы запустили скрипт с тестовым ключом, скачали корректный SVG и повторили загрузку с тем же ключом запроса. В обоих случаях API вернул один и тот же ID конвертации.

Схема работы
Локальный растровый файл передаётся в облачный запрос с меткой и возвращается на диск как векторный файл.
Храните ключ запроса вместе с данными о загрузке и запишите ID конвертации перед скачиванием SVG.

Отправьте изображение и сохраните SVG из Python

Сохраните код в файл vectorize.py. Аргумент files указывает Requests сформировать multipart-запрос с исходными байтами в поле формы image. Multipart-запросы в Requests

import os
import sys
import time
from pathlib import Path
 
import requests
 
API = "https://api.perfectvector.com/v1"
AUTH = {"Authorization": f"Bearer {os.environ['PERFECTVECTOR_API_KEY']}"}
 
 
def checked(response):
    content_type = response.headers.get("Content-Type", "").split(";")[0]
    if response.status_code >= 400 and content_type == "application/problem+json":
        problem = response.json()
        raise RuntimeError(f"{problem['code']} (request {problem['request_id']})")
    response.raise_for_status()
    return response
 
 
def vectorize(source, destination, operation_id):
    with source.open("rb") as image:
        response = checked(requests.post(
            f"{API}/vectorizations",
            headers={**AUTH, "Idempotency-Key": operation_id, "Prefer": "wait=10"},
            files={"image": (source.name, image)},
            timeout=30,
        ))
 
    conversion = response.json()
    conversion_id = conversion["id"]
    print(f"Conversion ID: {conversion_id}", flush=True)
    deadline = time.monotonic() + 720
    while conversion["status"] in {"queued", "processing"}:
        if time.monotonic() >= deadline:
            raise TimeoutError(f"Stopped polling {conversion_id}")
        time.sleep(2)
        conversion = checked(requests.get(
            f"{API}/vectorizations/{conversion_id}", headers=AUTH, timeout=30,
        )).json()
 
    if conversion["status"] != "succeeded":
        error = conversion["results"][0].get("error") or {}
        raise RuntimeError(f"{conversion_id}: {error.get('code', conversion['status'])}")
 
    svg = checked(requests.get(
        f"{API}/vectorizations/{conversion_id}/result", headers=AUTH, timeout=30,
    ))
    if svg.headers.get("Content-Type", "").split(";")[0] != "image/svg+xml":
        raise ValueError("Expected an SVG response")
    partial = destination.with_suffix(".svg.part")
    partial.write_bytes(svg.content)
    partial.replace(destination)
    print(f"{destination} saved ({len(svg.content)} bytes)")
 
 
if __name__ == "__main__":
    source = Path(sys.argv[1])
    if source.suffix.lower() not in {".png", ".jpg", ".jpeg", ".webp"}:
        raise SystemExit("Choose a PNG, JPEG or WebP file")
    if source.stat().st_size > 5 * 1024 * 1024:
        raise SystemExit("Choose a file no larger than 5 MiB")
    vectorize(source, source.with_suffix(".svg"), sys.argv[2])

Запустите команду из папки с файлом logo.png. Выберите идентификатор для этой операции и запишите его перед запуском. В API он называется ключом идемпотентности и связывает повторные отправки с одной конвертацией. В примере используется logo-asset-0001. Для другого изображения или другой операции выберите новый ключ. Безопасные повторы в PerfectVector

python vectorize.py logo.png logo-asset-0001

При успешном тесте скрипт выводит ID конвертации и число байтов, а рядом с logo.png появляется logo.svg. Откройте logo.svg и проверьте, что он отображается. Скрипт заменяет уже существующий одноимённый SVG после скачивания нового. Для первого запуска используйте временную папку.

Скрипт просит сервер подождать до 10 секунд, прежде чем вернуть незавершённую конвертацию. Он опрашивает задачи в состояниях queued и processing примерно каждые две секунды и начинает скачивание при статусе succeeded. Тестовые конвертации завершаются сразу. Для проверки ветки опроса перед использованием в рабочем обработчике подставьте локальный тестовый ответ с незавершённой задачей. Ожидание и асинхронные запросы PerfectVector

Восстановите конвертацию после тайм-аута

Если Python вывел ID, проверьте его запросом GET /v1/vectorizations/{id}. После успеха скачайте SVG через GET /v1/vectorizations/{id}/result в том же аккаунте и режиме. Ссылка действует 24 часа после завершения. Если файл нужен позже, сохраните его в своём хранилище. Скачивание результатов PerfectVector

Если скрипт остановился до вывода ID, повторите команду с теми же байтами и ключом идемпотентности в течение 24 часов после первого запроса. Если API принял исходную загрузку, он вернёт существующую конвертацию. После окончания окна запрос с тем же ключом может начать новую. Безопасные повторы в PerfectVector

Что вы видитеЧто проверить
401 invalid_api_keyЗадайте действующий тестовый ключ в окружении Python. Если ключ отозван, создайте новый в том же режиме.
415 unsupported_media_type или 422 invalid_imageОткройте исходник и проверьте фактический формат и размеры в пикселях. Сохраните исправленный файл и назначьте загрузке новый ключ.
После ID конвертации появляется processing_failedAPI создал запись, но трассировка не удалась. Проверьте исходник и отправьте исправленный файл как новую операцию.
409 idempotency_conflictС тем же ключом отправлены другие байты или параметры. Для восстановления используйте исходный файл. Для новых данных задайте новый ключ.

Если потребуется помощь, сохраните ID запроса из исключения или ID конвертации, выведенный скриптом. В справочнике ошибок API указано, какие запросы можно безопасно повторять.

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

Можно ли этим же скриптом векторизовать JPEG или WebP?

Да. Передайте файл JPEG или WebP первым аргументом. Действуют те же требования к объёму, размерам и одному кадру. Результат сохраняется с расширением SVG.

Подойдёт ли этот пример Python для целой папки?

Сначала проверьте одну загрузку и одно скачивание. Для папки храните ключ, ID конвертации и путь к результату каждого файла в постоянной очереди. По умолчанию PerfectVector допускает одну активную рабочую конвертацию на аккаунт. Дождитесь завершения текущей перед отправкой следующей. Ограничения PerfectVector API

Источники

  1. Requests — краткое руководство — multipart-файлы, тайм-ауты и байты ответа.
  2. PerfectVector — тестовый режим — ограничения загрузки, фиксированный SVG и расходы в тестовом режиме.
  3. PerfectVector — ожидание и асинхронная работа — ожидание на сервере, опрос и завершение тестового запроса.
  4. PerfectVector — идемпотентность — срок действия ключа, область действия, конфликты и повторы.
  5. PerfectVector — результаты — адрес результата, аутентификация и срок действия.
  6. PerfectVector — ошибки — коды HTTP и способы восстановления.
  7. PerfectVector — ограничения — лимиты одновременных рабочих конвертаций и ограничения файлов.

Получите тестовый ключ на странице PerfectVector API, запустите скрипт со своим изображением и проверьте, что SVG открывается, а в терминале выведен ID конвертации.

Ещё из блога

PerfectVector

Превратите изображение в
чистые редактируемые контуры

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