在C++中处理jpg、png等图片时,必须按二进制方式打开文件流,否则文本模式会在某些系统上篡改换行字节,导致图片无法打开。下面直接看如何用binary模式完成图片的读取与写回。

为什么要用binary模式
使用默认 ifstream 打开文件时,系统可能把 n 和 rn 互相转换,这对纯文本没问题,但图片字节中恰好含有这些数值就会被破坏。加上 ios::binary 标志可以禁止这种转换,保证字节原样读写。
读取二进制图片到内存
思路是先以binary模式打开,把文件指针移到末尾得到大小,再回到开头,用 read() 读入 char 数组。
#include <fstream>
#include <iostream>
#include <vector>
int main() {
// 以二进制读模式打开图片
std::ifstream in("test.jpg", std::ios::binary);
if (!in) {
std::cerr << "打开文件失败" << std::endl;
return 1;
}
// 获取文件大小
in.seekg(0, std::ios::end);
std::streamsize size = in.tellg();
in.seekg(0, std::ios::beg);
// 读入缓冲区
std::vector<char> buffer(size);
if (!in.read(buffer.data(), size)) {
std::cerr << "读取失败" << std::endl;
return 1;
}
in.close();
std::cout << "读取字节数: " << size << std::endl;
return 0;
}
将内存数据写回二进制图片
写出时用 ofstream 同样指定 ios::binary,调用 write() 即可。
#include <fstream>
#include <vector>
int main() {
std::vector<char> buffer;
// 假设buffer中已经装好从某处来的图片字节
// 这里仅为示例,直接写固定大小
buffer.resize(100);
for (int i = 0; i < 100; i++) buffer[i] = i % 256;
// 以二进制写模式保存
std::ofstream out("copy.jpg", std::ios::binary);
if (!out.write(buffer.data(), buffer.size())) {
return 1;
}
out.close();
return 0;
}
完整实战:复制一张图片
把读和写串起来,就是最常见的图片拷贝实战。
#include <fstream>
#include <iostream>
int main() {
std::ifstream in("source.png", std::ios::binary);
if (!in) {
std::cerr << "源文件打开失败" << std::endl;
return 1;
}
in.seekg(0, std::ios::end);
std::streamsize size = in.tellg();
in.seekg(0, std::ios::beg);
char* data = new char[size];
in.read(data, size);
in.close();
std::ofstream out("target.png", std::ios::binary);
out.write(data, size);
out.close();
delete[] data;
std::cout << "图片已复制" << std::endl;
return 0;
}
注意事项
- 路径中含中文时,部分编译器需要用宽字符接口,或保证系统编码一致。
- 读取后务必检查
gcount()是否等于预期大小。 - 网络收到的图片流也可以直接放进
vector<char>再按上面方式写文件。
只要坚持使用 ios::binary 并配合 read 和 write,C++读写二进制图片就非常稳定。