Python 为什么在记事本中复制和粘贴字符并将其转换而成的图片会损坏?

Python 为什么在记事本中复制和粘贴字符并将其转换而成的图片会损坏?,python,image,file,encoding,Python,Image,File,Encoding,这个问题本质上是导致编写更大程序时出现问题。我已经把问题的原因缩小到这个小得多的问题上 简单地说,我们遵循以下程序 使用油漆制作图片,例如位图 通过重命名将此图片转换为.txt文件 从使用记事本访问的文本文件中复制所有字符 将其粘贴到新的.txt文件中 将其转换为原始图片文件类型,例如位图 我们为此获取的图片将无法打开,因为它显然已损坏。为什么会这样 在进行此操作时,我假设所有的数据都包含在编码中,这是错误的吗?是否创建了一些“隐形签名”以防止在没有适当软件的情况下创建新图片文件?如果是这样,我

这个问题本质上是导致编写更大程序时出现问题。我已经把问题的原因缩小到这个小得多的问题上

简单地说,我们遵循以下程序

  • 使用油漆制作图片,例如位图
  • 通过重命名将此图片转换为.txt文件
  • 从使用记事本访问的文本文件中复制所有字符
  • 将其粘贴到新的.txt文件中
  • 将其转换为原始图片文件类型,例如位图
  • 我们为此获取的图片将无法打开,因为它显然已损坏。为什么会这样

    在进行此操作时,我假设所有的数据都包含在编码中,这是错误的吗?是否创建了一些“隐形签名”以防止在没有适当软件的情况下创建新图片文件?如果是这样,我是否可以使用Python 2.7.5中pygame支持的其他文件类型

    计算机存储文件的方式是否与游戏安装存储与安装相关的文件的方式类似,因此它们不允许未经合法安装的应用程序执行?如果是这样的话,是否有一种文件类型我可以使用,但它不能做到这一点


    总的来说,我主要是想弄清楚为什么这不起作用。感谢您的回复,非常感谢

    记事本可能正在将换行符(0x0a)转换为DOS换行符(0x0d0a)。几乎所有Windows文本编辑器都会自动执行此操作

    这将破坏图像文件,这并不奇怪。更一般地说,这就是为什么您不应该尝试使用文本编辑器编辑二进制文件的原因


    你到底为什么要这么做?为什么不直接复制文件?

    这取决于图像编码与文本编码的本质。下面是发生的情况,然后是如何修复:

    1) 正如您所期望的,将文件重命名为.txt对底层数据没有任何影响,而底层数据保持不变

    2) 用记事本打开它就行了。记事本将看到一组字节(0-256),并尝试将它们解释为ASCII或其他编码

    • 32到128之间的字节以及32以下的几个字节将被解释为ASCII字母(a-z、a-z、0-9等)
    • 32以下的大多数字节和128以上的许多字节将被解释为非打印字符,并被忽略或打印为其UTF描述符号。这会导致它们丢失或改变
    • 超过128的某些字节将被解释为有效的多字节编码字符,并显示为有效的多字节编码字符(例如UTF或另一种自动错误检测的编码)
    3) 复制字符会将这些损坏的字符复制到剪贴板,然后返回到python

    4) Python可能会将新字符串存储为UTF字符串或字节字符串,无论哪种方式,如果与记事本错误检测的编码不匹配,此转换可能会创建一组类似于#2中的情况

    5) 转换回二进制字节会得到不同的结果,因为不协调的数据已被2-4破坏

    现在,如何修复它

    使用有效的ASCII(或UTF-7)编码算法。我建议使用一个base-64,就像MIME中使用的那个。下面是一个使用Python的
    base64
    模块的示例:

    import base64, binascii
    # Here, we write the content of source.png to a text file store.txt
    with open('source.png', 'rb') as src_file, open('store.txt', 'w') as store_file:
        store_file.write(binascii.b2a_base64(src_file.read()))
    # Now, read the store.txt file and convert back to binary.
    with open('store.txt', 'r') as store_file:
        data = binascii.a2b_base64(store_file.read())
    # Finally, if desired, write out the recreated png file to make sure it worked.
    with open('destination.png', 'wb') as dest_file:
        dest_file.write(data)
    

    PS:对于那些好奇的人来说,这是电子邮件中附件的发送方式,所以如果你在电子邮件中收到了一个图像(我相信你收到了),那么你的计算机很可能会收到它的编码是使用如上所述的base-64编码。(为了确保MIME兼容性,需要一些细微的差异。)

    我也不清楚所有有效像素值是否都是有效的ascii。通过转换换行符,这会不会像我看到的那样将相同的字符发送到下一个文件中?尝试这样做的原因是希望让程序在不存在文件的实际副本的情况下复制图片文件,而不是将字符放在字符串中。正在尝试为我正在制作的游戏制作一个安装程序。好的,为所有的帮助人员干杯,为这个帮助干杯。(正在查看stackoverflow的内容)。需要补充的一点很简单,就是必须导入binascii。@user3011122捕捉得很好。