PGM là Portable Gray Map. Muốn lưu mảng 2D trong C thành ảnh PNG, JPEG, cần encode dữ liệu theo định dạng quy định trước khi ghi file.
Định dạng Netpbm giải pháp dễ dàng và di động. Netpbm là gói đồ họa mã nguồn mở dùng chủ yếu Linux/Unix, cũng chạy Windows.
Mỗi file bắt đầu magic number 2 byte. Magic number xác định loại file: PBM, PGM, PPM. Cũng xác định encoding (ASCII hoặc Binary). Magic number là chữ P in hoa theo sau số 1 chữ số.
Encoding ASCII cho đọc được người và chuyển nền tảng dễ; binary hiệu quả dung lượng nhưng có vấn đề byte-order bản địa.
Cách ghi file PGM:
- Đặt magic number P2
- Thêm whitespace (Space, Tabs, CRs, LFs)
- Thêm width, dạng ASCII decimal
- Thêm Whitespace
- Thêm height, dạng ASCII decimal
- Thêm Whitespace
- Đặt giá trị xám tối đa, ASCII decimal
- Thêm Whitespace
- Width x Height giá trị xám, mỗi giá trị ASCII decimal (0 đến max), cách nhau whitespace từ trên xuống dưới.
Ví dụ mã
#include <stdio.h>
main() {
int i, j;
int w = 13, h = 13;
// Mảng 2D chuyển thành ảnh, kích thước 13x13
int image[13][13] = {
{ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 },
{ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31},
{ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47},
{ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63},
{ 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79},
{ 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95 },
{ 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111},
{ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127},
{ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143},
{ 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159},
{ 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175},
{ 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191},
{ 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207}
};
FILE* pgmimg;
pgmimg = fopen("my_pgmimg.pgm", "wb"); // ghi file chế độ binary
fprintf(pgmimg, "P2\n"); // Ghi Magic Number
fprintf(pgmimg, "%d %d\n", w, h); // Ghi Width Height
fprintf(pgmimg, "255\n"); // Ghi giá trị xám tối đa
int count = 0;
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
fprintf(pgmimg, "%d ", image[i][j]); // Copy giá trị xám từ mảng ra file
}
fprintf(pgmimg, "\n");
}
fclose(pgmimg);
}Ảnh PGM trông như sau:
Kết quả
