测试流程就是:图片->压缩图片->base64->解压图片->图片
(注意压缩会失真的,可以不压缩,但是base64会比较大)
main.cpp
#include "stdafx.h" #include#include "base64.h" #include #include #include #include #include using namespace std; using namespace cv; #define MAX_SIZE_BASE64 100000 int main() { long t1 = GetTickCount(); string source_data, source_data_encode; Mat srcImage, grayImage,dstImage; //读取图片1 srcImage = imread("image.jpg"); dstImage = srcImage.clone(); imshow("【原图】", srcImage); //MAT转base64 int quality = 50; //压缩比率0~100 vector compress_params; compress_params.push_back(IMWRITE_JPEG_QUALITY); compress_params.push_back(quality); std::vector buf(MAX_SIZE_BASE64, 0); //vector要分配内存,否则imencode会崩 cv::imencode(".jpg", dstImage, buf, compress_params); source_data.insert(source_data.begin(), buf.begin(), buf.end()); Base64::Encode(source_data, &source_data_encode); printf("len: %d n", source_data_encode.length()); //base64写入文件 FILE * fp = NULL; fp = fopen( "data.txt", "a+" ); if ( fp == NULL ) return -1; int res=fprintf( fp, "%sn" ,source_data_encode.c_str()); fclose(fp); //base64转MAT Base64::Decode(source_data_encode, &source_data); std::vector buf2(source_data.begin(), source_data.end()); dstImage = cv::imdecode(cv::Mat(buf2), CV_LOAD_IMAGE_COLOR); long t2 = GetTickCount(); printf("time: %d n", t2-t1); //原图1 imshow("【转Base64再转MAT】", dstImage); waitKey(0); vector ().swap(buf); //释放vector内存 vector ().swap(buf2); //释放vector内存 return 0; }
base64.h
#pragma once #ifndef BASE64_H #define BASE64_H #include#include const char kBase64Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; class Base64 { public: static bool Encode(const std::string &in, std::string *out) { int i = 0, j = 0; size_t enc_len = 0; unsigned char a3[3]; unsigned char a4[4]; out->resize(EncodedLength(in)); int input_len = in.size(); std::string::const_iterator input = in.begin(); while (input_len--) { a3[i++] = *(input++); if (i == 3) { a3_to_a4(a4, a3); for (i = 0; i < 4; i++) { (*out)[enc_len++] = kBase64Alphabet[a4[i]]; } i = 0; } } if (i) { for (j = i; j < 3; j++) { a3[j] = ' '; } a3_to_a4(a4, a3); for (j = 0; j < i + 1; j++) { (*out)[enc_len++] = kBase64Alphabet[a4[j]]; } while ((i++ < 3)) { (*out)[enc_len++] = '='; } } return (enc_len == out->size()); } static bool Encode(const char *input, size_t input_length, char *out, size_t out_length) { int i = 0, j = 0; char *out_begin = out; unsigned char a3[3]; unsigned char a4[4]; size_t encoded_length = EncodedLength(input_length); if (out_length < encoded_length) return false; while (input_length--) { a3[i++] = *input++; if (i == 3) { a3_to_a4(a4, a3); for (i = 0; i < 4; i++) { *out++ = kBase64Alphabet[a4[i]]; } i = 0; } } if (i) { for (j = i; j < 3; j++) { a3[j] = ' '; } a3_to_a4(a4, a3); for (j = 0; j < i + 1; j++) { *out++ = kBase64Alphabet[a4[j]]; } while ((i++ < 3)) { *out++ = '='; } } return (out == (out_begin + encoded_length)); } static bool Decode(const std::string &in, std::string *out) { int i = 0, j = 0; size_t dec_len = 0; unsigned char a3[3]; unsigned char a4[4]; int input_len = in.size(); std::string::const_iterator input = in.begin(); out->resize(DecodedLength(in)); while (input_len--) { if (*input == '=') { break; } a4[i++] = *(input++); if (i == 4) { for (i = 0; i < 4; i++) { a4[i] = b64_lookup(a4[i]); } a4_to_a3(a3, a4); for (i = 0; i < 3; i++) { (*out)[dec_len++] = a3[i]; } i = 0; } } if (i) { for (j = i; j < 4; j++) { a4[j] = ' '; } for (j = 0; j < 4; j++) { a4[j] = b64_lookup(a4[j]); } a4_to_a3(a3, a4); for (j = 0; j < i - 1; j++) { (*out)[dec_len++] = a3[j]; } } return (dec_len == out->size()); } static bool Decode(const char *input, size_t input_length, char *out, size_t out_length) { int i = 0, j = 0; char *out_begin = out; unsigned char a3[3]; unsigned char a4[4]; size_t decoded_length = DecodedLength(input, input_length); if (out_length < decoded_length) return false; while (input_length--) { if (*input == '=') { break; } a4[i++] = *(input++); if (i == 4) { for (i = 0; i < 4; i++) { a4[i] = b64_lookup(a4[i]); } a4_to_a3(a3, a4); for (i = 0; i < 3; i++) { *out++ = a3[i]; } i = 0; } } if (i) { for (j = i; j < 4; j++) { a4[j] = ' '; } for (j = 0; j < 4; j++) { a4[j] = b64_lookup(a4[j]); } a4_to_a3(a3, a4); for (j = 0; j < i - 1; j++) { *out++ = a3[j]; } } return (out == (out_begin + decoded_length)); } static int DecodedLength(const char *in, size_t in_length) { int numEq = 0; const char *in_end = in + in_length; while (*--in_end == '=') ++numEq; return ((6 * in_length) / 8) - numEq; } static int DecodedLength(const std::string &in) { int numEq = 0; int n = in.size(); for (std::string::const_reverse_iterator it = in.rbegin(); *it == '='; ++it) { ++numEq; } return ((6 * n) / 8) - numEq; } inline static int EncodedLength(size_t length) { return (length + 2 - ((length + 2) % 3)) / 3 * 4; } inline static int EncodedLength(const std::string &in) { return EncodedLength(in.length()); } inline static void StripPadding(std::string *in) { while (!in->empty() && *(in->rbegin()) == '=') in->resize(in->size() - 1); } 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 std::string base64Encode(const unsigned char* Data, int DataByte) { //编码表 const char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; //返回值 std::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 += "rn"; 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; } //imgType 包括png bmp jpg jpeg等opencv能够进行编码解码的文件 static std::string Mat2Base64(const cv::Mat &img, std::string imgType) { //Mat转base64 std::string img_data; std::vector vecImg; std::vector vecCompression_params; vecCompression_params.push_back(CV_IMWRITE_JPEG_QUALITY); vecCompression_params.push_back(90); imgType = "." + imgType; cv::imencode(imgType, img, vecImg, vecCompression_params); img_data = base64Encode(vecImg.data(), vecImg.size()); return img_data; } static cv::Mat Base2Mat(std::string &base64_data) { cv::Mat img; std::string s_mat; s_mat = base64Decode(base64_data.data(), base64_data.size()); std::vector base64_img(s_mat.begin(), s_mat.end()); img = cv::imdecode(base64_img, CV_LOAD_IMAGE_COLOR); return img; } private: static inline void a3_to_a4(unsigned char * a4, unsigned char * a3) { a4[0] = (a3[0] & 0xfc) >> 2; a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4); a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6); a4[3] = (a3[2] & 0x3f); } static inline void a4_to_a3(unsigned char * a3, unsigned char * a4) { a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4); a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2); a3[2] = ((a4[2] & 0x3) << 6) + a4[3]; } static inline unsigned char b64_lookup(unsigned char c) { if (c >= 'A' && c <= 'Z') return c - 'A'; if (c >= 'a' && c <= 'z') return c - 71; if (c >= '0' && c <= '9') return c + 4; if (c == '+') return 62; if (c == '/') return 63; return 255; } }; #endif // BASE64_H



