转自:PIL.Image与Base64 String的互相转换 - 简书
0.环境
- py2: python2.7.13
- py3: python3.6.2
- PIL: pip(2/3) install pillow, PIL库已不再维护,而pillow是PIL的一个分支,如今已超越PIL
1.Convert PIL.Image to Base64 String
- py2 :
先使用CStringIO.StringIO把图片内容转为二进制流,再进行base64编码
# -*- coding: utf-8 -*-
import base64
from cStringIO import StringIO
# pip2 install pillow
from PIL import Image
def image_to_base64(image_path):
img = Image.open(image_path)
output_buffer = StringIO()
img.save(output_buffer, format='PNG')
binary_data = output_buffer.getvalue()
base64_data = base64.b64encode(binary_data)
return base64_data
- py3:
python3中没有cStringIO,对应的是io,但却不能使用io.StringIO来处理图片,它用来处理文本的IO操作,处理图片的应该是io.BytesIO
import base64
from io import BytesIO
# pip3 install pillow
from PIL import Image
# 若img.save()报错 cannot write mode RGBA as JPEG
# 则img = Image.open(image_path).convert('RGB')
def image_to_base64(image_path):
img = Image.open(image_path)
output_buffer = BytesIO()
img.save(output_buffer, format='PNG')
byte_data = output_buffer.getvalue()
base64_str = base64.b64encode(byte_data)
return base64_str
2. Convert Base64 String to PIL.Image
要注意的是图片内容转化所得的Base64 String是不带有头信息/html标签(data:image/jpeg;base64,)的,这是在h5使用的时候需要添加用来声明数据类型的,如果拿到的Base64 String带了这个标签的话,需要处理一下,这里从参考的博客中找了一种正则处理方法。
- py2:
# -*- coding: utf-8 -*-
import base64
from cStringIO import StringIO
from PIL import Image
def base64_to_image(base64_str, image_path=None):
head, base64_data = base64_str.split(',')
binary_data = base64.b64decode(base64_data)
img_data = StringIO(binary_data)
img = Image.open(img_data)
if image_path:
img.save(image_path)
return img
- py3
import base64
from io import BytesIO
from PIL import Image
def base64_to_image(base64_str, image_path=None):
head, base64_data = base64_str.split(',')
byte_data = base64.b64decode(base64_data)
image_data = BytesIO(byte_data)
img = Image.open(image_data)
if image_path:
img.save(image_path)
return img
3.Ruquests获取网络图片后转换为base64
- py3
import base64
import requests
req_image = requests.get(url)
base_data = str(base64.encodebytes(req_image.content), 'utf-8')
result = 'data:image/png;base64,%s' % base_data
- py3 (获取图片转换成 png 格式再转换为 base64)
# -- coding: utf-8 --
import io
import base64
import requests
from PIL import Image
def request_image_to_base64(image_url):
req_image = requests.get(image_url, verify = False)
byte_stream = io.BytesIO(req_image.content)
img = Image.open(byte_stream)
output_buffer = io.BytesIO()
img.save(output_buffer, format = 'PNG')
byte_data = output_buffer.getvalue()
return str(base64.encodebytes(byte_data), 'utf-8')
4.将 Image 网络存储、将 Base64 图片网络存储
- py3 (base64)
def request_image_and_save(image_url): req_image = requests.get(image_url, verify = False) head, base64_data = str(req_image.content).split(',') byte_data = base64.b64decode(base64_data) image_data = io.BytesIO(byte_data) filename = 'folder/test_name.png' # 下面的 upload_img_stream 是自己封装的函数 upload_img_stream(filename, image_data.getvalue())
- py3(PIL 的 Image)
def read_image_and_save(file_path): img = Image.open(file_path) img_byte = io.BytesIO() # 创建一个空的Bytes对象 img.save(img_byte, format = 'PNG') # PNG就是图片格式,我试过换成JPG/jpg都不行 filename = 'folder/test_name.png' upload_img_stream(filename, img_byte.getvalue())
5. 参考
https://stackoverflow.com/questions/16065694/is-it-possible-to-create-encodeb64-from-image-objecthttps://link.jianshu.com?t=https%3A%2F%2Fstackoverflow.com%2Fquestions%2F16065694%2Fis-it-possible-to-create-encodeb64-from-image-object
https://stackoverflow.com/questions/31826335/how-to-convert-pil-image-image-object-to-base64-stringhttps://link.jianshu.com?t=https%3A%2F%2Fstackoverflow.com%2Fquestions%2F31826335%2Fhow-to-convert-pil-image-image-object-to-base64-string
https://stackoverflow.com/questions/26070547/decoding-base64-from-post-to-use-in-pilhttps://link.jianshu.com?t=https%3A%2F%2Fstackoverflow.com%2Fquestions%2F26070547%2Fdecoding-base64-from-post-to-use-in-pil