c++ base64写jpg
时间: 2023-10-14 15:16:59 浏览: 71
c++ base64 编码工具
这里提供一个基于 C++11 标准的 base64 编码和解码实现,以及使用 libjpeg-turbo 库读取和写入 JPEG 图片的示例代码:
```cpp
#include <iostream>
#include <string>
#include <vector>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <jpeglib.h>
// Base64 编码
std::string base64_encode(const std::string& input) {
static const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::string output;
output.reserve(((input.size() + 2) / 3) * 4);
uint32_t buf = 0;
int bits = 0;
for (char c : input) {
buf = (buf << 8) | static_cast<uint8_t>(c);
bits += 8;
while (bits >= 6) {
bits -= 6;
output.push_back(table[(buf >> bits) & 0x3F]);
}
}
if (bits > 0) {
buf <<= (6 - bits);
output.push_back(table[buf & 0x3F]);
while (bits < 6) {
output.push_back('=');
bits += 2;
}
}
return output;
}
// Base64 解码
std::string base64_decode(const std::string& input) {
static const unsigned char table[] = {
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, // 0-15
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 62, 99, 99, 99, 63, // 16-31
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 99, 99, 99, 64, 99, 99, // 32-47
99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 48-63
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 99, 99, 99, 99, 99, // 64-79
99, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 80-95
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 99, 99, 99, 99, 99, // 96-111
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, // 112-127
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, // 128-143
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, // 144-159
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, // 160-175
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, // 176-191
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, // 192-207
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, // 208-223
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, // 224-239
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 // 240-255
};
std::string output;
output.reserve(input.size() * 3 / 4);
uint32_t buf = 0;
int bits = 0;
for (char c : input) {
if (c == '=') {
break;
}
buf = (buf << 6) | table[static_cast<uint8_t>(c)];
bits += 6;
if (bits >= 8) {
bits -= 8;
output.push_back((buf >> bits) & 0xFF);
}
}
return output;
}
// 读取 JPEG 图片
bool read_jpeg(const std::string& filename, std::vector<uint8_t>& data, int& width, int& height) {
FILE* fp = fopen(filename.c_str(), "rb");
if (!fp) {
return false;
}
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, fp);
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
width = cinfo.output_width;
height = cinfo.output_height;
int row_stride = width * cinfo.output_components;
data.resize(row_stride * height);
while (cinfo.output_scanline < cinfo.output_height) {
uint8_t* buffer[1] = { &data[cinfo.output_scanline * row_stride] };
jpeg_read_scanlines(&cinfo, buffer, 1);
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(fp);
return true;
}
// 写入 JPEG 图片
bool write_jpeg(const std::string& filename, const std::vector<uint8_t>& data, int width, int height, int quality = 90) {
FILE* fp = fopen(filename.c_str(), "wb");
if (!fp) {
return false;
}
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, fp);
cinfo.image_width = width;
cinfo.image_height = height;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE);
jpeg_start_compress(&cinfo, TRUE);
int row_stride = width * 3;
while (cinfo.next_scanline < cinfo.image_height) {
const uint8_t* buffer = &data[cinfo.next_scanline * row_stride];
jpeg_write_scanlines(&cinfo, const_cast<uint8_t**>(&buffer), 1);
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
fclose(fp);
return true;
}
int main() {
// 读取 JPEG 图片
std::vector<uint8_t> jpg_data;
int width = 0, height = 0;
if (!read_jpeg("input.jpg", jpg_data, width, height)) {
std::cerr << "Failed to read input.jpg" << std::endl;
return EXIT_FAILURE;
}
// Base64 编码
std::string base64_data = base64_encode(std::string(reinterpret_cast<const char*>(jpg_data.data()), jpg_data.size()));
// Base64 解码
std::vector<uint8_t> decoded_data(base64_decode(base64_data));
// 写入 JPEG 图片
if (!write_jpeg("output.jpg", decoded_data, width, height)) {
std::cerr << "Failed to write output.jpg" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
```
说明:
- `base64_encode` 函数实现了 Base64 编码。
- `base64_decode` 函数实现了 Base64 解码。
- `read_jpeg` 函数使用 libjpeg-turbo 库读取 JPEG 图片。
- `write_jpeg` 函数使用 libjpeg-turbo 库写入 JPEG 图片。
- 主函数中读取输入图片,进行 Base64 编码,再解码为二进制数据,并写入输出图片。
注意事项:
- 本示例代码使用了 libjpeg-turbo 库,请确保已经安装并配置好该库。
- 本示例代码仅支持 RGB 格式的 JPEG 图片,如果需要处理其他格式的 JPEG 图片,需要修改相关代码。
阅读全文