python读取image文件_python编码:打开/读取图像文件,解码图像,重新编码图像

注意:我对编码/解码不太了解,但是在我遇到这个问题之后,这些词对我来说已经完全是行话了。

问题:我有点困惑。我在玩编码/解码图像,在django模型中存储一个作为TextField的图像,查看堆栈溢出,我发现我可以从ascii解码一个图像(我想还是二进制的?无论open('file', 'wb')使用什么作为编码。我假设默认的ascii到latin1,并将其存储在一个没有问题的数据库中。

问题来自于从latin1解码数据创建图像。当试图写入文件句柄时,我得到一个UnicodeEncodeError表示ascii编码失败。

我认为问题是当以二进制数据(rb形式打开文件时,它不是正确的ascii编码,因为它包含二进制数据。然后我将二进制数据解码为latin1,但当转换回ascii时(尝试写入文件时自动编码),由于一些未知的原因,它失败了。

我的猜测是,当解码到latin1时,原始二进制数据被转换成其他数据,然后当尝试重新编码到ascii时,它无法识别曾经的原始二进制数据。(尽管原始数据和解码数据的长度相同)。或者问题不在于对latin1的解码,而在于我试图用ASCII编码二进制数据。在这种情况下,我如何编码latin1。数据返回到图像。

我知道这很令人困惑,但我对这一切都很困惑,所以我无法很好地解释。如果有人能回答这个问题,很可能有个谜语大师。

一些要可视化的代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47>>> image_handle = open('test_image.jpg', 'rb')

>>>

>>> raw_image_data = image_handle.read()

>>> latin_image_data = raw_image_data.decode('latin1')

>>>

>>>

>>> # The raw data can't be processed by django

... # but in `latin1` it works

>>>

>>> # Analysis of the data

>>>

>>> type(raw_image_data), len(raw_image_data)

(, 2383864)

>>>

>>> type(latin_image_data), len(latin_image_data)

(, 2383864)

>>>

>>> len(raw_image_data) == len(latin_image_data)

True

>>>

>>>

>>> # How to write back to as a file?

>>>

>>> copy_image_handle = open('new_test_image.jpg', 'wb')

>>>

>>> copy_image_handle.write(raw_image_data)

>>> copy_image_handle.close()

>>>

>>>

>>> copy_image_handle = open('new_test_image.jpg', 'wb')

>>>

>>> copy_image_handle.write(latin_image_data)

Traceback (most recent call last):

File"", line 1, in

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)

>>>

>>>

>>> latin_image_data.encode('ascii')

Traceback (most recent call last):

File"", line 1, in

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)

>>>

>>>

>>> latin_image_data.decode('ascii')

Traceback (most recent call last):

File"", line 1, in

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)

我先在维基百科上查找JPG,然后查找纯文本文件。一个图像文件不会有任何可以编码成ASCII的纯文本数据。它们只是不同类型的数据、苹果和橘子、纯文本文件和二进制文件

所以我可以从ASCII中解码图像数据,但不能返回到它?这意味着这是一种单向转换?

等等,当以二进制方式打开文件时,它的编码是什么?我知道python默认为ascii,但这是原始数据,对吗?妈的,我不能通过这个。

二进制文件将没有文本编码。格式可能是一个更好的术语。JPG中的二进制数据与任何类型的文本编码都没有关系。您可以尝试将二进制文件作为文本文件读取。python将读取文件并显示unicode字符,但它实际上只是一个jibberish。要打开二进制文件,您需要一个准备好处理该文件格式的程序。Microsoft Word文本文档被认为是二进制文件,因为它们添加了额外的格式,您需要使用Word专门打开这些文件。文本文件可以用普通的文本编辑器(如记事本)读取。

啊,有道理。没有编码是一个完美的答案。

我将用二进制文件和文本文件键入一个答案,并链接到另一个有关编码的stackoverflow问题。

与普通/疼痛文本文件不同,图像文件没有任何编码,显示的数据是图像的二进制等价物的可视表示。就像@cameron-f在上面的问题评论中所说的,这基本上是胡言乱语,任何编码都会破坏图像文件,所以不要尝试它。

但这并不意味着所有的希望都丧失了。这是我通常将图像转换为字符串并返回图像的方法。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43from base64 import b64decode, b64encode

image_handle = open('test_image.jpg', 'rb')

raw_image_data = image_handle.read()

encoded_data = b64encode(raw_image_data)

compressed_data = zlib.compress(encoded_image, 9)

uncompressed_data = zlib.decompress(compressed_data)

decoded_data = b64decode(uncompressed_data)

new_image_handle = open('new_test_image.jpg', 'wb')

new_image_handle.write(decoded_data)

new_image_handle.close()

image_handle.close()

# Data Types && Data Size Analysis

type(raw_image_data), len(raw_image_data)

>>> (, 2383864)

type(encoded_image), len(encoded_image)

>>> (, 3178488)

type(compressed_data), len(compressed_data)

>>> (, 2189311)

type(uncompressed_data), len(uncompressed_data)

>>> (, 3178488)

type(decode_data), len(decode_data)

>>> (, 2383864)

# Showing that the conversions were successful

decode_data == raw_image_data

>>> True

encoded_data == uncompressed_data

>>> True

因为jpeg是二进制文件,而ascii编码是纯文本文件中的纯文本,所以会弹出unicodeencode错误。

纯文本文件可以使用通用文本编辑器(如Windows记事本或Linux nano)创建。大多数将使用ASCII或Unicode编码。当文本编辑器读取一个ASCII文件时,它将抓取一个字节,比如说01100001(在DEC中为97),并找到相应的标志符号"A"。

因此,当文本编辑器试图读取JPG时,它将获取相同的字节01100001并获得"A",但由于文件包含用于显示照片的信息,因此文本将是不安全的。尝试在记事本或nano中打开jpeg。

关于编码,这里有一个解释:编码/解码之间的区别是什么?

感谢您发布答案。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值