C++实现图片转base64的示例代码
1.base64编码的原因
网络传送渠道并不支持所有的字节,例如传统的邮件只支持可见字符的传送,像ASCII码的控制字符就不能通过邮件传送。这样用途就受到了很大的限制,比如图片二进制流的每个字节不可能全部是可见字符,所以就传送不了。最好的方法就是在不改变传统协议的情 况下,做一种扩展方案来支持二进制文件的传送。把不可打印的字符也能用可打印字符来表示,问题就解决了。Base64编码应运而生,Base64就是一种 基于64个可打印字符来表示二进制数据的表示方法。
2.base64编码原理
Base64编码的思想是是采用64个基本的ASCII码字符对数据进行重新编码。它将需要编码的数据拆分成字节数组。以3个字节为一组。按顺序排列24 位数据,再把这24位数据分成4组,即每组6位。再在每组的的最高位前补两个0凑足一个字节。这样就把一个3字节为一组的数据重新编码成了4个字节。当所要编码的数据的字节数不是3的整倍数,也就是说在分组时最后一组不够3个字节。这时在最后一组填充1到2个0字节。
3.实现代码
ZBase64.h
#include string using namespace std; class ZBase64 { public: /*编码 DataByte [in]输入的数据长度,以字节为单位 */ string Encode(const unsigned char* Data,int DataByte); /*解码 DataByte [in]输入的数据长度,以字节为单位 OutByte [out]输出的数据长度,以字节为单位,请不要通过返回值计算 输出数据的长度 */ string Decode(const char* Data,int DataByte,int& OutByte); };
ZBase64.cpp
#include "ZBase64.h" string ZBase64::Encode(const unsigned char* Data,int DataByte) { //编码表 const char EncodeTable[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; //返回值 string strEncode; unsigned char Tmp[4]={0}; int LineLength=0; for(int i=0;i<(int)(DataByte / 3);i++) { Tmp[1] = *Data++; Tmp[2] = *Data++; Tmp[3] = *Data++; strEncode+= EncodeTable[Tmp[1] >> 2]; strEncode+= EncodeTable[((Tmp[1] << 4) | (Tmp[2] >> 4)) & 0x3F]; strEncode+= EncodeTable[((Tmp[2] << 2) | (Tmp[3] >> 6)) & 0x3F]; strEncode+= EncodeTable[Tmp[3] & 0x3F]; if(LineLength+=4,LineLength==76) {strEncode+="\r\n";LineLength=0;} } //对剩余数据进行编码 int Mod=DataByte % 3; if(Mod==1) { Tmp[1] = *Data++; strEncode+= EncodeTable[(Tmp[1] & 0xFC) >> 2]; strEncode+= EncodeTable[((Tmp[1] & 0x03) << 4)]; strEncode+= "=="; } else if(Mod==2) { Tmp[1] = *Data++; Tmp[2] = *Data++; strEncode+= EncodeTable[(Tmp[1] & 0xFC) >> 2]; strEncode+= EncodeTable[((Tmp[1] & 0x03) << 4) | ((Tmp[2] & 0xF0) >> 4)]; strEncode+= EncodeTable[((Tmp[2] & 0x0F) << 2)]; strEncode+= "="; } return strEncode; } string ZBase64::Decode(const char* Data,int DataByte,int& OutByte) { //解码表 const char DecodeTable[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, // '+' 0, 0, 0, 63, // '/' 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9' 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z' 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z' }; //返回值 string strDecode; int nValue; int i= 0; while (i < DataByte) { if (*Data != '\r' && *Data!='\n') { nValue = DecodeTable[*Data++] << 18; nValue += DecodeTable[*Data++] << 12; strDecode+=(nValue & 0x00FF0000) >> 16; OutByte++; if (*Data != '=') { nValue += DecodeTable[*Data++] << 6; strDecode+=(nValue & 0x0000FF00) >> 8; OutByte++; if (*Data != '=') { nValue += DecodeTable[*Data++]; strDecode+=nValue & 0x000000FF; OutByte++; } } i += 4; } else// 回车换行,跳过 { Data++; i++; } } return strDecode; }
4.使用示例(结合opencv)
main.cpp
#include<opencv2/opencv.hpp> #include<iostream> #include"ZBase64.h" #include<vector> using namespace std; using namespace cv; void main() { Mat img = imread("1.bmp"); vector<uchar> vecImg; //Mat 图片数据转换为vector<uchar> vector<int> vecCompression_params; vecCompression_params.push_back(CV_IMWRITE_JPEG_QUALITY); vecCompression_params.push_back(90); imencode(".jpg", img, vecImg, vecCompression_params); ZBase64 base64; string imgbase64 = base64.Encode(vecImg.data(), vecImg.size()); //实现图片的base64编码 cout << imgbase64 << endl; }
5.效果图
6.方法补充
除了上文的方法,小编还为大家整理了其他C++实现图片转base64的方法,希望对大家有所帮助
方法一
//++Base64.h #pragma once class CBase64 { public: public: CBase64(); ~CBase64(); /*编码 DataByte [in]输入的数据长度,以字节为单位 */ std::string Encode(const char* Data, int DataByte); /*解码 DataByte [in]输入的数据长度,以字节为单位 OutByte [out]输出的数据长度,以字节为单位,请不要通过返回值计算 输出数据的长度 */ std::string Decode(const char* Data, int DataByte, int& OutByte); }; //++Base64.cpp #include"stdafx.h" #include"Base64.h" CBase64::CBase64() { } CBase64::~CBase64() { } std::string CBase64::Encode(const char* Data, int DataByte) { //编码表 const char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; //返回值 string strEncode; unsigned char Tmp[4] = { 0 }; int LineLength = 0; for (int i = 0; i<(int)(DataByte / 3); i++) { Tmp[1] = *Data++; Tmp[2] = *Data++; Tmp[3] = *Data++; strEncode += EncodeTable[Tmp[1] >> 2]; strEncode += EncodeTable[((Tmp[1] << 4) | (Tmp[2] >> 4)) & 0x3F]; strEncode += EncodeTable[((Tmp[2] << 2) | (Tmp[3] >> 6)) & 0x3F]; strEncode += EncodeTable[Tmp[3] & 0x3F]; if (LineLength += 4, LineLength == 76) { strEncode += "\r\n"; LineLength = 0; } } //对剩余数据进行编码 int Mod = DataByte % 3; if (Mod == 1) { Tmp[1] = *Data++; strEncode += EncodeTable[(Tmp[1] & 0xFC) >> 2]; strEncode += EncodeTable[((Tmp[1] & 0x03) << 4)]; strEncode += "=="; } else if (Mod == 2) { Tmp[1] = *Data++; Tmp[2] = *Data++; strEncode += EncodeTable[(Tmp[1] & 0xFC) >> 2]; strEncode += EncodeTable[((Tmp[1] & 0x03) << 4) | ((Tmp[2] & 0xF0) >> 4)]; strEncode += EncodeTable[((Tmp[2] & 0x0F) << 2)]; strEncode += "="; } return strEncode; } std::string CBase64::Decode(const char* Data, int DataByte, int& OutByte) { //解码表 const char DecodeTable[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, // '+' 0, 0, 0, 63, // '/' 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9' 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z' 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z' }; //返回值 string strDecode; int nValue; int i = 0; while (i < DataByte) { if (*Data != '\r' && *Data != '\n') { nValue = DecodeTable[*Data++] << 18; nValue += DecodeTable[*Data++] << 12; strDecode += (nValue & 0x00FF0000) >> 16; OutByte++; if (*Data != '=') { nValue += DecodeTable[*Data++] << 6; strDecode += (nValue & 0x0000FF00) >> 8; OutByte++; if (*Data != '=') { nValue += DecodeTable[*Data++]; strDecode += nValue & 0x000000FF; OutByte++; } } i += 4; } else// 回车换行,跳过 { Data++; i++; } } return strDecode; } 以下是读写图片的调用代码: bool CBusinessDataMgr::ReadPhotoFile(std::basic_string<TCHAR> strFileName,std::string &strData) { HANDLE hFile; hFile = CreateFile(strFileName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { return false; } DWORD dFileSize = GetFileSize(hFile, NULL); char * pBuffer = new char[dFileSize + 1]; if(pBuffer == NULL) return false; memset(pBuffer, 0, dFileSize); DWORD dReadSize(0); if (!ReadFile(hFile, pBuffer, dFileSize, &dReadSize, NULL)) { delete[]pBuffer; CloseHandle(hFile); return false; } CBase64 base64; strData = ""; strData = base64.Encode((const char*)pBuffer, dReadSize); delete[]pBuffer; CloseHandle(hFile); return true; } bool CBusinessDataMgr::WritePhotoFile(std::basic_string<TCHAR> strFileName, std::string &strData) { HANDLE hFile; hFile = CreateFile(strFileName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { return false; } CBase64 base64; int datalen(0); DWORD dwritelen(0); std::string strdcode = base64.Decode(strData.data(),strData.size(), datalen); if (!WriteFile(hFile, strdcode.data(), datalen, &dwritelen, NULL)) { CloseHandle(hFile); return false; } CloseHandle(hFile); return true; }
方法二
#include <string> #include <iostream> static std::string base64Decode(const char* Data, int DataByte) { //解码表 const char DecodeTable[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, // '+' 0, 0, 0, 63, // '/' 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9' 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z' 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z' }; std::string strDecode; int nValue; int i = 0; while (i < DataByte) { if (*Data != '\r' && *Data != '\n') { nValue = DecodeTable[*Data++] << 18; nValue += DecodeTable[*Data++] << 12; strDecode += (nValue & 0x00FF0000) >> 16; if (*Data != '=') { nValue += DecodeTable[*Data++] << 6; strDecode += (nValue & 0x0000FF00) >> 8; if (*Data != '=') { nValue += DecodeTable[*Data++]; strDecode += nValue & 0x000000FF; } } i += 4; } else { Data++; i++; } } return strDecode; } static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; std::string base64_encode(const 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(){ std::fstream f; f.open("2.jpeg", std::ios::in | std::ios::binary); f.seekg(0, std::ios_base::end); //设置偏移量至文件结尾 std::streampos sp = f.tellg(); //获取文件大小 int size = sp; char* buffer = (char*)malloc(sizeof(char) * size); f.seekg(0, std::ios_base::beg); //设置偏移量至文件开头 f.read(buffer, size); //将文件内容读入buffer std::string imgBase64 = base64_encode(buffer, size); std::string s_mat = base64Decode(imgBase64.c_str(), imgBase64.size()); FILE* stream; if ((stream = fopen("1.JPG", "wb")) != NULL) { int numwritten = fwrite(s_mat.data(), sizeof(char), s_mat.size(), stream); fclose(stream); } //编码 }
到此这篇关于C++实现图片转base64的示例代码的文章就介绍到这了,更多相关C++图片转base64内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
最新评论