Làm chủ OpenSeadragon Bài 2: Kiến trúc dữ liệu Deep Zoom (DZI) - Cách cắt một bức ảnh Gigapixel thành hàng ngàn mảnh nhỏ (tiles) bằng các công cụ như VIPS.
Chào mừng bạn đến với Bài 2 của series. Ở bài trước, chúng ta đã biết OpenSeadragon cần một cấu trúc "kim tự tháp" để có thể render mượt mà các bức ảnh khổng lồ. Hôm nay, chúng ta sẽ xắn tay áo lên để tìm hiểu cấu trúc đó trông như thế nào, và làm sao để tự tay "thái nhỏ" một bức ảnh Gigapixel bằng công cụ VIPS.

1. Định dạng DZI (Deep Zoom Image) là gì?
Khi bạn đưa một bức ảnh gốc (ví dụ: monalisa.jpg nặng 500MB) qua quá trình xử lý Deep Zoom, kết quả trả về không phải là một file ảnh duy nhất, mà là một bộ dữ liệu bao gồm hai thành phần chính:
- File cấu hình XML (
monalisa.dzi): File này rất nhẹ, đóng vai trò như một "tấm bản đồ" khai báo cho OpenSeadragon biết thông số của bức ảnh. - Thư mục chứa ảnh đã cắt (
monalisa_files/): Chứa hàng ngàn mảnh ảnh nhỏ (tiles) được sắp xếp theo từng cấp độ thu phóng (zoom level).
Cấu trúc thư mục thực tế sẽ trông như thế này:
/project-folder
├── monalisa.dzi <-- File XML chứa metadata
└── monalisa_files/ <-- Thư mục chứa các tiles
├── 0/ <-- Zoom level 0 (xa nhất, kích thước ảnh nhỏ nhất)
│ └── 0_0.jpg
├── 1/
│ ├── 0_0.jpg
│ └── 0_1.jpg
...
└── 14/ <-- Zoom level 14 (gần nhất, ảnh gốc, chứa hàng ngàn file)
├── 0_0.jpg
├── 0_1.jpg
...
└── 45_60.jpg <-- Tọa độ cột 45, hàng 60 của lưới ảnh
Góc nhìn kỹ thuật: Định dạng của file tile thường là
C_R.jpg(Column_Row - Cột_Hàng). Khi bạn cuộn chuột ở Zoom Level 14 tại một tọa độ nhất định, OpenSeadragon sẽ đọc file.dzivà tự động fetch chính xác file14/45_60.jpgđể hiển thị trên Canvas thay vì tải cả bức ảnh.
2. Công cụ "thái ảnh": Giới thiệu libvips
Để chuyển đổi một bức ảnh bình thường sang chuẩn DZI, chúng ta cần một công cụ xử lý ảnh. Mặc dù bạn có thể dùng ImageMagick hoặc các script Python thuần, nhưng libvips luôn là "tiêu chuẩn vàng" trong ngành vì:
- Tốc độ cực nhanh: Nhanh hơn ImageMagick từ 3-5 lần.
- Siêu tiết kiệm RAM: VIPS có thể xử lý một bức ảnh 10GB trên một chiếc máy tính chỉ có 2GB RAM nhờ cơ chế luồng (streaming) và tính toán lazy-evaluation.
VIPS hỗ trợ CLI (Command Line Interface), hoặc bạn có thể dùng nó thông qua các thư viện wrapper phổ biến như sharp (Node.js) hay pyvips (Python).
3. Thực hành: Cắt ảnh bằng VIPS CLI
Để làm phần này, bạn cần cài đặt vips trên máy tính:
- macOS:
brew install vips - Ubuntu/Debian:
sudo apt install libvips-tools - Windows: Tải bản binary từ trang chủ của libvips.
Bước 1: Chuẩn bị một bức ảnh lớn
Hãy tìm một bức ảnh thật sắc nét (khoảng 5000x5000 pixels trở lên), đặt tên là hinh-goc.jpg.
Bước 2: Chạy lệnh cắt ảnh
Mở Terminal tại thư mục chứa ảnh và chạy dòng lệnh đơn giản sau:
vips dzsave hinh-goc.jpg output_folder
Bước 3: Phân tích kết quả
Chỉ sau vài giây (hoặc vài phút tùy độ lớn của ảnh), VIPS sẽ sinh ra:
- File
output_folder.dzi - Thư mục
output_folder_files
Nội dung bên trong file output_folder.dzi sẽ có dạng XML như sau:
<?xml version="1.0" encoding="UTF-8"?>
<Image xmlns="http://schemas.microsoft.com/deepzoom/2008"
Format="jpg"
Overlap="1"
TileSize="254" >
<Size
Height="6000"
Width="8000"
/>
</Image>
- Format: Định dạng của các mảnh ảnh (thường là
jpghoặcpng). - Overlap: Số pixel trùng lặp giữa 2 mảnh ảnh cạnh nhau (giúp tránh hiện tượng có đường viền trắng mỏng khi ghép ảnh trên trình duyệt).
- TileSize: Kích thước của mỗi mảnh vuông (thường là 254px hoặc 256px).
- Size: Kích thước thật của bức ảnh gốc ban đầu.
4. Mang DZI lên Web
Sau khi đã có bộ đôi output_folder.dzi và thư mục output_folder_files/, công việc phía "Back-end / Tiền xử lý" đã hoàn tất.
Bây giờ, bạn chỉ việc upload toàn bộ chúng lên một Static Server (như Amazon S3, Google Cloud Storage, hoặc thư mục public của dự án Web). Trong OpenSeadragon, bạn chỉ cần chỉ định URL trỏ đến file .dzi đó là xong!
All rights reserved