Когда вы это сделаете:
import cv2
A = cv2.imread("image.jpg")
im_bytes = A.tostring()
A
будет массивом Numpy всех пикселей изображения. Таким образом, если изображение имеет размер 1024x1024 и RGB, A
будет массивом Numpy из shape(1024,1024,3)
, который непосредственно содержит все пиксели RGB в массиве типа np.uint8
. Затем, когда вы запустите на нем tobytes()/tostring()
, он будет иметь размер 3 МБ необработанных данных пикселей без размеров, без даты и без сжатия. Если вы передадите его кому-то другому через сокет или сохраните его в файле, приемник не узнает, какой это формат: 1024x1024 RGB, 1048576x3 в оттенках серого или 384x2048 RGBA.
С другой стороны, когда вы сделайте следующее:
import cv2
from PIL import Image
import io
A = cv2.imread("image.jpg")
pil_im = Image.fromarray(A)
b = io.BytesIO()
pil_im.save(b, 'jpeg')
b
теперь будет JPEG-сжатой версией вашего изображения с потерями, которая содержит то же самое, как если бы вы записали его в файл JPEG. Таким образом, он содержит дату, которую вы написали, размеры изображения, цветовое пространство и таблицы, необходимые для его распаковки, а также сжатые данные пикселей. b
- это, по сути, JPEG в ОЗУ.
Есть и другие проблемы с вашим вторым примером.
Во-первых, и что наиболее важно, нет никакого смысла распаковывать изображение JPEG в массив Numpy пикселей, а затем повторно сжимать его в JPEG. Если вам нужны данные в кодировке JPEG, вы также можете прочитать их без кодирования прямо из файла:
with open('image.jpg', 'rb') as f:
image = f.read()
Во-вторых, если по какой-то неизвестной причине вы действительно хотите декодировать JPEG в массив Numpy сырых пикселей, а затем перекодировать его обратно в JPEG, вы могли бы также использовать OpenCV, а не вводить совершенно новую зависимость от PIL:
A = cv2.imread("image.jpg")
_, JPEG = cv2.imencode('.jpeg', A)
В-третьих, если вы настаиваете на ненужном декодировании и перекодировании в JPEG, а также при введении PIL в качестве зависимости вы столкнетесь с еще одной проблемой. Поскольку вы читаете изображение с помощью OpenCV, вы получите его в порядке BGR. PIL хранит изображения в порядке RGB. Итак, если вы создадите изображение PIL из массива OpenCV Numpy, вы получите поменять местами красный и синий каналы, и все ваши цвета будут неправильными.