C++讀寫圖片數據轉成Base64格式


轉載:http://www.cnblogs.com/jeray/p/8746976.html

轉載:https://www.cnblogs.com/lujin49/p/4957742.html

轉載:https://blog.csdn.net/whish1994/article/details/79894451

轉載:https://blog.csdn.net/gu_wen_jie/article/details/79050287

最近在一個項目中要實現前端傳遞給我們客戶端的是base64的圖片數據流,我們需要做的就是將它轉為圖片並且保存起來,根據需要再將圖片存儲路徑信息做進一步操作。

前端傳過來的字符串是這樣的:

<img src="data:image/jpg;base64,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
" />
那么這是什么呢?這是Data URI scheme。
Data URI scheme是在RFC2397中定義的,目的是將一些小的數據,直接嵌入到網頁中,從而不用再從外部文件載入。比如上面那串字符,其實是一張小圖片,將這些字符復制黏貼到火狐的地址欄中並轉到,就能看到它了,一張1X36的白灰png圖片。
在上面的Data URI中,data表示取得數據的協定名稱,image/png 是數據類型名稱,base64 是數據的編碼方法,逗號后面就是這個image/png文件base64編碼后的數據。
 
目前,Data URI scheme支持的類型有:
data:,文本數據
data:text/plain,文本數據
data:text/html,HTML代碼
data:text/html;base64,base64編碼的HTML代碼
data:text/css,CSS代碼
data:text/css;base64,base64編碼的CSS代碼
data:text/javascript,Javascript代碼
data:text/javascript;base64,base64編碼的Javascript代碼
data:image/gif;base64,base64編碼的gif圖片數據
data:image/png;base64,base64編碼的png圖片數據
data:image/jpeg;base64,base64編碼的jpeg圖片數據
data:image/x-icon;base64,base64編碼的icon圖片數據
 
base64簡單地說,它把一些 8-bit 數據翻譯成標准 ASCII 字符,網上有很多免費的base64 編碼和解碼的工具,在PHP中可以用函數base64_encode() 進行編碼,如 echo base64_encode(file_get_contents(‘wg.png’));
目前,IE8、Firfox、Chrome、Opera瀏覽器都支持這種小文件嵌入。
 舉個圖片的例子:
網頁中一張圖片可以這樣顯示:
<img src="http://mail.163.com/images/x.png" />

也可以這樣顯示:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJAQMAAADaX5RTAAAAA3NCSVQICAjb4U/gAAAABlBMVEX///+ZmZmOUEqyAAAAAnRSTlMA/1uRIrUAAAAJcEhZcwAACusAAArrAYKLDVoAAAAWdEVYdENyZWF0aW9uIFRpbWUAMDkvMjAvMTIGkKG+AAAAHHR
FWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAAB1JREFUCJljONjA8LiBoZyBwY6BQQZMAtlAkYMNAF1fBs/zPvcnAAAAAElFTkSuQmCC"
/>

把圖像文件的內容直接寫在了HTML 文件中,這樣做的好處是,節省了一個HTTP 請求。壞處是瀏覽器不會緩存這種圖像。

 

Base64.h

#ifndef _BASE64_H_
#define _BASE64_H_

#include <string>
using namespace std;

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);

};
#endif//_BASE64_H_

Base64.cpp

#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;
}

main.cpp

#include "Base64.h"
#include <tchar.h>
#include <windows.h>
#include <iostream>
using namespace std;

//以下是讀寫圖片的調用代碼:
bool 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 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;
}int main()
{
    wstring path = L"C:\\Users\\Administrator\\Desktop\\test.jpg";
    string data;
    ReadPhotoFile(path, data);

    wstring strfilename = L"C:\\Users\\Administrator\\Desktop\\123.jpg";

    WritePhotoFile(strfilename, data);



    for (int i = 0; i < 10;i++)
    {
        for (int j = 0; j < 5;j++)
        {
            if (j == 3)
            {

                break;
            }
            cout << "j=" << j << endl;
        }

        cout << "i=" << i << endl;
    }

    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM