- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试用 C++ 编写一个程序,它可以将图像编码为 base64,也可以将 base64 解码为图像。我相信编码器功能工作正常,一些网站可以采用我生成的 base64 代码并将其解码成图像,但出于某种原因,一旦我将 base64 解码为字符串,然后将其写入文件并将其另存为png 它说它不能在图像查看器中打开。
我确认正在写入新文件的字符串与现有文件完全相同(在文本编辑器中打开时),但由于某种原因,新文件无法打开,但现有文件可。我什至尝试过在文本编辑器中创建一个新文件,然后将旧文件中的文本复制到其中,但它仍然无法在图像查看器中打开。
我相信编码函数和 base64 解码函数都可以正常工作。我认为问题出在图像解码功能上。
图像编码函数
string base64_encode_image(const string& path) {
vector<char> temp;
std::ifstream infile;
infile.open(path, ios::binary); // Open file in binary mode
if (infile.is_open()) {
while (!infile.eof()) {
char c = (char)infile.get();
temp.push_back(c);
}
infile.close();
}
else return "File could not be opened";
string ret(temp.begin(), temp.end() - 1);
ret = base64_encode((unsigned const char*)ret.c_str(), ret.size());
return ret;
}
图像解码函数
void base64_decode_image(const string& input) {
ofstream outfile;
outfile.open("test.png", ofstream::out);
string temp = base64_decode(input);
outfile.write(temp.c_str(), temp.size());
outfile.close();
cout << "file saved" << endl;
}
编码函数base64
string base64_encode(unsigned const char* input, unsigned const int len) {
string ret;
size_t i = 0;
unsigned char bytes[3];
unsigned char sextets[4];
while (i <= (len - 3)) {
bytes[0] = *(input++);
bytes[1] = *(input++);
bytes[2] = *(input++);
sextets[0] = (bytes[0] & 0xfc) >> 2; // Cuts last two bits off of first byte
sextets[1] = ((bytes[0] & 0x03) << 4) + ((bytes[1] & 0xf0) >> 4); // Takes last two bits from first byte and adds it to first 4 bits of 2nd byte
sextets[2] = ((bytes[1] & 0x0f) << 2) + ((bytes[2] & 0xc0) >> 6); // Takes last 4 bits of 2nd byte and adds it to first 2 bits of third byte
sextets[3] = bytes[2] & 0x3f; // takes last 6 bits of third byte
for (size_t j = 0; j < 4; ++j) {
ret += base64_chars[sextets[j]];
}
i += 3; // increases to go to third byte
}
if (i != len) {
size_t k = 0;
size_t j = len - i; // Find index of last byte
while (k < j) { // Sets first bytes
bytes[k] = *(input++);
++k;
}
while (j < 3) { // Set last bytes to 0x00
bytes[j] = '\0';
++j;
}
sextets[0] = (bytes[0] & 0xfc) >> 2; // Cuts last two bits off of first byte
sextets[1] = ((bytes[0] & 0x03) << 4) + ((bytes[1] & 0xf0) >> 4); // Takes last two bits from first byte and adds it to first 4 bits of 2nd byte
sextets[2] = ((bytes[1] & 0x0f) << 2) + ((bytes[2] & 0xc0) >> 6); // Takes last 4 bits of 2nd byte and adds it to first 2 bits of third byte
// No last one is needed, because if there were 4, then (i == len) == true
for (j = 0; j < (len - i) + 1; ++j) { // Gets sextets that include data
ret += base64_chars[sextets[j]]; // Appends them to string
}
while ((j++) < 4) // Appends remaining ='s
ret += '=';
}
return ret;
}
解码函数base64
string base64_decode(const string& input) {
string ret;
size_t i = 0;
unsigned char bytes[3];
unsigned char sextets[4];
while (i < input.size() && input[i] != '=') {
size_t j = i % 4; // index per sextet
if (is_base64(input[i])) sextets[j] = input[i++]; // set sextets with characters from string
else { cerr << "Non base64 string included in input (possibly newline)" << endl; return ""; }
if (i % 4 == 0) {
for (j = 0; j < 4; ++j) // Using j as a seperate index (not the same as it was originally used as, will later be reset)
sextets[j] = indexof(base64_chars, strlen(base64_chars), sextets[j]); // Change value to indicies of b64 characters and not ascii characters
bytes[0] = (sextets[0] << 2) + ((sextets[1] & 0x30) >> 4); // Similar bitshifting to before
bytes[1] = ((sextets[1] & 0x0f) << 4) + ((sextets[2] & 0x3c) >> 2);
bytes[2] = ((sextets[2] & 0x03) << 6) + sextets[3];
for (j = 0; j < 3; ++j) // Using j seperately again to iterate through bytes and adding them to full string
ret += bytes[j];
}
}
if (i % 4 != 0) {
for (size_t j = 0; j < (i % 4); ++j)
sextets[j] = indexof(base64_chars, strlen(base64_chars), sextets[j]);
bytes[0] = (sextets[0] << 2) + ((sextets[1] & 0x30) >> 4); // Similar bitshifting to before
bytes[1] = ((sextets[1] & 0x0f) << 4) + ((sextets[2] & 0x3c) >> 2);
for (size_t j = 0; j < (i % 4) - 1; ++j)
ret += bytes[j]; // Add final bytes
}
return ret;
}
当我尝试打开由图像解码功能生成的文件时,它说文件格式不受支持,或者文件已损坏。我要解码的编码函数生成的 base64 在此链接中 https://pastebin.com/S5D90Fs8
最佳答案
当您在 base64_decode_image
中打开 outfile
时,您不会像在 base64_encode_image< 中那样指定
读取图像时。如果没有该标志,您将以文本模式编写,这可能会改变您正在编写的数据(在调整换行符时)。ofstream::binary
标志
关于c++ - 从 base64 C++ 解码和保存图像文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57050461/
如果我不定义自己的构造函数,Base *b = new Base; 与 Base *b = new Base(); 之间有什么区别吗? 最佳答案 初始化是标准中要遵循的一种 PITA...然而,这两个
是否有现成的函数可以在 C# 中进行基本转换?我希望将以 26 为基数和以 27 为基数的数字转换为以 10 为基数。我可以在纸上完成,但我不是一个非常有经验的程序员,如果可能的话,我宁愿不要从头开始
JNA 中'base'是什么意思 Pointer.getPointerArray(long base) Pointer.getStringArray(long base) ? JNA Document
我正在做一个将数字从 10 进制转换为 2 进制的基本程序。我得到了这段代码: #include #include #include #include using namespace std;
“假设以下代码: public class MultiplasHerancas { static GrandFather grandFather = new GrandFather();
当我分析算法的时候,我突然问自己这个问题,如果我们有三元计算机时间复杂度会更便宜吗?还是有任何基础可以让我们构建计算机,这样时间复杂度分析就无关紧要了?我在互联网上找不到太多,但是基于三元的计算机在给
一个简化的场景。三个类,GrandParent,Parent 和 Child。我想要做的是利用 GrandParent 和 Parent 构造函数来初始化一个 Child 实例。 class Gran
我编写了一个简单的函数来将基数为 10 的数字转换为二进制数。我编写的函数是我使用我所知道的简单工具的最佳尝试。我已经在这个网站上查找了如何执行此操作的其他方法,但我还不太了解它。我确定我编写的函数非
我尝试了以下代码将数字从 base-10 转换为另一个 base。如果目标基地中没有零(0),它就会工作。检查 79 和 3 并正确打印正确的 2221。现在尝试数字 19 和 3,结果将是 21 而
这个问题在这里已经有了答案: Is Big O(logn) log base e? (7 个答案) 关闭 8 年前。 Intro 练习 4.4.6 的大多数解决方案。算法第三版说,n*log3(n)
如何判断基类(B)的指针是否(多态)重写了基类的某个虚函数? class B{ public: int aField=0; virtual void f(){}; }; class C
我测试了这样的代码: class A { public A() { } public virtual void Test () { Console.WriteL
两者都采用相同的概念:定义一些行和列并将内容添加到特定位置。但是 Grid 是最常见的 WPF 布局容器,而 html 中基于表格的布局是 very controversial .那么,为什么 WPF
我试图在 JS 中“获得”继承。我刚刚发现了一种基本上可以将所有属性从一个对象复制到另一个对象的简洁方法: function Person(name){ this.name="Mr or Miss
class A { public override int GetHashCode() { return 1; } } class B : A { pu
我有一个 Base32 信息哈希。例如IXE2K3JMCPUZWTW3YQZZOIB5XD6KZIEQ ,我需要将其转换为base16。 我怎样才能用 PHP 做到这一点? 我的代码如下所示: $ha
我已经使用其实验界面对 Google Analytics 进行了一些实验,一切似乎都运行良好,但我无法找到 Google Analytics 属性如何达到变体目标的答案,即归因 session - 基
if (state is NoteInitial || state is NewNote) return ListView.builder(
MSVC、Clang 和 GCC 不同意此代码: struct Base { int x; }; struct Der1 : public Base {}; struct Der2 : public
我已经尝试构建一个 Base 10 到 Base 2 转换器... var baseTen = window.prompt("Put a number from Base 10 to conver
我是一名优秀的程序员,十分优秀!