Преобразовать строку из base64 обратно в байты base64 - PullRequest
0 голосов
/ 25 июня 2018

Я загрузил изображение, используя OpenCV, а затем закодировал его в кодировке base64, используя base64 's b64encode.

>>> import cv2
>>> import base64
>>> image = cv2.cvtColor(cv2.imread("some_image.jpg"), cv2.COLOR_BGR2RGB)
>>> image_64 = base64.b64encode(image)
>>> image_64
b'//////////////////...
>>> type(image_64)
<class 'bytes'>

Затем я преобразую его в строку, используя метод str(). Это создает строку закодированного изображения.

>>> image_64str = str(image_64)
>>> image_64str
b'//////////////////...
>>> type(image_64str)
<class 'str'>

Оба они (тип <class 'bytes'> и <class 'str'>) выглядят одинаково. Я попытался декодировать их, используя base64 s b64decode и функцию decode(). Однако произошла ошибка, когда я декодировал image_64str.

>>> image_64str.decode()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'decode'
>>> base64.b64decode(image_64str)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/base64.py", line 87, in b64decode
    return binascii.a2b_base64(s)
binascii.Error: Incorrect padding

Я полностью понял, что ошибки пытались сказать мне. Но мой вопрос, как я могу преобразовать строку закодированного изображения (image_64str) обратно в байты?

Я попытался снова использовать base64 'b64encode` в строке. Тем не менее, он возвращает ошибку.

>>> str_to_b64 = base64.b64encode(image_64str)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/base64.py", line 58, in b64encode
    encoded = binascii.b2a_base64(s, newline=False)
TypeError: a bytes-like object is required, not 'str'

Пожалуйста, скажите, заметил ли кто-нибудь, что я пропустил. Я использую Python 3.6. Заранее спасибо.

РЕДАКТИРОВАТЬ: Добавление более описания к моему вопросу.

Мне удалось включить двоичную поддержку AWS API Gateway. Моя цель - передать изображение в виде двоичных данных через запрос POST к API и преобразовать его в объект PIL, чтобы я мог обработать его в бэкэнде с помощью AWS Lambda. В API Gateway двоичные данные были закодированы в двоичном формате base64.

Я открыл изображение как двоичные данные, используя функцию open в python (было два изображения, которые я хотел передать через API). Затем я использую словарь для хранения двоичных данных обоих изображений, например

data = {"data1": img_binary_data_1, "data2": img_binary_data_2}

Я отправляю запрос POST, используя библиотеку python request. Одним из аргументов, которые я могу передать в функции post, является data, поэтому я передал данные изображения, используя это.

Мне удалось отправить запрос. В бэкэнде Lambda я хотел преобразовать двоичные данные в объект PIL для дальнейшей обработки. Однако кажется, что данные были упакованы в формат JSON, а двоичное изображение в кодировке base64 было преобразовано в строку Python. Я подтвердил это, напечатав данные в журнале AWS CloudWatch.

Я пытался использовать .decode(), но база здесь Вы не можете декодировать строку.

Мне удалось декодировать строку, используя b64decode(), возвращая объект байта. Однако при попытке преобразовать его в объект PIL, например

img = imread(io.BytesIO(base64.b64decode(b64_string)))

Я получил сообщение об ошибке

OSError: cannot identify image file <_io.BytesIO object at 0x1101dadb0>

Я попробовал некоторые решения из по этой ссылке , но, очевидно, вы не можете сделать это с помощью объекта-байта.

Я пытался использовать PIL.frombuffer и PIL.frombytes. Тем не менее, они вернули значение not enough data, когда я очень уверен насчет размера изображения (в данном случае (256, 256)).

Итак, мой вопрос, как я могу преобразовать изображение base64 в объект PIL? Надеюсь, это поможет лучше понять мой вопрос. Заранее спасибо.

1 Ответ

0 голосов
/ 26 июня 2018

Base64 - это двоичное кодирование -> char, поэтому кодирование изображения имеет смысл, вы получаете text байт, где группа из 6 битов считается символом.

Теперь, даже если вышеуказанные байты состоят из символов, они не являются строками Python, так как строки Python являются utf-8.

Когда вы конвертируете байты в строку, он конвертирует их в utf-8 и портит заполнение base64 (только = разрешено для заполнения), и вы получаете строку Python.

Теперь вы получите ошибку при декодировании, так как она больше не является кодировкой base64. Вы также не можете закодировать строку, поскольку base64 это байты -> char, а строка не байты.

Почему вы все равно конвертируете закодированные байты в строку? Немного больше описания вашего варианта использования поможет.

...