Sharp SVG sang PNG: kích thước, mật độ và độ sắc nét
Dùng Sharp kết xuất SVG thành PNG trong suốt đúng kích thước pixel cuối. Xem phép thử 1x và 2x có thể tái hiện, khi nào cần density và vì sao phóng PNG thất bại.
Trên trang này
Với quy trình Sharp hiện tại, bắt đầu từ SVG trong mỗi lần xuất và gọi resize() với chiều rộng pixel bạn thực sự cần. Nếu cần tài nguyên 2x, yêu cầu số pixel đầu ra gấp đôi. Đừng tạo PNG nhỏ trước rồi phóng lớn tệp đó. Cũng đừng sao chép cách sửa density cũ vào mọi quy trình: thử nghiệm Sharp 0.34.4 của chúng tôi tạo cùng pixel dù có hay không có mật độ đầu vào cao hơn.
Câu trả lời ngắn gọn
- Giữ SVG gốc làm bản chính.
- Tạo từng kích thước PNG trực tiếp từ SVG đó bằng Sharp.
- Kiểm tra kích thước đầu ra và kênh alpha, rồi xem tệp ở kích thước hiển thị dự định.
- Đổi SVG hoặc tìm hiểu trình hiển thị nếu kết quả vẫn khác nguồn. Cài đặt density không thể tạo chi tiết bên trong bitmap nhúng.
Tạo PNG 1x và 2x từ SVG
Hàm khởi tạo Sharp nhận tệp hoặc buffer SVG, và API resize đặt kích thước đầu ra. Với biểu tượng vuông 64 đơn vị sẽ xuất hiện ở 256 pixel CSS, xuất PNG 256 pixel để dùng 1x và PNG 512 pixel cho trường hợp 2x:
import sharp from "sharp";
const source = "icon.svg";
await Promise.all([
sharp(source).resize({ width: 256 }).png().toFile("icon-1x.png"),
sharp(source).resize({ width: 512 }).png().toFile("icon-2x.png"),
]);Bỏ chiều cao giúp giữ tỷ lệ nguồn theo hành vi resize thông thường của Sharp. Chọn chiều rộng đầu ra thực tế cho nơi sử dụng; “2x” chỉ kích thước pixel so với kích thước hiển thị CSS dự định, không phải thuộc tính SVG hay cam kết cho mọi màn hình. Nếu muốn xem biểu tượng ở 256 pixel CSS, so sánh PNG 256 và 512 pixel ở kích thước hiển thị đó và quyết định tệp lớn hơn có xứng đáng với dung lượng hay không.
Biểu tượng thử nghiệm gốc của chúng tôi khai báo width="64" height="64" viewBox="0 0 64 64". Chúng tôi kết xuất nó thành 64, 512 và 1.024 pixel bằng Sharp 0.34.4 được cố định trong kho mã. Đầu ra 512 và 1.024 pixel được tạo từ SVG, có góc trong suốt và tâm được tô đục, đồng thời báo đúng kích thước yêu cầu. Đó là quan sát cho mẫu thử và phiên bản này, không phải phép đánh giá mọi hình SVG.

Hình minh họa cụ thể tình huống thất bại: khi đầu ra đầu tiên là PNG 64 pixel, lần resize sau nội suy những pixel đó. Nó không còn đường dẫn để vẽ lại. Kết quả 512 pixel trực tiếp và có điều chỉnh density của chúng tôi giống hệt trên các kênh RGBA thô trong thử nghiệm này. SVG nguồn, tập lệnh kết xuất và metadata kết quả được giữ cùng bộ tài liệu nghiên cứu của bài.
Bạn có cần density trong Sharp không?
Tùy chọn density của hàm khởi tạo Sharp điều khiển DPI dùng khi đọc đầu vào SVG hoặc PDF; mặc định được tài liệu hóa là 72. Nó khác với yêu cầu chiều rộng cuối trong resize(). Bạn có thể gặp ví dụ Sharp cũ tăng density đầu vào để tránh phóng lớn bị mềm. Các ví dụ đó mô tả dấu hiệu thực sự trong quá khứ: vấn đề Sharp #1421 báo cáo SVG 32 pixel bị vỡ pixel khi phóng thành 512 pixel vào năm 2018. Chúng không chứng minh cách khắc phục vẫn cần cho bản cài hiện tại.
Chúng tôi thử đúng cặp này trên Sharp 0.34.4:
const direct = await sharp("icon.svg")
.resize({ width: 512 })
.png()
.toBuffer();
const densityFirst = await sharp("icon.svg", { density: 576 })
.resize({ width: 512 })
.png()
.toBuffer();Với biểu tượng vector 64 pixel của chúng tôi, cả hai quy trình cho cùng pixel RGBA 512 × 512. Chỉ đặt density đầu vào khi một tệp cụ thể và phiên bản Sharp đã cài cho thấy cần, rồi lặp lại so sánh sau nâng cấp. Đừng coi số DPI cao hơn là công tắc độ sắc nét cho mọi trường hợp. Câu hỏi đầu tiên hữu ích là bạn có còn hình học vector ở thời điểm Sharp tạo PNG cuối hay không.
Nếu cũng làm việc với PDF, thử đầu vào đó riêng: thử nghiệm SVG này không xác định hành vi PDF. Tương tự, withDensity() trong tài liệu Sharp mới hơn mô tả metadata DPI đầu ra; đó là thao tác khác với density kết xuất SVG đầu vào của hàm khởi tạo.
Kiểm tra kích thước, độ trong suốt và nội dung nguồn
Dùng API metadata của Sharp trên đầu ra thay vì đoán từ mức thu phóng bản xem trước:
const oneX = await sharp("icon-1x.png").metadata();
const twoX = await sharp("icon-2x.png").metadata();
console.log({
oneX: [oneX.width, oneX.height, oneX.hasAlpha],
twoX: [twoX.width, twoX.height, twoX.hasAlpha],
});Với mẫu vuông ở đây, kích thước dự kiến là 256 × 256 và 512 × 512. hasAlpha cho biết có kênh alpha, nhưng không chứng minh một góc cụ thể trong suốt; kiểm tra tệp hoặc lấy mẫu pixel nếu độ trong suốt quan trọng với bàn giao. Alpha ở góc mẫu thử là không và alpha ở tâm là 255 trong mọi đầu ra được thử. Ngược lại, hình chữ nhật trắng trong SVG sẽ được vẽ vào mọi PNG, bất kể định dạng PNG.
Nếu bản kết xuất mới ở kích thước lớn vẫn vỡ pixel, kiểm tra nội dung SVG. Tiêu chuẩn SVG cho phép phần tử <image> nhúng hoặc liên kết ảnh raster. Vì vậy tệp có thể có đuôi .svg trong khi hình bên trong vẫn là PNG độ phân giải thấp. Hướng dẫn tìm ảnh raster trong SVG của chúng tôi cho biết cách kiểm tra đối tượng và XML. Tăng chiều rộng đầu ra của Sharp không thể biến những pixel nhúng đó thành đường dẫn.
Cũng kiểm tra nơi sử dụng. Tệp 512 pixel hiển thị ở 1.024 pixel có thể trông mềm. Trình xem phóng vượt xa 100% làm lộ lưới PNG ngay cả khi xuất đúng. So sánh ở kích thước và nền hiển thị thực tế, rồi quyết định cung cấp PNG lớn hơn hay chính SVG. Khi đưa lên web, SVG nội tuyến và SVG trong phần tử ảnh cung cấp các lựa chọn tích hợp khác nhau; không cách nào cần PNG nếu nơi sử dụng hỗ trợ SVG.
PerfectVector phù hợp ở đâu
Sharp raster hóa SVG; nó không khôi phục đường dẫn chỉnh sửa được từ PNG. Nếu bản chính chỉ là biểu tượng hoặc logo raster, tạo và kiểm tra SVG trước quy trình xuất này. Hướng dẫn PNG biểu tượng sang SVG cho bộ UI trình bày hình học nhất quán và kiểm tra bàn giao cho cả bộ. Quy trình ảnh sang vector của PerfectVector có thể tạo một bản SVG từ hình chỉ có raster. Mở kết quả đó, kiểm tra dáng bao ngoài, chi tiết nhỏ và xem có đường dẫn thực sự không, rồi tạo PNG 1x và 2x từ SVG đã duyệt. Nếu đã sở hữu SVG gốc sạch, giữ nó và dùng Sharp trực tiếp.
Câu hỏi thường gặp
Vì sao đầu ra SVG sang PNG của Sharp trông mờ? Kiểm tra quy trình có tạo PNG nhỏ trước rồi phóng lớn không. Tiếp theo kiểm tra SVG có nội dung raster nhúng và so sánh PNG bàn giao ở kích thước hiển thị thực. Trên phiên bản Sharp hiện tại, thử kết xuất trực tiếp SVG ở kích thước cuối trước khi thêm cách khắc phục density đầu vào.
density: 576 có bắt buộc để phóng lớn tám lần không?
Không cần với mẫu SVG từ 64 đến 512 pixel của chúng tôi trên Sharp 0.34.4: resize trực tiếp và resize điều chỉnh density tạo pixel RGBA giống hệt. SVG và trình hiển thị đã cài của bạn có thể hoạt động khác, nên hãy thử đúng đầu vào đó thay vì coi con số là quy tắc.
Tôi tạo PNG 2x trong suốt thế nào? Kết xuất từ SVG ở kích thước gấp đôi kích thước CSS dự định và xuất PNG. Xác nhận chiều rộng, chiều cao kết quả rồi kiểm tra độ trong suốt ở vùng không được vẽ. Khung vẽ trong suốt không xóa hình nền đã có trong SVG.
Nguồn tham khảo
- Sharp — Hàm khởi tạo — Hỗ trợ đầu vào SVG và tùy chọn
densityđầu vào. - Sharp — thay đổi kích thước ảnh — Hành vi đặt kích thước đầu ra dùng trong ví dụ.
- Sharp — metadata đầu vào — Kiểm tra kích thước và metadata alpha.
- Sharp GitHub — vấn đề SVG sang PNG vỡ pixel #1421 — Dấu hiệu được báo cáo trong quá khứ, được phân biệt rõ với thử nghiệm phiên bản hiện tại cố định.
- Sharp — tùy chọn đầu ra — Phân biệt metadata density đầu ra mới hơn với density kết xuất đầu vào.
- W3C — nội dung nhúng SVG 2 — Vì sao SVG có thể chứa pixel raster.
Nếu bản chính chỉ có raster, tạo một bản SVG bằng PerfectVector, kiểm tra đường dẫn và dùng Sharp tạo tệp đã duyệt ở từng kích thước PNG cần thiết.
Thêm từ blog

Nhập SVG Unity: Chuẩn bị hình cho UI Toolkit hoặc sprite
Chọn cách nhập SVG Unity theo phiên bản editor và đích đến. Chuẩn bị đường dẫn, xử lý hiệu ứng không hỗ trợ và kiểm tra ảnh UI Toolkit hoặc sprite trong ngữ cảnh.
Biểu tượng SVG Shopify tùy chỉnh: Chuẩn bị biểu trưng thương hiệu sạch
Chuẩn bị biểu tượng SVG tùy chỉnh cho giao diện Shopify, rồi chọn tài nguyên ảnh hoặc snippet Liquid nội tuyến. Kiểm tra đường dẫn, màu, kích thước và khả năng tiếp cận.