jpeg二進制數據轉base64後在前端顯示

需求:前端從後端獲取圖片。

背景:後端數據均保存在硬盤裏,從硬盤取出後的Jpeg圖片,二進制數據傳輸給前端顯示圖片

直接二進制傳輸,中間層需要兼容,想着直接轉base64字符串,js剛好可以直接顯示圖片

 

Bse64是一種以64個可打印字符對二進制數據進行編碼的編碼算法。base64在對數據進行編碼時以三個8位字符型數據爲一組,取這三個字符型數據的ASCII碼,然後以6位爲一組組成4個新的數據,這4個新的數據有6位,所以它的最大值爲2^6=64。我們以4個6位數據的十進制數從base64表中得到最終編碼後的字符。

Base64 編碼表

 

Value Char  Value Char  Value Char  Value Char 
0 A 16 Q 32 g 48 w
1 B 17 R 33 h 49 x
2 C 18 S 34 i 50 y
3 D 19 T 35 j 51 z
4 E 20 U 36 k 52 0
5 F 21 V 37 l 53 1
6 G 22 W 38 m 54 2
7 H 23 X 39 n 55 3
8 I 24 Y 40 o 56 4
9 J 25 Z 41 p 57 5
10 K 26 a 42 q 58 6
11 L 27 b 43 r 59 7
12 M 28 c 44 s 60 8
13 N 29 d 45 t 61 9
14 O 30 e 46 u 62 +
15 P 31 f 47 v 63 /

 

       由於base64編碼是將編碼前的3*8位數據,分解成4個6位的數據,所以經過base64編碼後的字符串長度是4的倍數。但往往我們進行編碼的數據長度並不是3的倍數,這就造成了“編碼”後的位數不爲4的倍數,比如Brisk共5×8=40位,以6位爲一組可以分爲7組,這樣“編碼”後就有7個字符,但base64編碼後的字符長度應該是4的倍數,顯然這裏就出問題了,那麼怎麼辦呢?前面的不可以拋棄掉,所以就只有“追加”了,所以Brisk經過base64編碼後的長度應該是8個字符,而第8個編碼後的字符是'=',再比如對單個字符a進行base64編碼,由於它的長度不是3的倍數,以3個字節爲一組它只能分一組,再以6位爲一位它只能分兩組,所以經過“編碼”後它的長度是2,但base64編碼後的個數應該是4的倍數,所以它的長度應該是4,所以在後面補上兩個‘=’,由於一個數求餘3後有三個不同的結果,0、1、2,所以在對一個數據進行base64進行編碼後它的長度爲:

 

(1)當進行編碼的數據長度是3的倍數時,len=strlen(str_in)/3*4;
(2)當進行編碼的數據長度不是3的倍數時,len=(strlen(str_in)/3+1)*4;

       我們以Brisk這個例子來說明一下base64編碼的過程。首先我們以3個字符爲一組將Brisk進行分組,Brisk被氛圍兩組:Bri 和 sk;然後我們取出這兩個分組中每個字節的ASCII碼,B:66 r:114 i:105 s:115 k:107。它們對應的二進制數爲  B:01000010 r:01110010 i:01101001 s:01110011 k:01101011;

       第一組,我們以6位爲一組對每一個3字節分組進行再分組就變成了010000 100111 001001 101001。所對應的十進制數是16 39 9 41,對應base64表中的結果是 Q n J p;

       第二組,011100 110110 101100(不夠補0),所以對應的十進制數是 28 54 44,對應base64表中的結果是 c 2 s,最終結果爲QnJpc2s=(因爲第二組“編碼”後只有三個字節)。

      解碼的過程是一個逆過程,我們將經過編碼後的字符按4個字符爲一組,然後對照base64表得到相應的十進制數,再將其通過拆分和組合,組成3個8位數據,這個數據就是解碼後的數據,下面給一個c語言實現編碼和解碼的代碼。

 

//need ms_free
char *base64_encode(char *str, int str_len)  
{  
    long len;  
    char *res = NULL;  
    int i = 0,j = 0;  
	//定義base64編碼表  
    char *base64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";  
  
	//計算經過base64編碼後的字符串長度  
    if(str_len % 3 == 0)  
        len = str_len/3*4;  
    else  
        len = (str_len/3+1)*4;  
  
    res = ms_malloc(len+1);  
    res[len] = '\0';
  
	//以3個8位字符爲一組進行編碼  
    for(i = 0,j = 0; i < len-2; j += 3,i += 4)  
    {  
        res[i]   = base64_table[str[j]>>2]; 						//取出第一個字符的前6位並找出對應的結果字符  
        res[i+1] = base64_table[(str[j]&0x3)<<4 | (str[j+1]>>4)]; 	//將第一個字符的後位與第二個字符的前4位進行組合並找到對應的結果字符  
        res[i+2] = base64_table[(str[j+1]&0xf)<<2 | (str[j+2]>>6)];	//將第二個字符的後4位與第三個字符的前2位組合並找出對應的結果字符  
        res[i+3] = base64_table[str[j+2]&0x3f];						//取出第三個字符的後6位並找出結果字符  
    }  
  
    switch(str_len % 3)  
    {  
        case 1:  
            res[i-2] = '=';  
            res[i-1] = '=';  
            break;  
        case 2:  
            res[i-1] = '=';  
            break;  
    }  
  
    return res;  
}


unsigned char *base64_decode(char *code)  
{  
//根據base64表,以字符找到對應的十進制數據  
    int table[]={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,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,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
    	       };  
    long len;  
    long str_len;  
    unsigned char *res;  
    int i,j;  
  
//計算解碼後的字符串長度  
    len = strlen(code);  
//判斷編碼後的字符串後是否有=  
    if (strstr(code,"=="))  
        str_len = len/4*3-2;  
    else if (strstr(code,"="))  
        str_len = len/4*3-1;  
    else  
        str_len = len/4*3;  
  
    res = ms_malloc(str_len+1);  
    res[str_len] = '\0';  
  
	//以4個字符爲一位進行解碼  
    for (i = 0,j = 0; i < len-2; j += 3,i += 4)  
    {  
        res[j]   = ((unsigned char)table[code[i]])<<2 | (((unsigned char)table[code[i+1]])>>4); 	//取出第一個字符對應base64表的十進制數的前6位與第二個字符對應base64表的十進制數的後2位進行組合  
        res[j+1] = (((unsigned char)table[code[i+1]])<<4) | (((unsigned char)table[code[i+2]])>>2); //取出第二個字符對應base64表的十進制數的後4位與第三個字符對應bas464表的十進制數的後4位進行組合  
        res[j+2] = (((unsigned char)table[code[i+2]])<<6) | ((unsigned char)table[code[i+3]]); 		//取出第三個字符對應base64表的十進制數的後2位與第4個字符進行組合  
    }  
  
    return res;  
}
<div class="subContent">
    <div id="bigImage">
    </div>
</div>

function showImage(oImage)
{
	var HTML = "";
	HTML += "<img src='data:image/jpeg;base64,"+oImage+"' width='455px' height='260px'";
	HTML += "/>"
	$("#bigImage").html(HTML);
}

function getBigImageBySdk()
{
	var str = "action=get.anpr.big_image";
	g_sUserPass = CheckUserPass(); 
	$.ajax({
		url:"/sdk.cgi",    
		type:"get",
		data:str,
		dataType:"text",
		async:false,
		timeout:1000,
        beforeSend: function (xhr) {
            xhr.setRequestHeader ("Authorization", "Basic "+g_sUserPass);
        },
        statusCode: {401: function() {
       		top.location.href = "/html/home.html";
    		}
        },
		success:function(sString){
			showImage(sString);
			//$("#images").attr("src","data:image/gif;base64,"+sString);
		}
	});
}

在線工具:

1、圖片base 64編碼:https://tool.lu/base64image

2、base64圖片轉換工具:http://tool.chinaz.com/tools/imgtobase/

1可以在線把圖片轉換成base 64

2可以把base64數據轉換成圖片

吐槽一下,2的圖片轉base64功能有異常,轉換後生成不了圖片,因此用1的工具轉換base64,用2去生成圖片

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章