-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrestore.cpp.back
More file actions
127 lines (106 loc) · 3.76 KB
/
restore.cpp.back
File metadata and controls
127 lines (106 loc) · 3.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <iostream>
#include <vector>
#include <fstream>
#include <filesystem>
#include <stdexcept>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image_write.h"
namespace fs = std::filesystem;
#pragma pack(push, 1)
struct BMPHeader {
uint16_t signature = 0x4D42;
uint32_t file_size;
uint16_t reserved1 = 0;
uint16_t reserved2 = 0;
uint32_t data_offset = 62;
uint32_t header_size = 40;
int32_t width;
int32_t height;
uint16_t planes = 1;
uint16_t bits_per_pixel = 1;
uint32_t compression = 0;
uint32_t image_size;
int32_t x_resolution = 2835;
int32_t y_resolution = 2835;
uint32_t colors_used = 2;
uint32_t colors_important = 2;
};
#pragma pack(pop)
struct ImageData {
int width;
int height;
std::vector<bool> pixels;
};
ImageData read_1bit_bmp(const std::string& path) {
std::ifstream file(path, std::ios::binary);
if (!file) throw std::runtime_error("无法打开文件: " + path);
BMPHeader header;
file.read(reinterpret_cast<char*>(&header), sizeof(BMPHeader));
if (header.bits_per_pixel != 1)
throw std::runtime_error("非1位BMP文件: " + path);
// 读取调色板(2个颜色项)
uint32_t palette[2];
file.seekg(sizeof(BMPHeader) + 14); // 跳过文件头
file.read(reinterpret_cast<char*>(palette), 8);
// 计算行字节数(4字节对齐)
const int row_size = ((header.width + 31) / 32) * 4;
const int data_size = row_size * header.height;
// 读取位图数据
std::vector<uint8_t> buffer(data_size);
file.seekg(header.data_offset);
file.read(reinterpret_cast<char*>(buffer.data()), data_size);
// 转换为像素数据
ImageData result;
result.width = header.width;
result.height = header.height;
result.pixels.resize(header.width * header.height);
for (int y = 0; y < header.height; ++y) {
int actual_y = header.height - 1 -y;
for (int x = 0; x < header.width; ++x) {
const int byte_idx = x / 8;
const int bit_idx = 7 - (x % 8);
const uint8_t byte = buffer[actual_y * row_size + byte_idx];
result.pixels[y * header.width + x] = (byte >> bit_idx) & 1;
}
}
return result;
}
void restore_images(const std::string& input_dir, const std::string& output_dir) {
fs::create_directories(output_dir);
for (int img_num = 1; img_num < 2; ++img_num) {
std::vector<ImageData> layers;
// 读取5个有效层
for (int layer = 0; layer <= 5; ++layer) {
//const int file_num = (img_num - 1) * 6 + layer + 1;
const int file_num = img_num + layer + 6;
const std::string path = input_dir + "/" + std::to_string(file_num) + ".bmp";
layers.push_back(read_1bit_bmp(path));
}
// 生成灰度图像
std::vector<uint8_t> output(layers[0].width * layers[0].height);
for (size_t i = 0; i < output.size(); ++i) {
int sum = 0;
for (const auto& layer : layers)
sum += layer.pixels[i];
output[i] = static_cast<uint8_t>(sum * 51); // 51 = 255/5
}
// 保存8位BMP
const std::string out_path = output_dir + "/" + std::to_string(img_num) + ".bmp";
stbi_write_bmp(out_path.c_str(),
layers[0].width,
layers[0].height,
1, // 通道数(灰度)
output.data());
}
}
int main() {
try {
restore_images("output", "restored");
std::cout << "图像恢复完成!共处理40组240张输入文件" << std::endl;
} catch (const std::exception& e) {
std::cerr << "错误: " << e.what() << std::endl;
return 1;
}
return 0;
}