Chuyển đến nội dung chính

第 20 課:列印檔案優化 — RGB→CMYK、DPI、超解析度

將設計從螢幕 (RGB) 轉換為列印就緒 (CMYK),透過 Real-ESRGAN、顏色設定檔管理確保 DPI、AI 高檔。 ICC 設定檔、色域映射。

🧠 人工智慧與機器學習 — 第 19 課 第 20 課:列印文件優化 — RGB→CMYK、DPI、超分辨率

人工智慧在行動:建構時尚和按需印刷的人工智慧平台

第 6 部分:生產流程中的人工智慧

亞洲開發網

簡介

在螢幕上看起來不錯的設計在列印上可能並不好看。本文處理列印製作流程:標準 RGB → CMYK 轉換,確保最低 DPI 為 300,以及使用 Real-ESRGAN 的 AI 高檔低解析度設計。


1. 印刷生產流程

User Design (RGB, 72-150 DPI)
        │
        ▼
┌──────────────────────┐
│ 1. Quality Assessment │  ← Check DPI, resolution, artifacts
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│ 2. AI Super Resolution│  ← Real-ESRGAN upscale (if needed)
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│ 3. Color Conversion   │  ← RGB → CMYK với ICC profile
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│ 4. Print File Export  │  ← TIFF/PDF, 300+ DPI, CMYK
└──────────────────────┘

2. 品質評估

from PIL import Image
import numpy as np

class PrintQualityAssessor:
    """Đánh giá chất lượng design cho print"""

    # DPI thresholds cho các phương pháp in
    MIN_DPI = {
        "dtg": 300,           # Direct-to-Garment
        "screen_print": 300,  # Screen Printing
        "sublimation": 150,   # Sublimation
        "vinyl": 72,          # Vinyl Cut
    }

    def assess(
        self,
        image: Image.Image,
        target_size_cm: tuple[float, float],
        print_method: str = "dtg",
    ) -> PrintQualityReport:
        width_px, height_px = image.size
        target_w_cm, target_h_cm = target_size_cm

        # Calculate actual DPI at target size
        dpi_w = width_px / (target_w_cm / 2.54)
        dpi_h = height_px / (target_h_cm / 2.54)
        actual_dpi = min(dpi_w, dpi_h)

        required_dpi = self.MIN_DPI[print_method]

        # Calculate upscale needed
        if actual_dpi < required_dpi:
            scale_factor = required_dpi / actual_dpi
            needs_upscale = True
        else:
            scale_factor = 1.0
            needs_upscale = False

        # Check for artifacts
        artifacts = self._detect_artifacts(image)

        return PrintQualityReport(
            actual_dpi=actual_dpi,
            required_dpi=required_dpi,
            needs_upscale=needs_upscale,
            scale_factor=scale_factor,
            artifacts=artifacts,
            is_print_ready=actual_dpi >= required_dpi and not artifacts,
        )

    def _detect_artifacts(
        self, image: Image.Image
    ) -> list[str]:
        """Detect common image artifacts"""
        issues = []
        img_array = np.array(image)

        # Check JPEG artifacts (blockiness)
        if self._detect_blockiness(img_array) > 0.3:
            issues.append("jpeg_artifacts")

        # Check if too small
        if min(image.size) < 500:
            issues.append("very_low_resolution")

        # Check transparency issues
        if image.mode == "RGBA":
            alpha = np.array(image.split()[3])
            if np.any((alpha > 0) & (alpha < 255)):
                issues.append("semi_transparent_pixels")

        return issues

3. AI超解析度(Real-ESRGAN)

import torch
from basicsr.archs.rrdbnet_arch import RRDBNet
from realesrgan import RealESRGANer

class AIUpscaler:
    """AI-powered image upscaling cho print"""

    def __init__(self):
        # RealESRGAN x4 model
        model = RRDBNet(
            num_in_ch=3, num_out_ch=3,
            num_feat=64, num_block=23,
            num_grow_ch=32, scale=4,
        )
        self.upsampler = RealESRGANer(
            scale=4,
            model_path="models/RealESRGAN_x4plus.pth",
            model=model,
            tile=400,       # Process in tiles (GPU memory)
            tile_pad=10,
            pre_pad=0,
            half=True,      # FP16 for speed
        )

    def upscale(
        self,
        image: Image.Image,
        target_scale: float,
    ) -> Image.Image:
        """
        Upscale image by target_scale factor

        Real-ESRGAN supports 4x natively.
        For other scales, upscale 4x then resize.
        """
        img_array = np.array(image.convert("RGB"))

        # Upscale 4x
        output, _ = self.upsampler.enhance(
            img_array, outscale=4
        )

        result = Image.fromarray(output)

        # If target < 4x, downscale to exact size
        if target_scale < 4:
            new_size = (
                int(image.width * target_scale),
                int(image.height * target_scale),
            )
            result = result.resize(
                new_size, Image.Resampling.LANCZOS
            )

        return result

    def upscale_for_print(
        self,
        image: Image.Image,
        target_size_cm: tuple[float, float],
        target_dpi: int = 300,
    ) -> Image.Image:
        """Upscale to exact print size + DPI"""
        target_w_px = int(target_size_cm[0] / 2.54 * target_dpi)
        target_h_px = int(target_size_cm[1] / 2.54 * target_dpi)

        # Calculate needed scale
        scale_w = target_w_px / image.width
        scale_h = target_h_px / image.height
        scale = max(scale_w, scale_h)

        if scale <= 1.0:
            # Already big enough, just resize
            return image.resize(
                (target_w_px, target_h_px),
                Image.Resampling.LANCZOS,
            )

        # Multi-pass upscale if scale > 4x
        current = image
        while scale > 1.0:
            step_scale = min(scale, 4.0)
            current = self.upscale(current, step_scale)
            scale /= 4.0

        # Final resize to exact dimensions
        return current.resize(
            (target_w_px, target_h_px),
            Image.Resampling.LANCZOS,
        )

4. RGB → CMYK 轉換

from PIL import ImageCms

class ColorConverter:
    """Convert RGB → CMYK với ICC profile"""

    def __init__(self):
        # ICC profiles
        self.srgb_profile = ImageCms.createProfile("sRGB")
        self.cmyk_profile = ImageCms.getOpenProfile(
            "profiles/USWebCoatedSWOP.icc"
        )

    def rgb_to_cmyk(
        self,
        image: Image.Image,
        rendering_intent: int = ImageCms.Intent.RELATIVE_COLORIMETRIC,
    ) -> Image.Image:
        """
        Convert RGB → CMYK sử dụng ICC profiles

        Rendering Intents:
        - PERCEPTUAL (0): Giữ overall look, tốt cho photos
        - RELATIVE_COLORIMETRIC (1): Accurate colors, default
        - SATURATION (2): Vivid colors, tốt cho graphics
        - ABSOLUTE_COLORIMETRIC (3): Exact match
        """
        # Ensure RGB input
        if image.mode == "RGBA":
            # Flatten alpha onto white background
            background = Image.new("RGB", image.size, (255, 255, 255))
            background.paste(image, mask=image.split()[3])
            image = background
        elif image.mode != "RGB":
            image = image.convert("RGB")

        # Create transform
        transform = ImageCms.buildTransformFromOpenProfiles(
            self.srgb_profile,
            self.cmyk_profile,
            "RGB",
            "CMYK",
            renderingIntent=rendering_intent,
        )

        # Apply transform
        cmyk_image = ImageCms.applyTransform(image, transform)

        return cmyk_image

    def check_gamut(
        self, image: Image.Image
    ) -> GamutReport:
        """Check which colors are out of CMYK gamut"""
        img_array = np.array(image.convert("RGB"))

        out_of_gamut = 0
        total = img_array.shape[0] * img_array.shape[1]

        for y in range(0, img_array.shape[0], 10):
            for x in range(0, img_array.shape[1], 10):
                r, g, b = img_array[y, x]
                if self._is_out_of_gamut(r, g, b):
                    out_of_gamut += 1

        return GamutReport(
            total_pixels_sampled=total // 100,
            out_of_gamut_pixels=out_of_gamut,
            percentage=out_of_gamut / (total // 100) * 100,
        )

5. 列印文件匯出管道

class PrintFileExporter:
    """Export print-ready files"""

    async def export(
        self,
        design: Image.Image,
        product_type: str,
        size: str,
        print_method: str = "dtg",
    ) -> PrintFile:
        # 1. Get print specs
        specs = self._get_print_specs(product_type, size)

        # 2. Assess quality
        quality = assessor.assess(
            design, specs.print_area_cm, print_method
        )

        # 3. Upscale if needed
        if quality.needs_upscale:
            design = upscaler.upscale_for_print(
                design, specs.print_area_cm, specs.dpi
            )

        # 4. Convert color space
        cmyk_design = color_converter.rgb_to_cmyk(design)

        # 5. Export TIFF
        output_path = f"print_files/{uuid4()}.tiff"
        cmyk_design.save(
            output_path,
            format="TIFF",
            dpi=(specs.dpi, specs.dpi),
            compression="lzw",
        )

        return PrintFile(
            path=output_path,
            dpi=specs.dpi,
            color_space="CMYK",
            size_cm=specs.print_area_cm,
        )

總結

列印檔案優化:

  1. 品質評估 — DPI 檢查、偽影檢測
  2. Real-ESRGAN — AI 高檔 4x,多通道 > 4x
  3. 顏色轉換 — ICC配置檔RGB→CMYK,色域檢查
  4. 列印匯出 — TIFF/PDF、300 DPI、LZW 壓縮

下一篇文章:人工智慧自動標記 — 自動標記和分類設計。