You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:实现JPG转Base64的C++方案(适配PLC与Web传输)

问题分析与解决方案

你的问题核心有两个:一是二进制文件读取方式错误,二是缺少Base64编码步骤——直接输出二进制字节当然会显示乱码,Base64是把二进制数据转换成ASCII字符集的编码格式,需要专门的编码逻辑。

为什么你的代码失败?

  • getline是为文本文件设计的,它会在遇到\n或\0时停止读取,而二进制图片文件里充满了这类控制字符,导致你读取的内容不完整,甚至提前中断。
  • 你只是把读取到的二进制字节直接写入文本文件,这些字节大多是非ASCII字符,自然显示成乱码,完全没有做Base64编码转换。

正确的实现步骤

1. 完整读取二进制图片文件

用ifstream的read方法一次性读取所有字节到缓冲区(比如std::vector<unsigned char>),避免文本读取函数的截断问题。

2. 实现Base64编码

C++标准库没有内置Base64编码器,所以我们需要自己实现一个简单版本。Base64的编码规则是:

  • 将每3个字节(24位)拆分成4个6位的片段
  • 每个6位片段对应Base64编码表中的一个字符
  • 如果最后剩余1个字节,补两个=;剩余2个字节,补一个=

完整代码示例

#include <iostream>
#include <fstream>
#include <vector>
#include <string>

// Base64编码表
const std::string base64_chars = 
             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
             "abcdefghijklmnopqrstuvwxyz"
             "0123456789+/";

// 二进制数据转Base64字符串
std::string base64_encode(const unsigned char* bytes_to_encode, unsigned int in_len) {
    std::string ret;
    int i = 0;
    int j = 0;
    unsigned char char_array_3[3];
    unsigned char char_array_4[4];

    while (in_len--) {
        char_array_3[i++] = *(bytes_to_encode++);
        if (i == 3) {
            char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
            char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
            char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
            char_array_4[3] = char_array_3[2] & 0x3f;

            for(i = 0; (i <4) ; i++)
                ret += base64_chars[char_array_4[i]];
            i = 0;
        }
    }

    if (i) {
        for(j = i; j < 3; j++)
            char_array_3[j] = '\0';

        char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
        char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
        char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
        char_array_4[3] = char_array_3[2] & 0x3f;

        for (j = 0; (j < i + 1); j++)
            ret += base64_chars[char_array_4[j]];

        while((i++ < 3))
            ret += '=';
    }

    return ret;
}

int main() {
    // 1. 读取二进制图片文件
    std::ifstream input("test.jpg", std::ios::binary | std::ios::ate);
    if (!input.is_open()) {
        std::cerr << "无法打开图片文件!" << std::endl;
        return 1;
    }

    // 获取文件大小,分配缓冲区
    std::streampos file_size = input.tellg();
    std::vector<unsigned char> image_data(file_size);

    // 回到文件开头,读取全部内容
    input.seekg(0, std::ios::beg);
    input.read(reinterpret_cast<char*>(image_data.data()), file_size);
    input.close();

    // 2. 进行Base64编码
    std::string base64_str = base64_encode(image_data.data(), image_data.size());

    // 3. 写入到文本文件
    std::ofstream output("text.txt");
    if (output.is_open()) {
        output << base64_str;
        output.close();
        std::cout << "Base64编码完成,已写入text.txt" << std::endl;
    } else {
        std::cerr << "无法打开输出文件!" << std::endl;
        return 1;
    }

    return 0;
}

额外注意事项

  • 你的Web端代码里写的是data:image/png;base64,,但你处理的是JPG图片,应该改成data:image/jpeg;base64,,否则Web应用可能无法正确解析显示图片。
  • 如果PLC对传输的字符串长度有要求,你可能需要考虑分块传输Base64字符串,或者压缩图片后再编码(不过JPG本身已经是压缩格式,压缩空间不大)。

内容的提问来源于stack exchange,提问作者EterNaL_SC2

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:59:43