python - 如何将 ascii 编码的图像数据解码为图像文件?
问题描述
概述
以简洁和(相对)全面的方式处理 base64 编码图像文件的解码。
目标
首要目标
- 使用 python 3.6 获取任意 base64 字符串,无论是作为“内存”字符串还是外部文件,并从中生成有效的图像文件。
次要目标
- 使用
libmagic
(或其他一些 python 库)尽可能确定编码文件的 mime 类型,以指导正确的文件类型输出。
初步假设
编码有效
- 一个小的 JPG 图像以 base64 编码。我已经通过使用浏览器的本机解码设备对编码图像通过 Web 浏览器查看编码数据来验证编码是否良好。见下文。
这在 Python 3.6 中是可行的
- 看起来这个
base64
包是为此而做的,除非我离基地很远。
尝试的解决方案
解释
我创建了一个名为Converter
来处理任务的python类,具有以下功能
构造函数
__init__(self, file="none", str_object="none")
- 接受 2 个字符串参数。根据所需的使用情况,只指定一个来替换默认值。
file="none"
- 文件路径作为基于文件解码的字符串。str_object="none"
- 裸编码字符串。
实例方法
convert_ascii_to_byte_stream(self)
- 没有论据
- 返回一个
base64
对象
convert_byte_stream_to_jpg(self)
- 没有论据
- 打开一个新文件,尝试写入一个字节流(使用
convert_ascii_to_byte_stream
,然后关闭文件。 - 不返回任何内容
@staticmethod strip_all_whitespace(s)
- 采用任意长度的单个字符串。
- 返回删除了所有空格、换行符、制表符和回车符的字符串。
用法
__main__.py
from Converter import *
c = Converter('ascii_image.txt', 'none') # create Converter instance
# print(c.get_encoding_type()) # attempt to get encoding
c.convert_byte_stream_to_jpg() # output the decoded data to image file
观察和问题
- 如果我调用构造函数
Converter('none', 'XyZxYzXyZxYzXyZxYz ...)
,那么转换就会完美无缺。显然,写入文件存在问题。 - 我了解
<img>
源属性的前缀,data:image/jpg;base64,
必须在解码之前剥离。因此,正在使用的测试文件ascii_image.txt
已被编辑以反映这一点。 - 在原始源代码中,每行末尾都有换行符,每个后续行的开头都有一个空格。不确定这是否会有所不同,尤其是考虑到我在尝试解码之前要删除所有空格。
- 我尝试了一堆复杂的使用
libmagic
,python-libmagic
,python-magic-bin
,file-magic
和其他各种扩展包的方法,但有很多困惑和进展。他们中的大多数人只是创建了关于缺少依赖项、编译器错误和其他问题的意大利面条式错误消息流。任何建议,将不胜感激。
相关代码和错误信息
Converter
Python 类
from io import *
import base64
# import magic
class Converter:
def __init__(self, file="none", str_object="none"):
self.file = file
self.str_object = str_object
if file == "none" or "":
self.isFromStringInput = True
self.asciiString = str_object
else:
f = open(file, 'r')
self.isFromStringInput = False
# this was the source of the pad error
#self.asciiString = f.read(file.__len__())
# changed to ... duh!
self.asciiString = f.read()
f.close()
def convert_byte_stream_to_jpg(self):
f = open('ascii_image.jpg', 'wb')
f.write(self.convert_ascii_to_byte_stream())
f.close()
return
def convert_ascii_to_byte_stream(self):
return base64.b64decode(self.strip_all_whitespace(self.asciiString))
@staticmethod
def strip_all_whitespace(s):
return s.replace('\n', ' ').replace('\r', '').replace('\t', '').replace(' ', '')
# def get_encoding_type(self):
# m = magic.MAGIC_MIME
# m.from_bytes(self.convert_ascii_to_byte_stream(), 'little')
# return m.file('./' + self.file)
错误信息
Traceback (most recent call last):
File "/Users/auser/PycharmProjects/btobin/__main__.py", line 5, in <module>
c.convert_byte_stream_to_jpg() # output the decoded data to image file
File "/Users/auser/PycharmProjects/btobin/Converter.py", line 22, in convert_byte_stream_to_jpg
f.write(self.convert_ascii_to_byte_stream())
File "/Users/auser/PycharmProjects/btobin/Converter.py", line 27, in convert_ascii_to_byte_stream
return base64.b64decode(self.strip_all_whitespace(self.asciiString))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/base64.py", line 87, in b64decode
return binascii.a2b_base64(s)
binascii.Error: Incorrect padding
已验证正确编码
如果将以下<img>
标记放在 html 文件中并用浏览器打开它,他们将看到正确解码的图像。这是解码图像的示例
<img src="data:image/jpg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNr
eQABAAQAAAAeAAD/4QOPaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYm
VnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHht
bG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjYtYzAxNC
A3OS4xNTY3OTcsIDIwMTQvMDgvMjAtMDk6NTM6MDIgICAgICAgICI+IDxyZGY6UkRGIHhtbG5z
OnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZG
Y6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUu
Y29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS
4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hh
cC8xLjAvIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6ZTg0NGJjNjUtYjAzZS
00ODZiLThlYTctZDFjZTY4OGU5YTc2IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjM4NTBE
Njg5Mzg2MzExRTZCOEZERTBFNjU0NTg5RUZDIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOj
M4NTBENjg4Mzg2MzExRTZCOEZERTBFNjU0NTg5RUZDIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2Jl
IFBob3Rvc2hvcCBDQyAyMDE0IChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0Um
VmOmluc3RhbmNlSUQ9InhtcC5paWQ6MjU4YjBiOTEtNGJhMC00NjI0LTg5NTUtYjU2ODg0OWIw
OWFhIiBzdFJlZjpkb2N1bWVudElEPSJhZG9iZTpkb2NpZDpwaG90b3Nob3A6ZTllYjAwMGQtOD
A0My0xMTc5LThhODktZjZmMjZkYTVhZGU1Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpS
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" />
解决方案
推荐阅读
- sikuli-script - Sikuli IDE 错误 - javax.script.ScriptException " 未在 nashorn:mozilla_compat.js 中第 69 行定义
- sql - 每月结束的数据准备 - 超过 12 个月
- r - R - 将 DFM 转换为 LSA,然后计算余弦相似度:Error inherits(x, "Matrix") is not TRUE
- google-cloud-logging - Google Cloud Logging 身份验证/权限
- r - 患者在 R 中表现良好的编程概率
- r - 如何逐行识别数据帧中的未知模式?
- jquery - 大数值以指数格式显示 Kendo jquery 树列表
- swift - 如何在 Swift 中合并 2 个 pdf 矢量图像资源
- django - 我如何在 django 和 windows 中编写 redis 通道层
- c# - EF 映射具有不同列类型的两个实体