PerfectVector
โดย Jay

ใช้ Python กับ API แปลงภาพเป็นเวกเตอร์และบันทึก SVG

ส่ง PNG, JPEG หรือ WebP ไปยัง API แปลงเวกเตอร์จาก Python บันทึก SVG ตรวจผลทดสอบ และเรียกคืนผลเดิมเมื่อการเชื่อมต่อหลุด

อ่าน 3 นาที
ในหน้านี้

สคริปต์ Python ส่งภาพแรสเตอร์ไปยัง PerfectVector API แล้วบันทึก SVG ที่ได้ไว้ข้างไฟล์ต้นฉบับได้ ตัวอย่างนี้พิมพ์ ID การแปลงก่อนดาวน์โหลด หากการเชื่อมต่อหลุด คุณเรียกคืนผลได้ด้วย ID นี้หรือคีย์คำขอที่กำหนดเอง

ลองกับรูปภาพของคุณเอง
เปิดเครื่องมือฉบับเต็ม
ลองใช้ฟรี วางรูปภาพเพื่อดูตัวอย่างเวกเตอร์ของคุณได้เลย ไม่ต้องสมัครสมาชิก

เตรียมคีย์ทดสอบและภาพหนึ่งไฟล์

สร้างคีย์ทดสอบจากหน้า Developer API ตั้งค่าในเทอร์มินัลเป็น PERFECTVECTOR_API_KEY โดยไม่ใส่คีย์ในสคริปต์หรือระบบควบคุมเวอร์ชัน ติดตั้ง Requests ในสภาพแวดล้อม Python ของโครงการด้วย python -m pip install requests

รอบแรกให้ใช้ PNG, JPEG หรือ WebP แบบเฟรมเดียว เช่น โลโก้ขนาด 512 × 512 พิกเซลชื่อ logo.png API รับไฟล์ไม่เกิน 5 MiB และแต่ละด้านยาว 100–4,096 พิกเซล โหมดทดสอบตรวจไฟล์ที่อัปโหลดและคืน SVG คงที่ที่มีข้อความ “TEST MODE” โดยไม่คิดเครดิต ใช้ไฟล์นี้ยืนยันว่าการส่งคำขอและดาวน์โหลดทำงาน แล้วประเมินคุณภาพจากการแปลงภาพจริงของคุณ โหมดทดสอบ PerfectVector API

เรารันสคริปต์ Python ด้วยคีย์ทดสอบ ดาวน์โหลด SVG ที่อ่านโครงสร้างได้ แล้วส่งไฟล์เดิมด้วยคีย์คำขอเดิม ทั้งสองครั้งได้ 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 กำหนด ID สำหรับการแปลงและจดไว้ก่อนรัน API เรียกว่า คีย์ป้องกันการส่งซ้ำ หรือ idempotency key ซึ่งเชื่อมการส่งไฟล์เดิมซ้ำกับการแปลงรายการเดียวกัน ตัวอย่างใช้ logo-asset-0001 ให้ใช้ค่าอื่นสำหรับภาพหรือการดำเนินการใหม่ การส่งซ้ำอย่างปลอดภัยของ PerfectVector

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

เมื่อทดสอบสำเร็จ สคริปต์จะพิมพ์ ID การแปลงและจำนวนไบต์ แล้วบันทึก logo.svg ไว้ข้าง logo.png เปิด logo.svg เพื่อตรวจว่าตัวอย่างแสดงได้ สคริปต์จะแทนที่ SVG ชื่อเดิมเมื่อดาวน์โหลดไฟล์ใหม่เสร็จ ใช้โฟลเดอร์ชั่วคราวสำหรับการทดสอบครั้งแรก

สคริปต์ขอให้เซิร์ฟเวอร์รอได้ถึง 10 วินาทีก่อนคืนรายการที่ยังไม่เสร็จ สคริปต์ตรวจสถานะ queued และ processing ทุกประมาณสองวินาที และดาวน์โหลดเมื่อเป็น succeeded เท่านั้น โหมดทดสอบแปลงเสร็จทันที จึงควรใช้ผลตอบกลับจำลองที่ยังไม่เสร็จเพื่อทดสอบส่วนตรวจสถานะในเครื่องก่อนใช้ในตัวประมวลผลงานจริง การรอและการประมวลผลแบบอะซิงโครนัส

เรียกคืนผลเมื่อหมดเวลารอ

ถ้า Python พิมพ์ ID การแปลงแล้ว ให้ตรวจ ID ด้วย GET /v1/vectorizations/{id} เมื่อสำเร็จ ใช้ GET /v1/vectorizations/{id}/result ด้วยบัญชีและโหมดเดิมเพื่อดาวน์โหลด SVG ลิงก์ผลลัพธ์หมดอายุ 24 ชั่วโมงหลังแปลงเสร็จ หากต้องใช้ภายหลัง ให้คัดลอกไฟล์ไปยังที่เก็บของคุณ ดาวน์โหลดผลจาก PerfectVector

ถ้า Python หยุดก่อนพิมพ์ 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

คำถามที่พบบ่อย

ใช้สคริปต์ Python เดิมแปลง 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

เปลี่ยนรูปภาพเป็น
เส้นพาธเวกเตอร์ที่เรียบร้อยและแก้ไขได้

แปลงเวกเตอร์และตรวจดูพรีวิวได้ฟรี ไม่จำกัดจำนวนครั้งต่อวัน