python flask base64 python-imaging-library pillow

python - Decodificación base64 de POST para usar en PIL



flask python-imaging-library (3)

Estoy haciendo una API simple en Flask que acepta una imagen codificada en base64, luego la decodifica para su posterior procesamiento con Pillow.

He visto algunos ejemplos ( 1 , 2 , 3 ), y creo que entiendo la esencia del proceso, pero sigo recibiendo un error donde Pillow no puede leer la cadena que le di.

Esto es lo que tengo hasta ahora:

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

que da el error:

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


Hay un prefijo de metadatos de data:image/jpeg;base64, se incluye en el campo img . Normalmente, estos metadatos se utilizan en un URI de datos CSS o HTML cuando se incorporan datos de imagen en el documento o en la hoja de estilo. Está allí para proporcionar el tipo MIME y la codificación de los datos integrados en el navegador de renderizado.

Puedes quitar el prefijo antes de la decodificación base64 y esto debería dar como resultado datos de imagen válidos que PIL puede cargar (ver a continuación), pero realmente necesitas cuestionar cómo los metadatos se envían a tu servidor como normalmente no debería.

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


Deberías probar algo como:

Voy a cambiar la cadena de imagen para un ejemplo que tomé de Google solo para fines de legibilidad.

from PIL import Image from io import BytesIO import base64 data[''img''] = ''''''R0lGODlhDwAPAKECAAAAzMzM/////wAAACwAAAAADwAPAAACIISPeQHsrZ5ModrLlN48CXF8m2iQ3YmmKqVlRtW4MLwWACH+H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw=='''''' im = Image.open(BytesIO(base64.b64decode(data)))

Su cadena de datos [''img''] no debe incluir las etiquetas html ni los datos de parámetros : image / jpeg; base64, que se encuentran en el ejemplo jsfiddle.


Perdón por la nigromancia, pero ninguna de las respuestas funcionó por completo para mí. Aquí está el código trabajando en Python 3.6 y Flask 0.13.

Servidor:

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''}

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