Trong đồ họa máy vi tính, BMP, còn được biết đến với tên tiếng Anh khác là Windows bitmap, là một định dạng tập tin hình ảnh khá phổ biến. Các tập tin đồ họa lưu dưới dạng BMP thường có đuôi là .BMP hoặc .DIB (Device Independent Bitmap).
Các thuộc tính tiêu biểu của một tập tin ảnh BMP (cũng như file ảnh nói chung) là
- số bit trên mỗi điểm ảnh (bit per pixel), thường được ký hiệu bởi n. Một ảnh BMP n-bit có 2n màu. Giá trị n càng lớn thì ảnh càng có nhiều màu, và càng rõ nét hơn. Giá trị tiêu biểu của n là 1 (ảnh đen trắng), 4 (ảnh 16 màu), 8 (ảnh 256 màu), 16 (ảnh 65536 màu) và 24 (ảnh 16 triệu màu). Ảnh BMP 24-bit có chất lượng hình ảnh trung thực nhất.
- chiều cao của ảnh (height), cho bởi điểm ảnh (pixel).
- chiều rộng của ảnh (width), cho bởi điểm ảnh.
Cấu trúc tập tin ảnh BMP bao gồm 4 phần
- Bitmap Header (14 bytes): giúp nhận dạng tập tin bitmap.
- Bitmap Information (40 bytes): lưu một số thông tin chi tiết giúp hiển thị ảnh.
- Color Palette (4*x bytes), x là số màu của ảnh: định nghĩa các màu sẽ được sử dụng trong ảnh.
- Bitmap Data: lưu dữ liệu ảnh.
Đặc điểm nổi bật nhất của định dạng BMP là tập tin hình ảnh thường không được nén bằng bất kỳ thuật toán nào. Khi lưu ảnh, các điểm ảnh được ghi trực tiếp vào tập tin – một điểm ảnh sẽ được mô tả bởi một hay nhiều byte tùy thuộc vào giá trị n của ảnh. Do đó, một hình ảnh lưu dưới dạng BMP thường có kích cỡ rất lớn, gấp nhiều lần so với các ảnh được nén (chẳng hạn GIF, JPEG hay PNG).
Định dạng BMP được hỗ trợ bởi hầu hết các phần mềm đồ họa chạy trên Windows, và cả một số ứng dụng chạy trên MS-DOS. Ngay từ Windows 3.1, Microsoft đã cho ra đời phần mềm PaintBrush, một phần mềm hỗ trợ vẽ hình ảnh đơn giản và lưu hình ảnh được vẽ dưới dạng BMP 16 hay 256 màu. Tuy nhiên, do kích thước tập tin ảnh BMP quá lớn, định dạng BMP không phù hợp để trao đổi hình ảnh qua mạng Internet (do hạn chế về tốc độ truyền dữ liệu). Do đó, các trang web thường sử dụng ảnh dạng GIF, JPEG hay PNG. Các định dạng này hỗ trợ các thuật toán nén hình ảnh, vì vậy có thể giảm bớt kích cỡ của ảnh.
(theo Wikipedia)
Cấu trúc Bitmap Header và Bitmap Information
struct bmHeader // 14 byte
{
short type; // 2 byte - Mã nhận dạng file bitmap
unsigned int size;// 4 byte - Kích thước của file tính theo byte
int reserved; // 4 byte - Dự trữ, không sử dụng
int offset; // 4 byte - Vị trí bắt đầu dữ liệu ảnh
};
struct bmInfo // 40 byte
{
unsigned long infoSize; // 4 byte - Kích thước phần Information (luôn là 40)
unsigned long width; // 4 byte - Chiều rộng ảnh tính bằng pixel
unsigned long height; // 4 byte - Chiều cao ảnh tính bằng pixel
unsigned short planes; // 2 byte - Số plane màu (thường là 1)
unsigned short bitsPerPixel;// 2 byte - Độ sâu của màu, mang các giá trị 1,4,8 hoặc 24
unsigned long compression; // 4 byte - Kiểu nén (0: không nén);(1:run_lenght(8 bit/pixel));(2:run_length(4 bit/pixel))
unsigned long sizeImage; // 4 byte - Kích thước phần dữ liệu ảnh tính theo byte
long xPelsPerMeter; // 4 byte - Độ phân giải ngang (metter)
long yPelsPerMeter; // 4 byte - Độ phân giải dọc (metter)
unsigned long clrUsed; // 4 byte - Số màu sử dụng (= 0 nếu là tất cả)
unsigned long clrImportant; // 4 byte - Số màu quan trọng (= 0 nếu là tất cả)
};
{
short type; // 2 byte - Mã nhận dạng file bitmap
unsigned int size;// 4 byte - Kích thước của file tính theo byte
int reserved; // 4 byte - Dự trữ, không sử dụng
int offset; // 4 byte - Vị trí bắt đầu dữ liệu ảnh
};
struct bmInfo // 40 byte
{
unsigned long infoSize; // 4 byte - Kích thước phần Information (luôn là 40)
unsigned long width; // 4 byte - Chiều rộng ảnh tính bằng pixel
unsigned long height; // 4 byte - Chiều cao ảnh tính bằng pixel
unsigned short planes; // 2 byte - Số plane màu (thường là 1)
unsigned short bitsPerPixel;// 2 byte - Độ sâu của màu, mang các giá trị 1,4,8 hoặc 24
unsigned long compression; // 4 byte - Kiểu nén (0: không nén);(1:run_lenght(8 bit/pixel));(2:run_length(4 bit/pixel))
unsigned long sizeImage; // 4 byte - Kích thước phần dữ liệu ảnh tính theo byte
long xPelsPerMeter; // 4 byte - Độ phân giải ngang (metter)
long yPelsPerMeter; // 4 byte - Độ phân giải dọc (metter)
unsigned long clrUsed; // 4 byte - Số màu sử dụng (= 0 nếu là tất cả)
unsigned long clrImportant; // 4 byte - Số màu quan trọng (= 0 nếu là tất cả)
};
Để đọc file bitmap ta cần mở file để đọc dưới dạng nhị phân:
#include <fstream>
using namespace std;
...
ifstream fi(fName, ios::binary);
//Các lệnh đọc file
fi.close();
using namespace std;
...
ifstream fi(fName, ios::binary);
//Các lệnh đọc file
fi.close();
Ta dùng phương thức read của ifstream để đọc dữ liệu Bitmap Header và Bitmap Infomation
Phương thức (hàm) read của ifstream nhận vào 2 tham số: một con trỏ kiểu char và kích thước dữ liệu đọc (kiểu int), do đó ta phải “ép kiểu” cho địa chỉ của header và info về kiểu con trỏ char.
bmHeader header;
bmInfo info;
fi.read((char*)&header, sizeof(header));
fi.read((char*)&info, sizeof(info));
bmInfo info;
fi.read((char*)&header, sizeof(header));
fi.read((char*)&info, sizeof(info));
Kiểm tra mã nhận dạng xem có đúng là file bitmap hay không
const short bmSign = 'MB';
if (header.type != bmSign) //Kiểm tra mã nhận dạng
{
//Thoát hàm đọc file, trả về kết quả đọc thất bại
}
if (header.type != bmSign) //Kiểm tra mã nhận dạng
{
//Thoát hàm đọc file, trả về kết quả đọc thất bại
}
Đọc bảng màu và dữ liệu ảnh
colorPaletteSize = header.offset - 54; //Kích thước của bảng màu
char* colorPalette = new char[colorPaletteSize];
fi.read(colorPalette, colorPaletteSize);
char* bmData = new char[info.sizeImage];
fi.read(bmData, info.sizeImage);
char* colorPalette = new char[colorPaletteSize];
fi.read(colorPalette, colorPaletteSize);
char* bmData = new char[info.sizeImage];
fi.read(bmData, info.sizeImage);
Class MyBitmap đọc file ảnh bitmap và chuyển từng pixcel vào mảng 2 chiều
/*
(c) http://kithuatlaptrinh.tk
Class MyBitmap, đọc file ảnh bitmap và chuyển từng pixcel vào mảng 2 chiều
Đọc được ảnh 1, 4, 8, 16 và 24 bit
Truy xuất từng pixcel bằng toán tử [] như trên mảng 2 chiều
*/
#pragma once
#include <iostream>
#include <fstream>
using namespace std;
static const short bmSign = 'MB'; //Mã nhận dạng file bitmap
#pragma pack(push, 2)// căn lề 1 byte cho struct
struct bmHeader // 14 byte
{
short type; // 2 byte - Mã nhận dạng file bitmap
unsigned int size;// 4 byte - Kích thước của file tính theo byte
int reserved; // 4 byte - Dự trữ, không sử dụng
int offset; // 4 byte - Vị trí bắt đầu dữ liệu ảnh
};
struct bmInfo // 40 byte
{
unsigned long infoSize; // 4 byte - Kích thước phần Information (luôn là 40)
unsigned long width; // 4 byte - Chiều rộng ảnh tính bằng pixel
unsigned long height; // 4 byte - Chiều cao ảnh tính bằng pixel
unsigned short planes; // 2 byte - Số plane màu (thường là 1)
unsigned short bitsPerPixel;// 2 byte - Độ sâu của màu, mang các giá trị 1,4,8 hoặc 24
unsigned long compression; // 4 byte - Kiểu nén (0: không nén);(1:run_lenght(8 bit/pixel));(2:run_length(4 bit/pixel))
unsigned long sizeImage; // 4 byte - Kích thước phần dữ liệu ảnh tính theo byte
long xPelsPerMeter; // 4 byte - Độ phân giải ngang (metter)
long yPelsPerMeter; // 4 byte - Độ phân giải dọc (metter)
unsigned long clrUsed; // 4 byte - Số màu sử dụng (= 0 nếu là tất cả)
unsigned long clrImportant; // 4 byte - Số màu quan trọng (= 0 nếu là tất cả)
};
#pragma pack(pop)
class CMyBitmap
{
bmHeader header;
bmInfo info;
char* colorPalette; //Lưu bảng màu
unsigned long colorPaletteSize; //Kích thước vùng bảng màu
char* bmData; //Lưu dữ liệu ảnh
unsigned long rowSize; //Kích thước mỗi dòng dữ liệu ảnh (byte)
void swap4byte(char*); //Đảo 4 byte Little Endian <-> Big Endian
unsigned long** pixcel; //Mảng các pixcel
unsigned long getPixel(unsigned long, unsigned long);
void setPixel(unsigned long, unsigned long, unsigned long);
void freeMem();
public:
unsigned long height();
unsigned long width();
unsigned short bitsPerPixel();
unsigned long* operator [] (unsigned int); //Toán tử lấy pixcel, trả về con trỏ đến dòng i
bool readFile(const char*);
bool writeFile(const char*);
CMyBitmap(void);
~CMyBitmap(void);
};
(c) http://kithuatlaptrinh.tk
Class MyBitmap, đọc file ảnh bitmap và chuyển từng pixcel vào mảng 2 chiều
Đọc được ảnh 1, 4, 8, 16 và 24 bit
Truy xuất từng pixcel bằng toán tử [] như trên mảng 2 chiều
*/
#pragma once
#include <iostream>
#include <fstream>
using namespace std;
static const short bmSign = 'MB'; //Mã nhận dạng file bitmap
#pragma pack(push, 2)// căn lề 1 byte cho struct
struct bmHeader // 14 byte
{
short type; // 2 byte - Mã nhận dạng file bitmap
unsigned int size;// 4 byte - Kích thước của file tính theo byte
int reserved; // 4 byte - Dự trữ, không sử dụng
int offset; // 4 byte - Vị trí bắt đầu dữ liệu ảnh
};
struct bmInfo // 40 byte
{
unsigned long infoSize; // 4 byte - Kích thước phần Information (luôn là 40)
unsigned long width; // 4 byte - Chiều rộng ảnh tính bằng pixel
unsigned long height; // 4 byte - Chiều cao ảnh tính bằng pixel
unsigned short planes; // 2 byte - Số plane màu (thường là 1)
unsigned short bitsPerPixel;// 2 byte - Độ sâu của màu, mang các giá trị 1,4,8 hoặc 24
unsigned long compression; // 4 byte - Kiểu nén (0: không nén);(1:run_lenght(8 bit/pixel));(2:run_length(4 bit/pixel))
unsigned long sizeImage; // 4 byte - Kích thước phần dữ liệu ảnh tính theo byte
long xPelsPerMeter; // 4 byte - Độ phân giải ngang (metter)
long yPelsPerMeter; // 4 byte - Độ phân giải dọc (metter)
unsigned long clrUsed; // 4 byte - Số màu sử dụng (= 0 nếu là tất cả)
unsigned long clrImportant; // 4 byte - Số màu quan trọng (= 0 nếu là tất cả)
};
#pragma pack(pop)
class CMyBitmap
{
bmHeader header;
bmInfo info;
char* colorPalette; //Lưu bảng màu
unsigned long colorPaletteSize; //Kích thước vùng bảng màu
char* bmData; //Lưu dữ liệu ảnh
unsigned long rowSize; //Kích thước mỗi dòng dữ liệu ảnh (byte)
void swap4byte(char*); //Đảo 4 byte Little Endian <-> Big Endian
unsigned long** pixcel; //Mảng các pixcel
unsigned long getPixel(unsigned long, unsigned long);
void setPixel(unsigned long, unsigned long, unsigned long);
void freeMem();
public:
unsigned long height();
unsigned long width();
unsigned short bitsPerPixel();
unsigned long* operator [] (unsigned int); //Toán tử lấy pixcel, trả về con trỏ đến dòng i
bool readFile(const char*);
bool writeFile(const char*);
CMyBitmap(void);
~CMyBitmap(void);
};
hay quá, cảm ơn bạn (o)
Trả lờiXóađúng cái mình đang cần. thank nhiều:-)
Trả lờiXóasao mediafire k tai ve dc ban :(
Trả lờiXóamediafire bây giờ ra chính sách bản quyền cho các tài liệu up lên nên file đó bị giới hạn bản quyền rồi bạn ơi. bạn xem tạo code phía trên mình sẽ tì lại source và up lên lại
Trả lờiXóalink die
Trả lờiXóaUp lại link giùm đi bạn ơi, đang rất cần
Trả lờiXóacái project này mình làm lâu quá rồi. mất code rồi các bạn ơi. các bạn chiu khó đọc và làm theo nha
Trả lờiXóa:(( link die
Trả lờiXóa