C++读写图片数据转成Base64格式的一种方法
最近在一个项目中要实现在客户端和服务端之间传送图片文件的功能,采用了C++语言读写图片转化成Base64格式进行传输。具体代码如下:
1 //++Base64.h 2 3 #pragma once 4 5 class CBase64 6 { 7 public: 8 public: 9 CBase64(); 10 ~CBase64(); 11 12 /*编码 13 DataByte 14 [in]输入的数据长度,以字节为单位 15 */ 16 std::string Encode(const char* Data, int DataByte); 17 18 /*解码 19 DataByte 20 [in]输入的数据长度,以字节为单位 21 OutByte 22 [out]输出的数据长度,以字节为单位,请不要通过返回值计算 23 输出数据的长度 24 */ 25 std::string Decode(const char* Data, int DataByte, int& OutByte); 26 27 }; 28 29 //++Base64.cpp 30 #include"stdafx.h" 31 #include"Base64.h" 32 33 CBase64::CBase64() 34 { 35 36 } 37 38 CBase64::~CBase64() 39 { 40 41 } 42 43 std::string CBase64::Encode(const char* Data, int DataByte) 44 { 45 //编码表 46 const char EncodeTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 47 //返回值 48 string strEncode; 49 unsigned char Tmp[4] = { 0 }; 50 int LineLength = 0; 51 for (int i = 0; i<(int)(DataByte / 3); i++) 52 { 53 Tmp[1] = *Data++; 54 Tmp[2] = *Data++; 55 Tmp[3] = *Data++; 56 strEncode += EncodeTable[Tmp[1] >> 2]; 57 strEncode += EncodeTable[((Tmp[1] << 4) | (Tmp[2] >> 4)) & 0x3F]; 58 strEncode += EncodeTable[((Tmp[2] << 2) | (Tmp[3] >> 6)) & 0x3F]; 59 strEncode += EncodeTable[Tmp[3] & 0x3F]; 60 if (LineLength += 4, LineLength == 76) { strEncode += "\r\n"; LineLength = 0; } 61 } 62 //对剩余数据进行编码 63 int Mod = DataByte % 3; 64 if (Mod == 1) 65 { 66 Tmp[1] = *Data++; 67 strEncode += EncodeTable[(Tmp[1] & 0xFC) >> 2]; 68 strEncode += EncodeTable[((Tmp[1] & 0x03) << 4)]; 69 strEncode += "=="; 70 } 71 else if (Mod == 2) 72 { 73 Tmp[1] = *Data++; 74 Tmp[2] = *Data++; 75 strEncode += EncodeTable[(Tmp[1] & 0xFC) >> 2]; 76 strEncode += EncodeTable[((Tmp[1] & 0x03) << 4) | ((Tmp[2] & 0xF0) >> 4)]; 77 strEncode += EncodeTable[((Tmp[2] & 0x0F) << 2)]; 78 strEncode += "="; 79 } 80 81 return strEncode; 82 } 83 84 std::string CBase64::Decode(const char* Data, int DataByte, int& OutByte) 85 { 86 //解码表 87 const char DecodeTable[] = 88 { 89 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91 62, // '+' 92 0, 0, 0, 93 63, // '/' 94 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9' 95 0, 0, 0, 0, 0, 0, 0, 96 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 97 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z' 98 0, 0, 0, 0, 0, 0, 99 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 100 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z' 101 }; 102 //返回值 103 string strDecode; 104 int nValue; 105 int i = 0; 106 while (i < DataByte) 107 { 108 if (*Data != '\r' && *Data != '\n') 109 { 110 nValue = DecodeTable[*Data++] << 18; 111 nValue += DecodeTable[*Data++] << 12; 112 strDecode += (nValue & 0x00FF0000) >> 16; 113 OutByte++; 114 if (*Data != '=') 115 { 116 nValue += DecodeTable[*Data++] << 6; 117 strDecode += (nValue & 0x0000FF00) >> 8; 118 OutByte++; 119 if (*Data != '=') 120 { 121 nValue += DecodeTable[*Data++]; 122 strDecode += nValue & 0x000000FF; 123 OutByte++; 124 } 125 } 126 i += 4; 127 } 128 else// 回车换行,跳过 129 { 130 Data++; 131 i++; 132 } 133 } 134 return strDecode; 135 } 136 137 以下是读写图片的调用代码: 138 bool CBusinessDataMgr::ReadPhotoFile(std::basic_string<TCHAR> strFileName,std::string &strData) 139 { 140 HANDLE hFile; 141 hFile = CreateFile(strFileName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 142 143 if (hFile == INVALID_HANDLE_VALUE) 144 { 145 return false; 146 } 147 148 DWORD dFileSize = GetFileSize(hFile, NULL); 149 char * pBuffer = new char[dFileSize + 1]; 150 151 if(pBuffer == NULL) 152 return false; 153 154 memset(pBuffer, 0, dFileSize); 155 156 DWORD dReadSize(0); 157 if (!ReadFile(hFile, pBuffer, dFileSize, &dReadSize, NULL)) 158 { 159 delete[]pBuffer; 160 CloseHandle(hFile); 161 return false; 162 } 163 164 CBase64 base64; 165 strData = ""; 166 strData = base64.Encode((const char*)pBuffer, dReadSize); 167 168 delete[]pBuffer; 169 CloseHandle(hFile); 170 return true; 171 } 172 173 bool CBusinessDataMgr::WritePhotoFile(std::basic_string<TCHAR> strFileName, std::string &strData) 174 { 175 HANDLE hFile; 176 hFile = CreateFile(strFileName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 177 178 if (hFile == INVALID_HANDLE_VALUE) 179 { 180 return false; 181 } 182 183 CBase64 base64; 184 int datalen(0); 185 DWORD dwritelen(0); 186 std::string strdcode = base64.Decode(strData.data(),strData.size(), datalen); 187 if (!WriteFile(hFile, strdcode.data(), datalen, &dwritelen, NULL)) 188 { 189 CloseHandle(hFile); 190 return false; 191 } 192 CloseHandle(hFile); 193 return true; 194 }