Thanh trượt chất lượng JPEG không phải là phần trăm! 80 và 100 khác nhau ở đâu?

Khi xuất ảnh, thanh trượt chất lượng JPEG đó, bạn có phải vẫn luôn dùng nó như một con số phần trăm? Kéo đến 80, trong lòng nghĩ là “giữ được 80% chất lượng hình ảnh”; kéo lên 100, cảm thấy “thế này thì không mất chút nào”.

Cách hiểu này cần phải đảo ngược hoàn toàn: con số trên thanh trượt không có bất kỳ quan hệ nào với “bao nhiêu phần trăm chất lượng”, chất lượng 100 cũng không phải là không mất dữ liệu. Đưa kết luận có thể áp dụng ngay ra trước — ảnh muốn lưu cho yên tâm, đặt 85–92; đăng lên web và mạng xã hội, 75–82 là đủ; đừng đặt 100 làm mặc định, nó chỉ khiến dung lượng tăng gấp đôi thậm chí gấp ba, chất lượng không hơn chút nào. Dưới đây nói bằng lời đơn giản, bóc tách thanh trượt này.

Nói một câu cho rõ: Thanh trượt chất lượng JPEG không kiểm soát “giữ lại bao nhiêu chất lượng”, mà là mức độ tàn nhẫn của nhóm số chia trong bảng lượng tử hóa — số chia càng lớn, làm tròn càng mạnh, mất càng nhiều. Nó không có quan hệ tuyến tính với chất lượng hay dung lượng, thay đổi từ 100 xuống 90 không giống thay đổi từ 20 xuống 10.

Thanh trượt chất lượng JPEG rốt cuộc đang làm gì

Đặt tiền đề trước: JPEG là định dạng có mất dữ liệu, từ khoảnh khắc bạn nhấn lưu là đã bắt đầu mất thứ gì đó, thanh trượt chỉ quyết định “mất tàn nhẫn đến đâu”, không quyết định “có mất hay không”. Cách mất của nó có một quy trình cố định, thanh trượt là cánh cổng cuối cùng trên dây chuyền này.

Khi lưu, ảnh trước tiên chuyển từ RGB sang YCbCr, tách độ sáng và màu sắc thành hai đường. Làm vậy vì mắt người nhìn độ sáng giỏi hơn nhìn màu sắc nhiều, tách trước, sau đó mới dễ tập trung giữ độ sáng.

Tiếp theo, toàn bộ ảnh được cắt thành các khối nhỏ 8×8 pixel, mỗi khối thực hiện một lần biến đổi cosine rời rạc (DCT), chuyển màu pixel thành một chuỗi giá trị tần số. Có thể ví như tách hợp âm thành từng nốt đơn: tần số thấp là màu nền và chuyển màu của hình, tần số cao là cạnh sắc nét và họa tiết nhỏ li ti. Phiên bản đầy đủ của quy trình này, mục từ JPEG trên Wikipedia viết rất đầy đủ.

Chiêu sát thủ thật sự nằm ở bước cuối: mỗi giá trị tần số đều phải chia cho một con số trong bảng lượng tử hóa (Quantization Table), rồi làm tròn lấy số nguyên. Làm tròn, chính là nơi thông tin chết vĩnh viễn — phần lẻ không chia hết bị vứt bỏ trực tiếp, không thể quay lại. Thanh trượt chất lượng quản lý chính là mức độ tàn nhẫn của các số chia này: giá trị thanh trượt cao, số chia nhỏ, làm tròn gần như không làm tổn hại dữ liệu; giá trị thanh trượt thấp, số chia lớn, làm tròn trực tiếp xóa phẳng chi tiết. Và số chia của thành phần tần số cao tăng nhanh hơn, nên thứ bị hy sinh đầu tiên mỗi lần, đều là cạnh và họa tiết nhỏ.

Vì vậy nó mới không thể là phần trăm. Từ 100 kéo xuống 90, và từ 20 kéo xuống 10, thay đổi của số chia hoàn toàn là hai chuyện khác nhau, khoảng cách chất lượng và dung lượng cũng hoàn toàn khác — ở gần 90 kéo một nấc, bạn có thể không cảm nhận gì; ở gần 20 kéo một nấc, ảnh hỏng luôn. Hiểu nó như phần trăm, là hiểu lầm phổ biến nhất và cũng đắt giá nhất trên thanh trượt này.

Tại sao chất lượng 100 không phải không mất dữ liệu

Đưa câu trả lời trước: 100 vẫn còn cách xa “không mất dữ liệu” ở hai nhược điểm chí mạng: một điểm không phụ thuộc vào thanh trượt, điểm kia ngay cả thanh trượt cũng không cứu được.

Nhược điểm thứ nhất là lấy mẫu phụ sắc độ (chroma subsampling). Sau khi RGB chuyển sang YCbCr, trước khi nén thật sự bắt đầu, hầu hết encoder đã vứt khoảng 75% chi tiết sắc độ trước, lý do vẫn là điều đó: mắt người kém nhạy với màu sắc, mất rồi cũng không thấy. Bước này vốn không thuộc quản lý của thanh trượt, bạn đặt 100 cũng vẫn thực hiện như vậy.

Nhược điểm thứ hai là bản thân phép toán không hoàn hảo. Cho dù số chia trong bảng lượng tử hóa đã đặt nhỏ nhất, “pixel thành tần số, tần số lại thành pixel” một đi một về, vẫn có sai số làm tròn nhỏ. File lưu ra rồi mở lại, đã không còn là những pixel lúc bạn nhấn nút lưu.

Muốn thật sự không mất một bit, xin đi đường không mất dữ liệu: PNG, TIFF, hoặc chế độ không mất dữ liệu của WebP. Có mất dữ liệu là đường một chiều, bất kỳ mức nào của JPEG cũng vậy, bao gồm cả cái 100 trông có vẻ “hoàn hảo” đó.

85–92 và 75–82, chọn thế nào

Rất nhiều thử nghiệm thực tế và so sánh cấp pixel, cuối cùng đều rơi vào một ranh giới rất rõ ràng: hai khoảng, bao phủ gần như tất cả tình huống.

85–92 là mức lưu giữ. Portfolio, ảnh phải giao cho khách, đống ảnh gốc bạn không nỡ động vào, đặt ở mức này. File lưu ở chất lượng 90, khoảng 1/8 đến 1/12 của chưa nén, mà khác biệt mắt thường không thấy — bạn phải phóng to đến 400%, nhìn chằm chằm vào một mảng nhỏ nào đó, mới tìm ra thay đổi.

75–82 là mức web. Ảnh minh họa website, đăng mạng xã hội, đặt ở mức này. File nhỏ hơn mức lưu giữ 40%–60%, cái giá chủ yếu là chỗ họa tiết phức tạp hơi mềm, xem ảnh bình thường cơ bản không nhận ra.

Nếu đã đọc bài trước “Có mất dữ liệu và không mất dữ liệu”, điểm tối ưu (sweet spot) 80–85 đưa ra ở đó không xung đột với hai mức này: quanh 80 vốn nằm trong mức web, 85 vừa bước vào mức lưu giữ, ảnh đã lưu theo 80–85 không cần nén lại.

Ba mức gom thành một câu: thứ muốn giữ đặt 85–92, thứ gửi đi đặt 75–82, dưới 60 là vùng mìn, đi vòng qua.

So sánh cùng một mảnh ảnh được xuất JPEG ở chất lượng 90, 75 và 35. Ở 90 và 75 không thấy khác biệt, ở 35 ảnh mờ rõ và bẹt khối
Cùng một mảnh ảnh, ba lần xuất thật. Chất lượng 90 — 102 KB, chất lượng 75 — 62 KB. Không có khác biệt nhìn thấy được nhưng file nhỏ hơn khoảng 40%. Trong vùng sụp đổ, chất lượng 35 còn nhỏ hơn nữa 28 KB nhưng ảnh mờ đi và bẹt khối.

Mặc định đầu ra kéo 100, là lo lắng, không phải chiến lược. File chất lượng 85, nhỏ hơn chất lượng 100 60%–75%, mà chất lượng nhìn không ra bất kỳ khác biệt nào; với web, đây là kéo dài thời gian tải vô ích — khoản này của ảnh web, tôi đã tính kỹ trong bài tăng tốc ảnh web.

Tại sao chất lượng dưới 60 là sụp đổ

Thanh trượt qua 60 rồi kéo xuống nữa, chất lượng rơi không phải dốc, mà là vực.

Nguyên nhân vẫn là làm tròn. Khi giá trị quá thấp, số chia của thành phần tần số cao lớn đến vô lý, một giá trị tần số chia xong rồi làm tròn, trực tiếp về không — chi tiết này coi như không lưu. Thế là cả loại thông tin thị giác biến mất hàng loạt: sợi tóc, vân dệt của vải, đầu nét chữ serif, đều là nhóm biến mất đầu tiên.

Hình còn lại, chính là artifact (tạo tác) JPEG điển hình: từng mảng khối màu 8×8, từng vòng dải màu trong chuyển màu, lông tua và nhiễu muỗi (mosquito noise) bên cạnh các cạnh sắc nét. Hình dạng lớn vẫn còn, nhưng bức ảnh này đã không còn tính là “ảnh cho người xem”. Mỗi dạng artifact hình thành từ đâu, tôi đã viết riêng một bài giải thích bằng hình.

So sánh phóng to mảnh JPEG chất lượng 90 và 30. Phía chất lượng thấp: vệt sáng mờ, tường gạch bẹt thành khối, trời loang đốm
Chuyện gì xảy ra dưới 60. Cả hai hàng đều là cùng một chỗ phóng to 3 lần. Trái: chất lượng 90, phải: chất lượng 30. Hàng trên: vệt sáng và tường gạch — đường mảnh mất trước, mạch vữa bẹt thành khối. Hàng dưới: trời và mép tường — chuyển màu mịn loang đốm, cạnh bị mờ.

Nên kết luận của tôi là: 60 là giới hạn thực tế của ảnh thông thường. Vài KB tiết kiệm thêm khi xuống nữa, đổi lại là thứ nhìn một cái là biết giả, không đáng.

Cùng là chất lượng 90, các phần mềm khác nhau xuất ra thứ khác nhau

“Chất lượng 90” không phải tiền tệ chung. Chuẩn JPEG đưa ra một bộ bảng lượng tử hóa đề xuất (Annex K), nhưng mỗi phần mềm dùng bảng nào, cách nhân tỷ lệ (scale) ra sao, là do mỗi hãng tự định. Cùng là “chất lượng cao”, bốn công cụ phổ biến đưa ra con số hoàn toàn khác nhau: thang của Photoshop là 0–12, số 10 của nó tương đương khoảng 90 của libjpeg tham chiếu; GIMP và ImageMagick đều là thang 1–100, mức “chất lượng cao” của GIMP lấy 85, ImageMagick lấy 92; libjpeg là bản tham chiếu, giá trị tham chiếu của chính nó là 90.

Hai công cụ đều đặt “chất lượng 85”, file xuất ra cũng sẽ không giống nhau. Nên đừng nhớ một con số trong một phần mềm, đổi sang phần mềm khác lại sao chép. So sánh giữa các phần mềm, giữa các dự án, cách đáng tin cậy chỉ có hai: xem dung lượng đầu ra thực tế, xem hiệu quả hình ảnh thực tế.

Thước đo đáng tin cậy hơn mắt thường: SSIM

Thanh trượt không đáng tin, mắt thường lại chịu ảnh hưởng của màn hình và trạng thái, “không thấy khác biệt” chuyện này còn có thể định lượng không? Có, cách đáng tin cậy hơn nhiều là đổi một cây thước: chỉ số tương đồng cấu trúc (SSIM, Structural Similarity Index Measure).

Nó không so từng pixel, mà xem cấu trúc, độ sáng, độ tương phản ba thứ thay đổi bao nhiêu, gần với cách mắt người đánh giá ảnh hơn “đếm xem có bao nhiêu pixel khác nhau”. Điểm từ 0 đến 1, 1 là hai ảnh hoàn toàn giống nhau. Công thức và toàn bộ ngọn ngành, mục từ SSIM trên Wikipedia giải thích rất rõ.

Với các mức chất lượng phổ biến, SSIM đại khái ở mức này: file chất lượng 85 thường đạt trên 0.97, về mặt thị giác không thể phân biệt với ảnh gốc; rơi xuống 60, điểm nằm ở 0.90–0.93, hơi mềm, phóng to mới thấy; đến 40, chỉ còn 0.82–0.87, artifact đã thấy bằng mắt thường.

Nhóm số này trung thực hơn thanh trượt nhiều. Muốn không dựa vào đoán để định chất lượng, có thể dùng lệnh compare của ImageMagick trực tiếp tính SSIM của hai ảnh, tìm ra điểm “tiết kiệm dung lượng tối đa, mà không rơi xuống dưới ngưỡng cảm nhận 0.85”. Cách dùng cây thước này, tôi đã viết riêng một bài chuyên sâu về SSIM.

Tự trải nghiệm: thanh trượt, SSIM và chất lượng tối ưu

Công cụ nhỏ dưới đây chạy hoàn toàn trong trình duyệt, ảnh không được gửi đi bất cứ đâu. Chọn một ảnh (hoặc bấm “Dùng ảnh mẫu”) rồi kéo thanh trượt, quan sát dung lượng sau nén và thay đổi SSIM. Có thể dùng tìm kiếm tự động để tìm thiết lập nhỏ nhất đạt SSIM ≥ 0.85. Giá trị SSIM được tính theo thời gian thực cho ảnh vừa nén. Đó chính là cây thước ở phần trên.

Bản gốc
Sau khi nén (chất lượng hiện tại)
Khác biệt (chi tiết bị bỏ)
Dung lượng: —
SSIM: —
—
Tỉ lệ xem bản gốc/sau nén
Khuếch đại khác biệt Trắng = chi tiết bị bỏ. Càng sáng mất càng nhiều
Bộ chuyển đổi chất lượng giữa các phần mềm (cùng một con số ở phần mềm khác nhau nghĩa khác nhau. Đừng sao chép trực tiếp)

Lưu ý: bộ mã hóa JPEG tích hợp trong trình duyệt không hiển thị tham số lấy mẫu phụ sắc độ và bảng lượng tử hóa. Công cụ này cho thấy tác dụng thật của thanh trượt và định lượng khác biệt qua SSIM, chứ không cho phép chỉnh tham số bên trong bộ mã hóa. Điều này cũng xác nhận luận điểm của bài: chất lượng 100 không phải không mất dữ liệu, và cùng một con số ở phần mềm khác nhau nghĩa khác nhau.

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

JPEG chất lượng đặt 80 hay 100 tốt hơn?

Tuyệt đại đa số trường hợp quanh 80 là đủ, 100 không nên làm mặc định. File chất lượng 85, nhỏ hơn chất lượng 100 60%–75%, mắt thường không thấy khác biệt; ảnh muốn an toàn thì đặt 85–92, web và mạng xã hội 75–82 là đủ, dưới 60 sẽ có artifact rõ ràng.

JPEG chất lượng 100 là không mất dữ liệu phải không?

Không phải. Cho dù kéo hết 100, JPEG cũng thường trước tiên mất khoảng 75% chi tiết màu trong lấy mẫu phụ sắc độ, rồi qua lượng tử hóa và làm tròn gây mất mát không thể đảo ngược. Muốn không mất dữ liệu, xin dùng PNG, TIFF hoặc WebP không mất dữ liệu.

Tại sao trong Photoshop không tìm thấy chất lượng 85?

Thang chất lượng JPEG của Photoshop là 0–12, không phải 1–100, số 10 của nó tương đương khoảng 90 của libjpeg tham chiếu. Các phần mềm có ánh xạ khác nhau với cùng một con số, giữa các phần mềm đừng sao chép số, lấy dung lượng đầu ra thực tế và hiệu quả hình ảnh làm chuẩn.

Làm sao đánh giá một ảnh sau khi nén chất lượng có giảm rõ rệt không?

Phóng to so sánh với ảnh gốc là trực tiếp nhất; muốn chỉ số khách quan thì dùng SSIM. JPEG chất lượng 85 thường có SSIM trên 0.97, về mặt thị giác không thể phân biệt với ảnh gốc; khoảng 40 rơi xuống 0.82–0.87, artifact thấy bằng mắt thường. Lệnh compare của ImageMagick có thể trực tiếp tính ra điểm này.

Lời kết

Con số trên thanh trượt là tham số phép chia, không phải phần trăm chất lượng; 100 không phải không mất dữ liệu, dưới 60 là vực. Muốn một câu khẩu quyết: ảnh lưu 85, đăng web lưu 80, 100 không cần đi đâu cả — file gấp đôi, chất lượng không tăng một phần.

Muốn đi suốt một mạch từ chọn định dạng, đổi kích thước đến chỉnh chất lượng và tăng tốc web, hãy xem hướng dẫn đầy đủ về nén ảnh, toàn bộ chuỗi đều ở bài đó.