图像RGB重新排序

//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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值