2014-09-27 45 views
20

我在Flask中製作了一個簡單的API,它接受以base64編碼的圖像,然後使用Pillow將其解碼以作進一步處理。從POST解碼base64以在PIL中使用

我看了一些例子(123),我覺得我得到的過程的要點,但我不斷收到一個錯誤的枕頭無法讀取我給它的字符串。

這裏是我到目前爲止有:

import cStringIO 
from PIL import Image 
import base64 

data = request.form 
image_string = cStringIO.StringIO(base64.b64decode(data['img'])) 
image = Image.open(image_string) 

這給錯誤:

IOError: cannot identify image file <cStringIO.StringIO object at 0x10f84c7a0> 
+0

你能在你的'數據[ 'IMG']'得到什麼的一個例子粘貼?記錄下來,或打印出來。 – OregonTrail 2014-09-27 03:57:53

+0

下面是一個例子:http://jsfiddle.net/gn0x0wvc/。我把它放在'img'標籤中,以確保圖像數據沒有被破壞。 – 2014-09-27 04:21:50

+0

'b64decode()'後面的數據是什麼樣的?是否有其他編碼正在進行,例如URL編碼?它是否真的是PIL支持的圖像? – mhawke 2014-09-27 05:09:02

回答

39

你應該嘗試像:

我會改變圖像串爲爲了便於閱讀,我從谷歌的例子。

from PIL import Image 
from io import BytesIO 
import base64 

data['img'] = '''R0lGODlhDwAPAKECAAAAzMzM/////wAAACwAAAAADwAPAAACIISPeQHsrZ5ModrLlN48CXF8m2iQ3YmmKqVlRtW4MLwWACH+H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw==''' 

im = Image.open(BytesIO(base64.b64decode(data))) 

你的數據[ 'IMG']字符串不應包括html標籤,或所述參數數據:圖像/ JPEG; BASE64,是在實施例的jsfiddle。

+2

非常感謝!這工作完美。我已經標記你的答案是正確的。 – 2014-09-28 14:18:05

16

img字段中包含data:image/jpeg;base64,的元數據前綴。通常,在將圖像數據嵌入到文檔或樣式表中時,此元數據將用於CSS或HTML數據URI。它提供了嵌入數據的MIME類型和編碼到渲染瀏覽器。

您可以在base64解碼之前剝離前綴,這應該會導致PIL可以加載的有效圖像數據(請參見下文),但是您確實需要質疑元數據是如何正常提交到服務器的不。

import re 
import cStringIO 
from PIL import Image 

image_data = re.sub('^data:image/.+;base64,', '', data['img']).decode('base64') 
image = Image.open(cStringIO.StringIO(image_data)) 
+0

非常感謝!這工作完美! – 2014-09-28 14:17:41

+0

@LazaroGamio:主要的一點是,前綴不應該出現在發佈到你的服務器的數據中。它是如何發佈的? – mhawke 2014-09-28 14:32:07

+0

我正在使用用戶上傳的圖像並通過jquery post方法將其發送到API。我想我可以剝離客戶端的前綴,而不是在服務器上刪除它。 – 2014-09-28 15:46:38

1

對不起,我的答案完全沒有效果。這裏是關於Python 3.6和Flask 0.13的代碼。

服務器:

from flask import Flask, jsonify, request 
from io import BytesIO 
from web import app 
import base64 
import re 
import json 
from PIL import Image 

@app.route('/process_image', methods=['post']) 
def process_image(): 
    image_data = re.sub('^data:image/.+;base64,', '', request.form['data']) 
    im = Image.open(BytesIO(base64.b64decode(image_data))) 
    return json.dumps({'result': 'success'}), 200, {'ContentType': 'application/json'} 

客戶JS:

// file comes from file input 
var reader = new FileReader(); 
reader.onloadend = function() { 
    var fileName = file.name; 
    $.post('/process_image', { data: reader.result, name: fileName }); 
}; 
reader.readAsDataURL(file);