PerfectVector
Bởi Jay

Cách vector hóa ảnh bằng Python và lưu SVG qua API

Gửi PNG, JPEG hoặc WebP đến API vector hóa trong Python. Lưu SVG, xác minh phản hồi thử nghiệm và lấy lại kết quả nếu mất kết nối.

7 phút đọc
Trên trang này

Tập lệnh Python có thể gửi ảnh raster đến API vector hóa của PerfectVector rồi lưu SVG trả về cạnh tệp nguồn. Ví dụ dưới đây in ID chuyển đổi trước khi tải xuống. Nếu mất kết nối, bạn có thể lấy lại kết quả bằng ID hoặc khóa yêu cầu do bạn chọn.

Thử với hình ảnh của chính bạn
Mở công cụ đầy đủ
Dùng thử miễn phí. Thả ảnh vào để xem trước bản vector của bạn, không cần đăng ký.

Chuẩn bị khóa thử nghiệm và một ảnh

Tạo khóa thử nghiệm trên trang Developer API. Đặt khóa trong biến môi trường PERFECTVECTOR_API_KEY của terminal và giữ khóa ngoài tập lệnh cũng như hệ thống quản lý phiên bản. Cài Requests trong môi trường Python của dự án bằng python -m pip install requests.

Lần đầu, dùng PNG, JPEG hoặc WebP một khung hình, chẳng hạn logo 512 × 512 pixel tên logo.png. API nhận tệp tối đa 5 MiB và ảnh có mỗi cạnh từ 100 đến 4.096 pixel. Chế độ thử nghiệm kiểm tra tệp tải lên và trả một SVG cố định có nhãn “TEST MODE” mà không trừ lượt. Tệp này giúp xác minh việc gửi yêu cầu và tải xuống. Để đánh giá chất lượng vector hóa, hãy chuyển đổi thực tế ảnh của bạn. Chế độ thử nghiệm PerfectVector API

Chúng tôi chạy tập lệnh Python bằng khóa thử nghiệm, tải SVG xuống và đọc cấu trúc thành công. Khi gửi lại cùng tệp với cùng khóa yêu cầu, cả hai lần đều trả cùng ID chuyển đổi.

Minh họa quy trình
Tệp raster cục bộ đi qua một yêu cầu lên máy chủ có thẻ đánh dấu rồi trở về dưới dạng tệp vector trên đĩa.
Lưu khóa yêu cầu cùng lần tải lên và ghi ID chuyển đổi trước khi tải SVG xuống.

Gửi ảnh và lưu SVG bằng Python

Lưu đoạn sau thành vectorize.py. Đối số files yêu cầu Requests tạo lượt tải lên multipart, đưa dữ liệu tệp gốc vào trường biểu mẫu image. Tải lên multipart bằng 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])

Chạy từ thư mục chứa logo.png. Chọn một ID cho lần chuyển đổi và ghi lại trước khi chạy. API gọi đây là khóa chống gửi trùng (idempotency key), dùng để liên kết các lần gửi lại cùng tệp với một lần chuyển đổi. Ví dụ dùng logo-asset-0001. Dùng giá trị khác cho ảnh hoặc thao tác khác. Gửi lại an toàn với PerfectVector

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

Nếu lần thử thành công, tập lệnh in ID chuyển đổi và số byte rồi lưu logo.svg cạnh logo.png. Mở logo.svg để xác nhận tệp mẫu hiển thị được. Tập lệnh thay SVG trùng tên sau khi tải tệp mới xong. Hãy dùng thư mục tạm cho lần đầu.

Tập lệnh yêu cầu máy chủ đợi tối đa 10 giây trước khi trả về một lượt chuyển đổi chưa xong. Tập lệnh kiểm tra queued và processing khoảng hai giây một lần và chỉ tải khi trạng thái là succeeded. Chế độ thử nghiệm hoàn tất ngay, vì vậy hãy dùng phản hồi chưa hoàn tất từ bộ dữ liệu thử cục bộ để kiểm tra nhánh chờ trước khi dùng trong chương trình xử lý thực tế. Chờ và xử lý bất đồng bộ trong PerfectVector

Lấy lại kết quả khi hết thời gian chờ

Nếu Python đã in ID chuyển đổi, kiểm tra ID bằng GET /v1/vectorizations/{id}. Khi thành công, dùng GET /v1/vectorizations/{id}/result với cùng tài khoản và chế độ để tải SVG. Liên kết kết quả hết hạn sau 24 giờ kể từ khi hoàn tất, nên hãy sao chép tệp sang kho của bạn nếu cần dùng sau. Tải kết quả PerfectVector

Nếu Python dừng trước khi in ID, chạy lại lệnh với đúng dữ liệu tệp và khóa chống gửi trùng trong vòng 24 giờ kể từ yêu cầu đầu. API trả lần chuyển đổi hiện có nếu đã nhận lượt gửi ban đầu. Sau khoảng này, gửi cùng khóa có thể bắt đầu lần chuyển đổi mới. Gửi lại an toàn với PerfectVector

Thông báoNội dung cần kiểm tra
401 invalid_api_keyĐặt khóa thử nghiệm còn hiệu lực trong môi trường Python đang dùng. Nếu đã thu hồi khóa, tạo khóa thay thế cùng chế độ.
415 unsupported_media_type hoặc 422 invalid_imageMở tệp gốc để kiểm tra định dạng thực và kích thước pixel. Lưu ảnh đã sửa và dùng khóa riêng cho lần tải lên đó.
Có ID chuyển đổi rồi thấy processing_failedAPI đã tạo bản ghi nhưng không vector hóa được. Kiểm tra ảnh gốc rồi gửi tệp đã sửa như một thao tác mới.
409 idempotency_conflictCùng khóa đã được dùng với dữ liệu ảnh hoặc tùy chọn khác. Lấy lại kết quả bằng tệp gốc hoặc dùng khóa mới cho đầu vào mới.

Nếu cần liên hệ hỗ trợ, giữ ID yêu cầu từ thông báo lỗi hoặc ID chuyển đổi từ tập lệnh. Tài liệu lỗi API nêu các lỗi có thể thử lại an toàn.

Câu hỏi thường gặp

Python có thể dùng cùng tập lệnh để vector hóa JPEG hoặc WebP không?

Có. Truyền tệp JPEG hoặc WebP làm đối số đầu tiên. Quy tắc về dung lượng, kích thước và một khung hình vẫn áp dụng, đầu ra có phần mở rộng SVG.

Tôi có thể dùng ví dụ Python này cho cả thư mục không?

Dùng ví dụ để xác minh một lần tải lên và tải xuống trước. Với cả thư mục, ghi khóa, ID chuyển đổi và đường dẫn đầu ra cho từng tệp vào hàng đợi lưu bền vững. Mặc định, PerfectVector cho mỗi tài khoản thực hiện đồng thời một lần chuyển đổi thực tế. Hãy chờ lần đang chạy xong rồi mới gửi lần tiếp theo. Giới hạn PerfectVector API

Nguồn tham khảo

  1. Requests — Hướng dẫn bắt đầu — Tệp multipart, thời gian chờ và phản hồi dạng byte.
  2. PerfectVector — Chế độ thử nghiệm — Giới hạn tải lên, SVG mẫu cố định và cách tính lượt thử.
  3. PerfectVector — Chờ và xử lý bất đồng bộ — Tùy chọn thời gian chờ máy chủ, kiểm tra trạng thái và lúc yêu cầu thử kết thúc.
  4. PerfectVector — Chống gửi trùng — Thời hạn khóa, phạm vi, xung đột và quy tắc gửi lại.
  5. PerfectVector — Kết quả — Điểm cuối lấy kết quả, xác thực và hết hạn.
  6. PerfectVector — Lỗi — Mã lỗi HTTP và cách khôi phục.
  7. PerfectVector — Giới hạn — Số tác vụ thực tế đồng thời theo mặc định và giới hạn tệp.

Lấy khóa thử nghiệm từ trang PerfectVector API, chạy tập lệnh với một ảnh của bạn rồi kiểm tra SVG đã lưu mở được và terminal in ID chuyển đổi.

Thêm từ blog

PerfectVector

Biến hình ảnh thành
đường vector gọn sạch, dễ chỉnh sửa

Vector hóa và kiểm tra bản xem trước miễn phí, không giới hạn theo ngày.