Định dạng tệp
BMP là gì? Giải thích định dạng ảnh bitmap
BMP là định dạng ảnh bitmap không nén, không mất dữ liệu của Windows. Bài viết giải thích cấu trúc phần đầu, độ sâu màu, các giới hạn của nó và cách làm tệp nhỏ hơn.
Tác giả: Hemen Dönüştür Editör EkibiNgày đăng: 10 phút đọc

BMP là một trong những định dạng ảnh lâu đời và đơn giản nhất trong thế giới Windows. Một tệp BMP thường ghi các điểm ảnh xuống đĩa theo từng hàng mà không hề nén. Sự đơn giản đó khiến nó dễ đọc và không mất dữ liệu, nhưng cũng chính sự đơn giản đó làm tệp nặng khủng khiếp. Bài viết này trình bày BMP ra đời từ đâu, bên trong tệp có gì, các chi tiết về độ sâu màu và độ trong suốt, ngày nay bạn còn gặp nó ở đâu và cách chuyển tệp BMP sang những định dạng thiết thực hơn.
BMP là gì?
BMP (bitmap, phần mở rộng .bmp) là định dạng tệp ảnh raster, dựa trên điểm ảnh. Tài liệu kỹ thuật còn gọi nó là DIB, tức bitmap độc lập với thiết bị (device-independent bitmap). "Độc lập với thiết bị" nghĩa là hình ảnh có thể được diễn giải như nhau bất kể nó được tạo trên card đồ họa hay máy in nào: tệp mang sẵn thông tin cần thiết để giải mã màu sắc trong phần đầu và bảng màu của chính nó.
Theo tài liệu Win32 của Microsoft, một tệp bitmap bắt đầu bằng cấu trúc BITMAPFILEHEADER, tiếp theo là BITMAPINFOHEADER, BITMAPV4HEADER hoặc BITMAPV5HEADER, rồi đến một bảng màu tùy chọn và cuối cùng là dữ liệu điểm ảnh. Kiểu MIME là image/bmp.
Sơ lược lịch sử: từ Windows và OS/2 đến nay
BMP ra đời từ sự hợp tác giữa Microsoft và IBM trong việc phát triển Windows và OS/2 vào cuối thập niên 1980. Bitmap thời Windows 1.0 phụ thuộc nhiều vào thiết bị đầu ra; dạng độc lập với thiết bị trở nên phổ biến cùng Windows 3.0 năm 1990. Phần đầu BITMAPCOREHEADER 12 byte được định nghĩa cho OS/2 Presentation Manager là lý do người ta vẫn còn nhắc đến các tệp "BMP OS/2".
Qua nhiều năm, định dạng được mở rộng bằng cách thêm trường vào cuối phần đầu. Theo mô tả định dạng của Library of Congress, phiên bản 5 ra đời cùng Windows 98 năm 1998 và cho phép ghi hồ sơ màu ICC vào tệp. Các kích thước phần đầu phổ biến hiện nay là:
| Phần đầu | Kích thước | Bổ sung chính |
|---|---|---|
| BITMAPCOREHEADER | 12 byte | Cấu trúc cơ bản tương thích OS/2 1.x |
| BITMAPINFOHEADER | 40 byte | Phần đầu phổ biến nhất, từ Windows 3.0; trường nén và độ phân giải |
| BITMAPV4HEADER | 108 byte | Mặt nạ màu, mặt nạ alpha và thông tin không gian màu |
| BITMAPV5HEADER | 124 byte | Hồ sơ ICC nhúng hoặc liên kết, ý đồ hiển thị (rendering intent) |
Trình đọc nhận biết phần đầu nào đang được dùng nhờ giá trị kích thước ở trường đầu tiên. Nhờ vậy phần mềm cũ có thể bỏ qua các trường mới mà vẫn đọc được phần cơ bản.
Bên trong một tệp BMP
Phần đầu tệp và chữ ký "BM"
Mọi tệp BMP đều bắt đầu bằng một phần đầu tệp 14 byte, và hai byte đầu tiên của nó là các ký tự ASCII BM (hệ thập lục phân 42 4D). Phần đầu này lưu tổng dung lượng tệp và vị trí byte nơi dữ liệu điểm ảnh bắt đầu. Một DIB đặt vào bộ nhớ tạm của Windows (định dạng CF_DIB) bỏ qua 14 byte này và bắt đầu thẳng bằng phần đầu thông tin.
Phần đầu thông tin
Phần đầu thông tin chứa chiều rộng, chiều cao, số bit mỗi điểm ảnh (biBitCount), kiểu nén, độ phân giải ngang và dọc (tính bằng điểm ảnh mỗi mét) và số màu được dùng trong bảng màu.
Bảng màu (palette)
Trong ảnh có từ 8 bit mỗi điểm ảnh trở xuống, một điểm ảnh không phải là màu mà là chỉ số trỏ vào bảng màu. Trong ví dụ được Microsoft ghi lại, một bitmap 32x32 với 16 màu có mảng điểm ảnh dài 32 x 32 x 4 = 4096 bit, vì 4 bit là đủ để đánh địa chỉ 16 màu.
Dữ liệu điểm ảnh: hàng từ dưới lên và căn chỉnh 4 byte
BMP có hai đặc điểm khác thường. Thứ nhất, nếu chiều cao là số dương, các hàng được lưu từ dưới lên: hàng đầu tiên trong tệp là hàng dưới cùng của bức ảnh. Chiều cao âm lưu các hàng từ trên xuống, nhưng những ảnh như vậy không thể nén. Thứ hai, mỗi hàng được đệm cho đủ bội số của 4 byte. Microsoft đưa ra công thức tính độ dài hàng (stride) như sau:
stride = ((width * bitCount + 31) & ~31) >> 3
imageSize = |height| * stride
Với một ảnh 1920x1080 ở 24 bit, mỗi hàng dài 1920 x 3 = 5.760 byte (vốn đã là bội số của 4), nên dữ liệu điểm ảnh là 5.760 x 1.080 = 6.220.800 byte. Cộng thêm 54 byte phần đầu, tệp nặng khoảng 6,2 MB. Cùng bức ảnh đó ở dạng JPG thường chỉ bằng một phần nhỏ con số này.
Độ sâu màu, nén và độ trong suốt
Tài liệu về BITMAPV5HEADER định nghĩa các mức 1, 4, 8, 16, 24 và 32 bit mỗi điểm ảnh (giá trị 0 nghĩa là độ sâu được lấy từ dữ liệu JPEG hoặc PNG nhúng). 1 bit là đen trắng, 4 bit là 16 màu và 8 bit là bảng 256 màu. Ở 24 bit, mỗi điểm ảnh gồm ba byte theo thứ tự xanh lam, xanh lục, đỏ.
Trường nén có thể nhận các giá trị sau:
- BI_RGB: Không nén. Trên thực tế là đại đa số tệp BMP.
- BI_RLE8 và BI_RLE4: Mã hóa độ dài loạt (run-length) đơn giản cho ảnh bảng màu 8 bit và 4 bit. Hữu ích với vùng phẳng rộng, gần như vô dụng với ảnh chụp.
- BI_BITFIELDS: Không phải nén; các mặt nạ xác định vị trí của bit đỏ, xanh lục và xanh lam trong điểm ảnh 16 bit và 32 bit (ví dụ RGB 565).
- BI_JPEG và BI_PNG: Cho phép chứa dữ liệu JPEG hoặc PNG bên trong bitmap. Hiếm khi được các trình xem thông dụng hỗ trợ.
Độ trong suốt là phần thiếu nhất quán nhất của BMP. Mặt nạ alpha trong phần đầu V4 và V5 có thể định nghĩa byte thứ tư của điểm ảnh 32 bit là độ mờ đục, nhưng trong BMP 32 bit cổ điển byte đó được mô tả là không dùng đến và nhiều chương trình bỏ qua nó. Vì vậy, một tệp BMP 32 bit trông trong suốt ở chương trình này nhưng lại nằm trên nền đen ở chương trình khác là chuyện không có gì lạ. Nếu cần độ trong suốt, PNG là lựa chọn an toàn hơn nhiều.
Mức hỗ trợ trên hệ điều hành, trình duyệt và phần mềm
BMP mở được gần như ở mọi nơi. Các trình xem có sẵn của Windows và Paint, Preview trên macOS và các trình xem phổ biến trên Linux đều đọc được. Hướng dẫn định dạng ảnh của MDN ghi nhận BMP được hỗ trợ trong mọi phiên bản Chrome, Edge, Firefox, Opera và Safari. Cũng hướng dẫn đó nhấn mạnh rằng tệp BMP không nén rất nặng so với PNG hay JPG và nhìn chung nên tránh dùng cho nội dung website.
Ngày nay BMP được dùng ở đâu?
- Tài nguyên ứng dụng Windows và phần mềm cũ: Hình ảnh thanh công cụ, đồ họa trình cài đặt và một số tài nguyên trò chơi vẫn là BMP.
- Hệ thống nhúng và vi điều khiển: Một thiết bị có màn hình không cần bộ giải mã JPEG; dữ liệu điểm ảnh có thể được sao chép thẳng lên màn hình.
- Camera công nghiệp, máy quét và công cụ kiểm thử: Khi cần đầu ra thô, không mất dữ liệu, BMP là một định dạng trung gian đơn giản.
- Giảng dạy: Với phần đầu chỉ vài chục byte, BMP thường là định dạng đầu tiên sinh viên đọc và ghi trong các khóa học xử lý ảnh.
Ưu điểm và nhược điểm
| Ưu điểm | Nhược điểm |
|---|---|
| Không mất dữ liệu; giá trị điểm ảnh không bao giờ thay đổi | Không nén nên tệp rất nặng |
| Đọc và ghi cực kỳ đơn giản, không tốn CPU | Hỗ trợ độ trong suốt không nhất quán |
| Mở được trên gần như mọi hệ điều hành và trình duyệt | Hỗ trợ siêu dữ liệu kém (EXIF, mô tả) |
| Chế độ bảng màu hợp với thiết bị ít tài nguyên | Không thiết thực cho web, email và biểu mẫu tải lên |
Các lỗi thường gặp và cách khắc phục
Tệp quá nặng để gửi email hoặc tải lên biểu mẫu
Đây là vấn đề phổ biến nhất. Với ảnh chụp và bản scan, chuyển BMP sang JPG thường giảm dung lượng đi hàng chục lần hoặc hơn. Với ảnh chụp màn hình, sơ đồ hay bất cứ thứ gì có chữ, chuyển BMP sang PNG tốt hơn: PNG cũng không mất dữ liệu nhưng có nén, và không tạo nhiễu quanh các cạnh sắc như JPG.
BMP 32 bit hiện nền đen
Chương trình không nhận ra hoặc đọc sai byte alpha. Chuyển sang PNG thường khắc phục được. Khi chuyển sang JPG, định dạng không có độ trong suốt, vùng trong suốt được tô màu trắng hoặc màu bạn chọn.
Ảnh bị lộn ngược hoặc xiên lệch
Trong một trình đọc tự viết, lỗi này thường đến từ hai sai sót: bỏ qua việc các hàng được lưu từ dưới lên, hoặc không bỏ qua các byte đệm ở cuối mỗi hàng. Dùng công thức stride ở trên và kiểm tra dấu của chiều cao sẽ tránh được cả hai.
Một chương trình từ chối mở tệp BMP
Tệp BMP nén RLE, dùng BI_BITFIELDS hoặc chứa dữ liệu JPEG/PNG nhúng không được một số trình đọc đơn giản hỗ trợ. Lưu lại thành BMP 24 bit không nén hoặc chuyển sang PNG sẽ loại bỏ vấn đề tương thích.
Mẹo chuyển đổi
- JPG cho ảnh chụp, PNG cho đồ họa: Quy tắc quen thuộc vẫn áp dụng khi rời bỏ BMP. Cho web, bạn cũng có thể chọn WebP hoặc AVIF trong công cụ chuyển đổi hình ảnh.
- Giữ chất lượng cao: Vì BMP không mất dữ liệu, chất lượng JPG 85-90% cho kết quả khó phân biệt với bản gốc.
- Thu nhỏ nếu cần: Nếu tệp vẫn còn nặng, hãy giảm kích thước điểm ảnh hoặc dùng công cụ nén ảnh để đạt dung lượng mục tiêu.
- Theo chiều ngược lại: Nếu một thiết bị nhúng hoặc chương trình cũ cần BMP, hãy chọn BMP làm định dạng đích trong công cụ chuyển đổi hình ảnh. Các công cụ của chúng tôi ghi tệp BMP 24 bit không nén chuẩn; vùng trong suốt được làm phẳng lên màu nền bạn chọn.
Các trang chuyển đổi BMP của chúng tôi chạy ngay trong trình duyệt của bạn: tệp không được tải lên, vẫn ở trên thiết bị của bạn và không bao giờ rời khỏi đó.
Câu hỏi thường gặp
BMP và DIB có phải là một?
Trên thực tế là vậy. DIB là cấu trúc bitmap độc lập với thiết bị mà Windows dùng trong bộ nhớ và bộ nhớ tạm; tệp BMP là cấu trúc đó có thêm phần đầu tệp 14 byte ở phía trước.
BMP có phải định dạng không mất dữ liệu?
Đúng. Tệp BMP không nén và nén RLE giữ chính xác giá trị điểm ảnh. Ngoại lệ duy nhất là những tệp BMP hiếm hoi chứa dữ liệu JPEG nhúng.
Chuyển BMP sang PNG có làm giảm chất lượng không?
Không. PNG cũng không mất dữ liệu; hình ảnh giữ nguyên và chỉ nhỏ đi vì được nén.
Có dùng BMP trên website được không?
Trình duyệt hiển thị được BMP, nhưng tệp nặng một cách không cần thiết và làm chậm trang. Hãy dùng JPG, PNG, WebP hoặc AVIF cho web.
BMP có hỗ trợ độ trong suốt không?
Về lý thuyết, BMP 32 bit có thể mang kênh alpha, nhưng phần mềm không hỗ trợ nó một cách nhất quán. PNG là lựa chọn an toàn hơn bất cứ khi nào bạn cần độ trong suốt.


