//RGB 排序
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
#pragma pack(push, 1) // 禁用结构体对齐
struct BMPHeader {
char signature[2];
int32_t file_size;
int16_t reserved1;
int16_t reserved2;
int32_t offset;
int32_t dib_header_size;
int32_t width;
int32_t height;
int16_t color_planes;
int16_t bits_per_pixel;
int32_t compression_method;
int32_t image_size;
int32_t horizontal_resolution;
int32_t vertical_resolution;
int32_t colors_in_palette;
int32_t important_colors;
};
#pragma pack(pop) // 恢复默认结构体对齐
// 函数声明,用于重新排序像素数据
void reorderPixels(vector<vector<vector<uint8_t>>>& pixels, vector<vector<vector<uint8_t>>>& reordered_pixels, int height, int width);
int main() {
const char* input_file = "1.bmp";
// 所有可能的排序顺序
vector<string> orderings = { "RGB", "RBG", "GRB", "GBR", "BRG", "BGR" };
// 打开 BMP 文件并读取文件头
ifstream bmp_file(input_file, ios::binary);
if (!bmp_file.is_open()) {
cout << "无法打开 BMP 文件!" << endl;
return -1;
}
BMPHeader header;
bmp_file.read(reinterpret_cast<char*>(&header), sizeof(header));
if (header.signature[0] != 'B' || header.signature[1] != 'M') {
cout << "不是有效的 BMP 文件!" << endl;
return -1;
}
int width = header.width;
int height = header.height;
int bytes_per_pixel = header.bits_per_pixel / 8;
// 读取像素数据
vector<vector<vector<uint8_t>>> pixels(height, vector<vector<uint8_t>>(width, vector<uint8_t>(bytes_per_pixel)));
bmp_file.seekg(header.offset, ios::beg);
for (int y = height - 1; y >= 0; --y) {
for (int x = 0; x < width; ++x) {
bmp_file.read(reinterpret_cast<char*>(pixels[y][x].data()), bytes_per_pixel);
}
}
bmp_file.close();
// 对每种排序顺序生成一个新的 BMP 文件
for (const auto& order : orderings) {
vector<vector<vector<uint8_t>>> reordered_pixels(height, vector<vector<uint8_t>>(width, vector<uint8_t>(bytes_per_pixel)));
// 重新排序像素数据
reorderPixels(pixels, reordered_pixels, height, width);
// 写入重新排序后的 BMP 文件
string output_file = "output_" + order + ".bmp";
ofstream output_bmp(output_file, ios::binary);
if (!output_bmp.is_open()) {
cout << "无法创建输出 BMP 文件:" << output_file << endl;
continue;
}
// 写入文件头部
output_bmp.write(reinterpret_cast<const char*>(&header), sizeof(header));
// 写入重新排序后的像素数据
for (int y = height - 1; y >= 0; --y) {
for (int x = 0; x < width; ++x) {
if (order == "RGB") {
output_bmp.write(reinterpret_cast<const char*>(pixels[y][x].data()), bytes_per_pixel);
}
else if (order == "RBG") {
output_bmp.write(reinterpret_cast<const char*>(pixels[y][x].data()) + 2, 1); // R
output_bmp.write(reinterpret_cast<const char*>(pixels[y][x].data()) + 1, 1); // B
output_bmp.write(reinterpret_cast<const char*>(pixels[y][x].data()), 1); // G
}
else if (order == "GRB") {
output_bmp.write(reinterpret_cast<const char*>(pixels[y][x].data()) + 1, 1); // G
output_bmp.write(reinterpret_cast<const char*>(pixels[y][x].data()), 1); // R
output_bmp.write(reinterpret_cast<const char*>(pixels[y][x].data()) + 2, 1); // B
}
else if (order == "GBR") {
output_bmp.write(reinterpret_cast<const char*>(pixels[y][x].data()) + 1, 1); // G
output_bmp.write(reinterpret_cast<const char*>(pixels[y][x].data()) + 2, 1); // B
output_bmp.write(reinterpret_cast<const char*>(pixels[y][x].data()), 1); // R
}
else if (order == "BRG") {
output_bmp.write(reinterpret_cast<const char*>(pixels[y][x].data()) + 2, 1); // B
output_bmp.write(reinterpret_cast<const char*>(pixels[y][x].data()), 1); // R
output_bmp.write(reinterpret_cast<const char*>(pixels[y][x].data()) + 1, 1); // G
}
else if (order == "BGR") {
output_bmp.write(reinterpret_cast<const char*>(pixels[y][x].data()) + 2, 1); // B
output_bmp.write(reinterpret_cast<const char*>(pixels[y][x].data()) + 1, 1); // G
output_bmp.write(reinterpret_cast<const char*>(pixels[y][x].data()), 1); // R
}
}
}
output_bmp.close();
cout << "已创建 BMP 文件:" << output_file << endl;
}
return 0;
}
// 函数定义,重新排序像素数据
void reorderPixels(vector<vector<vector<uint8_t>>>& pixels, vector<vector<vector<uint8_t>>>& reordered_pixels, int height, int width) {
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
reordered_pixels[y][x] = { pixels[y][x][2], pixels[y][x][1], pixels[y][x][0] };
}
}
}
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm> // For std::swap
#include <cstdlib> // for std::atoi
#include <string>
#pragma pack(push, 1) // 设置按字节对齐
// BMP文件头结构体
struct BMPFileHeader {
char type[2]; // 文件类型,"BM"
uint32_t size; // 文件大小
uint16_t reserved1; // 保留字段,必须为0
uint16_t reserved2; // 保留字段,必须为0
uint32_t offset; // 位图数据起始位置
};
// BMP信息头结构体
struct BMPInfoHeader {
uint32_t size; // 信息头大小
int32_t width; // 图像宽度
int32_t height; // 图像高度
uint16_t planes; // 色彩平面数,必须为1
uint16_t bitCount; // 每个像素位数
uint32_t compression; // 压缩方式
uint32_t imageSize; // 图像大小,字节为单位
int32_t xPixelsPerMeter; // 水平分辨率
int32_t yPixelsPerMeter; // 垂直分辨率
uint32_t colorsUsed; // 实际使用的颜色表中的颜色数
uint32_t colorsImportant; // 重要的颜色数
};
#pragma pack(pop) // 恢复默认对齐方式
bool readBMPHeaders(const std::string& filename, BMPFileHeader& fileHeader, BMPInfoHeader& infoHeader) {
std::ifstream bmpFile(filename, std::ios::binary);
if (!bmpFile) {
std::cerr << "Error opening BMP file: " << filename << std::endl;
return false;
}
// 读取文件头
bmpFile.read(reinterpret_cast<char*>(&fileHeader), sizeof(BMPFileHeader));
if (fileHeader.type[0] != 'B' || fileHeader.type[1] != 'M') {
std::cerr << "Error: " << filename << " is not a BMP file." << std::endl;
return false;
}
// 读取信息头
bmpFile.read(reinterpret_cast<char*>(&infoHeader), sizeof(BMPInfoHeader));
bmpFile.close();
return true;
}
void processPixelData(std::vector<uint8_t>& imageData, int width, int height) {
int bytesPerPixel = 3; // 每像素3个字节 (B, G, R)
int rowSize = width * bytesPerPixel;
// 对每四个像素组进行操作
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; x += 4) {
int index1 = y * rowSize + x * bytesPerPixel;
int index2 = index1 + bytesPerPixel;
int index3 = index1 + 2 * bytesPerPixel;
int index4 = index1 + 3 * bytesPerPixel;
// 保存原始像素数据
std::vector<uint8_t> originalPixels(4 * bytesPerPixel);
originalPixels[0] = imageData[index1];
originalPixels[1] = imageData[index1 + 1];
originalPixels[2] = imageData[index1 + 2];
originalPixels[3] = imageData[index2];
originalPixels[4] = imageData[index2 + 1];
originalPixels[5] = imageData[index2 + 2];
originalPixels[6] = imageData[index3];
originalPixels[7] = imageData[index3 + 1];
originalPixels[8] = imageData[index3 + 2];
originalPixels[9] = imageData[index4];
originalPixels[10] = imageData[index4 + 1];
originalPixels[11] = imageData[index4 + 2];
// 第一个像素 R 和 G 交换顺序
std::swap(imageData[index1], imageData[index1 + 1]);
// 将第三个像素的 B 替换第二个像素的 R
std::swap(imageData[index2 + 2], imageData[index1 + 2]);
// 将第二个像素的 R 替换第三个像素的 B
std::swap(imageData[index2], imageData[index3 + 2]);
// 第四个像素 G 和 B 交换顺序
std::swap(imageData[index4 + 1], imageData[index4 + 2]);
}
}
}
bool writeBMP(const std::string& filename, const BMPFileHeader& fileHeader, const BMPInfoHeader& infoHeader, const std::vector<uint8_t>& imageData) {
std::ofstream bmpFile(filename, std::ios::binary);
if (!bmpFile) {
std::cerr << "Error creating BMP file: " << filename << std::endl;
return false;
}
// 写入文件头和信息头
bmpFile.write(reinterpret_cast<const char*>(&fileHeader), sizeof(BMPFileHeader));
bmpFile.write(reinterpret_cast<const char*>(&infoHeader), sizeof(BMPInfoHeader));
// 写入像素数据
bmpFile.write(reinterpret_cast<const char*>(imageData.data()), imageData.size());
bmpFile.close();
return true;
}
void processPixelData_RGBTOBGR(std::vector<uint8_t>& imageData, int width, int height) {
int bytesPerPixel = 3; // Assuming 24-bit RGB (3 bytes per pixel)
for (int i = 0; i < width * height; ++i) {
uint8_t temp = imageData[i * bytesPerPixel]; // Save R
imageData[i * bytesPerPixel] = imageData[i * bytesPerPixel + 2]; // Swap B to R
imageData[i * bytesPerPixel + 2] = temp; // Swap R to B
// Green component (imageData[i * bytesPerPixel + 1]) remains unchanged in RGB to BGR conversion.
}
}
int main(int argc, char* argv[])
{
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << "PixelRearrangement.exe <path>" << std::endl;
return 1;
}
std::string inputFilename = argv[1];
std::string outputFilename = "PixelRearrangement.bmp";
BMPFileHeader fileHeader;
BMPInfoHeader infoHeader;
if (readBMPHeaders(inputFilename, fileHeader, infoHeader)) {
std::cout << "Image width: " << infoHeader.width << std::endl;
std::cout << "Image height: " << infoHeader.height << std::endl;
std::cout << "Bits per pixel: " << infoHeader.bitCount << std::endl;
// 计算每像素字节数
int bytesPerPixel = infoHeader.bitCount / 8;
int imageDataSize = infoHeader.width * infoHeader.height * bytesPerPixel;
// 读取像素数据
std::vector<uint8_t> imageData(imageDataSize);
std::ifstream bmpFile(inputFilename, std::ios::binary);
bmpFile.seekg(fileHeader.offset); // 定位到位图数据起始位置
bmpFile.read(reinterpret_cast<char*>(imageData.data()), imageDataSize);
bmpFile.close();
// 处理像素数据
processPixelData(imageData, infoHeader.width, infoHeader.height);
processPixelData_RGBTOBGR(imageData, infoHeader.width, infoHeader.height);
// 写入修改后的像素数据到新的BMP文件
if (writeBMP(outputFilename, fileHeader, infoHeader, imageData)) {
std::cout << "Modified BMP file saved as: " << outputFilename << std::endl;
}
else {
std::cerr << "Failed to save BMP file." << std::endl;
}
}
return 0;
}