如何解码包含纯文本和字节字符的`piexif`元数据字符串?

huangapple go评论57阅读模式
英文:

How to decode `piexif` metadata strings containing both plain text and bytes characters?

问题

抱歉,由于文本长度较长,我将截取一部分文本进行翻译和处理。以下是部分翻译和处理的内容:

原始字符串包含人类可读部分和字节/控制字符(我猜测),如下所示:

weird_string = ''Nikon\x00\x02\x00\x00\x00II*\x00\x08\x00\x00\x00\x15\x00\x01\x00\x07\x00\x04\x00\x00\x00\x00\x02\x00\x00\x02\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x02\x00\x06\x00\x00\x00\n\x01\x00\x00\x04\x00\x02\x00\x07\x00\x00\x00\x10\x01\x00\x00\x05\x00\x02\x00\r\x00\x00\x00\x18\x01\x00\x00\x06\x00\x02\x00\x07\x00\x00\x00&\x01\x00\x00\x07\x00\x02\x00\x07\x00\x00\x00.\x01\x00\x00\x08\x00\x02\x00\x08\x00\x00\x006\x01\x00\x00...

我会尽力将它处理成仅包含可打印字符、替换空格/制表符/换行符等非打印字符,并去除不可打印字符。请继续提供需要处理的文本或具体的操作要求。

英文:

I have a string containing both human-readable parts and bytes/control characters (I guess), like the following:

weird_string = 'Nikon\x00\x02\x00\x00\x00II*\x00\x08\x00\x00\x00\x15\x00\x01\x00\x07\x00\x04\x00\x00\x00\x00\x02\x00\x00\x02\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x02\x00\x06\x00\x00\x00\n\x01\x00\x00\x04\x00\x02\x00\x07\x00\x00\x00\x10\x01\x00\x00\x05\x00\x02\x00\r\x00\x00\x00\x18\x01\x00\x00\x06\x00\x02\x00\x07\x00\x00\x00&\x01\x00\x00\x07\x00\x02\x00\x07\x00\x00\x00.\x01\x00\x00\x08\x00\x02\x00\x08\x00\x00\x006\x01\x00\x00\n\x00\x05\x00\x01\x00\x00\x00>\x01\x00\x00\x0f\x00\x02\x00\x07\x00\x00\x00F\x01\x00\x00\x00\x02\x00\x0e\x00\x00\x00N\x01\x00\x00\x00\x02\x00\r\x00\x00\x00\\\x01\x00\x00\x00\x05\x00\x01\x00\x00\x00j\x01\x00\x00\x00\x05\x00\x01\x00\x00\x00r\x01\x00\x00\x00\x07\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x10\x00\x00\x00z\x01\x00\x00\x00\x08\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x05\x00\x00\x00\x01\x00\x00\x10\x00\x07\x00\x00\x00\x00\x01\x00\x00\x11\x00\x04\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00COLOR\x00FINE  \x00\x00AUTO        \x00\x00AUTO  \x00\x00AF-S  \x00\x00       \x00"\x00\x00\x03\x00\x00AUTO  \x00\x00AUTO         \x00OFF         \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00d\x00\x00\x00               \x00OFF \x00\x00\x05\x02\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00a\x05\x00\x00\x00\x03r\x00`\x14\x00\x01!\x00\x00\x06{\x00\x00\x00\x00\x00\x00\x1f\x05\x0b\x00\x1b\x07\x06&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07*]\x00\x00\x06\x07\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x007\x06\x00\x00J\x02\x15\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02C\x16\x00\x00\x00\x00\x04\x07\x00\x1a\x00\x00\x00\x00\x19a\x121uv\x1b\x17\x12\x18\x14\x15\x15\x17\x00\x00\x00\x00\x0c\x00\r\x01\x02 R\x00\x03\x03z\x00\x00\x00\x0fch\x0cU\x0ed\x00d\x00\x0e\x12\x06\x06\x01\x02L\x00\x02\x00\x00@\x00M\x00\x00\x00\x11\x00\x00\x00\x00\x11\x11\x11\x11\x00\x00\x00c\x00\x00\x03\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x0b\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00eC!\x07\x00\x03\x01\x03\x00\x01\x00\x00\x00\x06\x00\x00\x00\x1a\x01\x05\x00\x01\x00\x00\x00\x02\x00\x00\x1b\x01\x05\x00\x01\x00\x00\x00\x02\x00\x00(\x01\x03\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\x02\x04\x00\x01\x00\x00\x00\x134\x00\x00\x02\x02\x04\x00\x01\x00\x00\x00%\x00\x00\x13\x02\x03\x00\x01\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00,\x01\x00\x00\x01\x00\x00\x00,\x01\x00\x00\x01\x00\x00\x00'

I would like to "decode" it by:

  • keeping only human readable characters
  • substituting spaces/tabs/newlines/... with appropriate control characters
  • strip non-printable characters

I don't know exactly what the desired output should be. The closest I could get is based on this discussion:

''.join(c for c in weird_string if c.isprintable())

>>> 'NikonII*&.6>FN\\jrzCOLORFINE  AUTO        AUTO  AF-S         "AUTO  AUTO         OFF         dd               OFF ar`!{&*]7JCa1uv RzchUddL@MceC!(4%,,'

As you can see this one-liner does most part of the job done, however there are still some weird parts. Is this the "correct" human representation of weird_string?

Apologies in advance for not being specific enough and possible misused terms. I am not familiar with string manipulation, which makes it difficult explaining clearly the problem and the desired output. I'm happy to include more details if asked.

EDIT:

I add a bit more context:

The weird_string comes from exif metadata of a .jpeg image. My ultimate goal is to dump all available metadata in a human-readable txt.

Specifically, I get the metadata using the piexif library:


with Image.open(image_path) as pil:
    metadata = piexif.load(pil.info['exif'])

This gives me a metadata dictionary as the following:

>>> metadata
{'0th': {270: '          ', 271: 'NIKON', 272: 'E4500', 274: 1, 282: (300, 1), 283: (300, 1), 296: 2, 305: 'E4500v1.3', 306: '0000:00:00 00:00:00', 531: 2, 34665: 284}, 'Exif': {33434: (10, 80), 33437: (31, 10), 34850: 4, 34855: 100, 36864: '0220', 36867: '0000:00:00 00:00:00', 36868: '0000:00:00 00:00:00', 37121: '\x01\x02\x03\x00', 37122: (3, 1), 37380: (0, 10), 37381: (28, 10), 37383: 5, 37384: 0, 37385: 16, 37386: (126, 10), 37500: 'Nikon\x00\x02\x00\x00\x00II*\x00\x08\x00\x00\x00\x15\x00\x01\x00\x07\x00\x04\x00\x00\x00\x00\x02\x00\x00\x02\x00\x03\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x02\x00\x06\x00\x00\x00\n\x01\x00\x00\x04\x00\x02\x00\x07\x00\x00\x00\x10\x01\x00\x00\x05\x00\x02\x00\r\x00\x00\x00\x18\x01\x00\x00\x06\x00\x02\x00\x07\x00\x00\x00&\x01\x00\x00\x07\x00\x02\x00\x07\x00\x00\x00.\x01\x00\x00\x08\x00\x02\x00\x08\x00\x00\x006\x01\x00\x00\n\x00\x05\x00\x01\x00\x00\x00>\x01\x00\x00\x0f\x00\x02\x00\x07\x00\x00\x00F\x01\x00\x00\x00\x02\x00\x0e\x00\x00\x00N\x01\x00\x00\x00\x02\x00\r\x00\x00\x00\\\x01\x00\x00\x00\x05\x00\x01\x00\x00\x00j\x01\x00\x00\x00\x05\x00\x01\x00\x00\x00r\x01\x00\x00\x00\x07\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x10\x00\x00\x00z\x01\x00\x00\x00\x08\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x05\x00\x00\x00\x01\x00\x00\x10\x00\x07\x00\x00\x00\x00\x01\x00\x00\x11\x00\x04\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00COLOR\x00FINE  \x00\x00AUTO        \x00\x00AUTO  \x00\x00AF-S  \x00\x00       \x00"\x00\x00\x03\x00\x00AUTO  \x00\x00AUTO         \x00OFF         \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00d\x00\x00\x00               \x00OFF \x00\x00\x05\x02\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00a\x05\x00\x00\x00\x03r\x00`\x14\x00\x01!\x00\x00\x06{\x00\x00\x00\x00\x00\x00\x1f\x05\x0b\x00\x1b\x07\x06&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07*]\x00\x00\x06\x07\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x007\x06\x00\x00J\x02\x15\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02C\x16\x00\x00\x00\x00\x04\x07\x00\x1a\x00\x00\x00\x00\x19a\x121uv\x1b\x17\x12\x18\x14\x15\x15\x17\x00\x00\x00\x00\x0c\x00\r\x01\x02 R\x00\x03\x03z\x00\x00\x00\x0fch\x0cU\x0ed\x00d\x00\x0e\x12\x06\x06\x01\x02L\x00\x02\x00\x00@\x00M\x00\x00\x00\x11\x00\x00\x00\x00\x11\x11\x11\x11\x00\x00\x00c\x00\x00\x03\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x0b\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00eC!\x07\x00\x03\x01\x03\x00\x01\x00\x00\x00\x06\x00\x00\x00\x1a\x01\x05\x00\x01\x00\x00\x00\x02\x00\x00\x1b\x01\x05\x00\x01\x00\x00\x00\x02\x00\x00(\x01\x03\x00\x01\x00\x00\x00\x02\x00\x00\x00\x01\x02\x04\x00\x01\x00\x00\x00\x134\x00\x00\x02\x02\x04\x00\x01\x00\x00\x00%\x00\x00\x13\x02\x03\x00\x01\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00,\x01\x00\x00\x01\x00\x00\x00,\x01\x00\x00\x01\x00\x00\x00', 37510: '\x00\x00\x00\x00\x00\x00\x00\x00                                                                                                                     ', 40960: '0100', 40961: 1, 40962: 2272, 40963: 1704, 40965: 1026, 41728: '\x03', 41729: '\x01', 41985: 0, 41986: 0, 41987: 0, 41988: (0, 100), 41989: 60, 41990: 0, 41991: 0, 41992: 0, 41993: 0, 41994: 0, 41996: 0}, 'GPS': {}, 'Interop': {1: 'R98'}, '1st': {259: 6, 282: (300, 1), 283: (300, 1), 296: 2, 513: 4084, 514: 3682}, 'thumbnail': b'\xff\xd8\xff\xdb\x00\xc5\x00\x07\x05\x06\x06\x06\x05\x07\x06\x06\x06\x08\x08\x07\t\x0b\x12\x0c\x0b\n\n\x0b\x17\x10\x11\r\x12\x1b\x17\x1c\x1c\x1a\x17\x1a\x19\x1d!*$\x1d\x1f( \x19\x1a%2%(,-/0/\x1d#484.7*./.\x01\x08\x08\x08\x0b\n\x0b\x16\x0c\x0c\x16.\x1e\x1a\x1e..................................................\x02\x08\x08\x08\x0b\n\x0b\x16\x0c\x0c\x16.\x1e\x1a\x1e..................................................\xff\xc4\x01\xa2\x00\x00\x01\x05\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x10\x00\x02\x01\x03\x03\x02\x04\x03\x05\x05\x04\x04\x00\x00\x01}\x01\x02\x03\x00\x04\x11\x05\x12!1A\x06\x13Qa\x07"q\x142\x81\x91\xa1\x08#B\xb1\xc1\x15R\xd1\xf0$3br\x82\t\n\x16\x17\x18\x19\x1a%&\'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz\x83\x84\x85\x86\x87\x88\x89\x8a\x92\x93\x94\x95\x96\x97\x98\x99\x9a\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\x01\x00\x03\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x11\x00\x02\x01\x02\x04\x04\x03\x04\x07\x05\x04\x04\x00\x01\x02w\x00\x01\x02\x03\x11\x04\x05!1\x06\x12AQ\x07aq\x13"2\x81\x08\x14B\x91\xa1\xb1\xc1\t#3R\xf0\x15br\xd1\n\x16$4\xe1%\xf1\x17\x18\x19\x1a&\'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x92\x93\x94\x95\x96\x97\x98\x99\x9a\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xff\xc0\x00\x11\x08\x00x\x00\xa0\x03\x01!\x00\x02\x11\x01\x03\x11\x01\xff\xda\x00\x0c\x03\x01\x00\x02\x11\x03\x11\x00?\x00\xf9\xb8\x03\x8e\r;\x91\xd2\xb3gDSB\xf2\xd5*c\x18\xc6O\xaeje\xa2:h\xfb\xd2\xbb\x15\xa4.6\x0e\x175\'\x9f\'\xd9\xc4[\xbe\\\xf7\xac\x9c.\xb5\xefs\xd0\x865\xd3\xa8\xe5\x0f\xe5q\xf9\x11.9\x1c\xf3S+\xba\xae\t\xe2\x9c\xf5D\xe1%\xc9%(\xff\x00Z\x92\x02\x18\x029\x03\xb8?\xd2\x9e\xecX\xe1A\xcfN\xb5\x8b\xbd\xd1\xec\xc2Q\x8c%%\xd6\xdf\x93$\xb6\x91!\x95\x1b`v\x1e\xf5\xa3y|\x97V\xe9\x1a+,\x91\x9c\x82y\xaeJ\xd0\x94\xa6\xa5\xd0\xf50U#\n2\xa6\xb7\xfdlcN\xe7\xa0$\x9fZ\xae\xc1\xb0\t8\xae\xfaj\xc8\xf9\x8c\xc2\xa3\x9dF\x84\xdc;PX\xf5\'5\xa5\x8e.{l\x1b\xb3\xc1\xe9M\xe3<f\x9a\xd0\x99\xcb\x9b\xa9eK\x18\xf6\x9eW\xd2\xa0\x990\x85\x80>\xf5\x9ct\x91\xd9\x88\x8f=\x14\xdfE\xff\x00\x07\xfc\xca\xf5 \xc7\x97\xc1\xc75\xbb<zoP\\\x03\x92i\xc7\x1c\x9d\xd5,\xde\x9a\xf7w\x00FG8\x1fJ\xd4[\x15\x93O\x17\x10\xb0\xdf\x82J\x93\xdb\xbdc^\xa7\xb3I\xbe\xac\xf4r\xec*\xc5JQ[\xa4\xda("\x00\xe0\xb3\x0f\xf8\r$\xd2\x19\x0f<\x01\xc0\xaa\xbf4\x8c\xf9=\x95)_\xe2n\xc3\xa2\xc8\\\xa8<r\xd5e\xbfv\x81\xbf\x88\xf6\xc7J\xce\xa6\xe7~\x05\xfe\xed\xb7\xb4U\xc6E\xb4\xb6O\x15<\x04.\xe6\xcf\x15\x9c\xfa\x9d\xf8K{\xad=/\xfa\x14\xa5;\x9d\xba\xe74\x83\x95\xe4f\xb7\x8e\x91G\x8dZ\\\xf5\xa4\xba;\x89\x81\xce\x05!\x1d\r]\xceWO\xb1\x1bcu*\x8ey5]\x0e\x7f\xb4O\x18\x00|\xcf\xd7\xb5,\x8c\xa2\x07\x199==\xf8\xac%\xbe\x87\xb1\x87\xb2\x8as}\xff\x00&S\xc1\xcf\x14u\xe2\xbaO\x9fJ\xc0\xa0\xf4\xa5 \x8aE$\xf9G\x85,\x06\xd1\xd3\xadn\xdb<6v@HI\x91\x91\x8f\x1d\xb28\xaeL^\xb0\xe5\xea\xcf\xa1\xc8#\xcb\x88u\x1e\x89G\xfc\x91KKX\xa5\xbbH\x9d?vrI$\xfa\x1fJ\x9a\xe5t\xd9ZFY\x9a)\x03p\x19\x0e\x1b\xdf\x8a\x89\xceq\xab\xa2\xbe\x87V\x1e\x86\x1e\xb6\t\xf3;{\xd6M\xf9+\x91\xa0\x11\xc7..#p\xc0\x05\x03\x8d\xdc\xfd=\xaa0\x03"\x93\x92s\x83MJ\xee\xe8\xb5I\xc6*\x13\xb6\xcd\xe9\xe4\xee\xbf\x0b\x88\xcb\xb7\xae>\x94\xe8NCc\xa9\x15M\xdd\\\x9aP\xe4\xa8\xa2\xc6<L0\xcc1\x91\x90j\x06Vl\xee8\xc75pi\x9c\x18\x9aR\x8b\xdbW\xfd~#\x01\xc0\xc0\x1f\xfdzF\'8\x15\xaaZ\x9et\xa4\xd4l\x86?\x06\x9595}\x0eo\xb7bpq\xc6\xd1\xc52Ts\x19b\xa7\x1e\xb5\x92\xdc\xf4g\xac\x1f*+\x80O\x15&\xdd\xa7\xaf5\xabv<\xb8E\xc9_\xb0\x00\xc0\xf0rjDf\xc7\xcc\xa1\xbd\xcdL\xb5GM\x06\xe3+I]\x0fH\xdagU_\x97\x9f\xc0{\xd1q6ID\xe5s\xd4\xfe\x95\x9bW\x92G|d\xe9P\x95G\xa5\xf4K\xef\xb9%\xa4\x8e#\x9ff\x01\xd9\x8f\xcc\x8a`\x8c\xa2\x96fP\xde\x84g\x14\x9d\xa3&\xfa\xbb"\xa9\xf3U\xa3\x08-\x12\xe6\x7f\xd7\xdc\x08\x1f\xa9\xe4\x9e\xe7\xbd[\xb6\x8fyh\xc9\xc6\xee\x06}j*;&\xce\xcc\x04eRQR\xeb\xa7\xde6E\xc68\xe0\xfe\x7f\x8dI\x12\x95\x8aFT\xce\x07$\xf6\xac\xdb\xbct=\x08\xd3J\xbf3\xd6\xca\xff\x00\x81^w\x93\x08\x01#\x19?Oj\x82B\n\xaeF\xd3\xdcz\xd6\xd0\x8aJ\xe8\xf21\x95e)\xca2\xf2\xb7\xdc\xbfO\xc8`8\x18\xc5\x0cpA\xc7\xe3Z\x9e[k\x94i\x19\xf7\x14\xaa\xc5xP?\x1aoUb"\xd4e\xcc\xd1z\xc3l\xb3\x85\x91q\x90H#\xd6\xac\xde\\\xaa\xdbI\x19q\x92\xa5p\x17\x19\xe2\xb8+\xa99\xf2\xa3\xeb\xf2\xba\x94V\x1eUf\x92\xd5\xfeI\xfeF\x1e\x08\x18\xc1\xa9\n8\x1ev\xd3\xb7w^\xd9\xafA\xb5{\x9f\x17\x05\'\x17\x14\xbc\xfe\xeb\x8d\xe0\xf2?#K\x8c\xf2()7\xd0\x96\'\x08x\xeb\xdc\xd4j\t`\xb9\xc78\xcdJZ\xb6tT\xa9zQ\x87f\xff\x00\x1b\x7f\x9123FN\xdc\xe4\xf4\xc51\x9d\x8bd\xf5\xf7\xa9Q\xbb\xb9\xd1:\xf2\x855K\xb7\xf5\xfed\xd0\xfc\xc7\xe6\xfc\xebsM\xb43B\xea1\xe6\x8f\x9a2z1\xf4\xae\\L\xb9Q\xee\xe4\xd0u\x1d\xda\xfe\xba\x16\xb5(\xa0u\x8d\x90)\xb8s\xcag\x1b\x07|\xfe=\xeb0O\xb2\x16O\x97\x0c1\xc0\xc5rSr\x94-s\xdd\x9a\x85:\x9c\xd6\xe8B\xe1Z%g\xc0\xeb\xc9\xaa\x13*\xef$\x13\x8e\xd9\xae\xea2\xd6\xc7\xce\xe6t\xa2\xe9\xa9\xad\x1b\xb1\x1e\xd2A\xa4\xdb\xc7Q\xf9\xd7M\xcf\x9e\xf6r\xb0,lN\x17\x19\xf4\xcd.\xc6S\xf3!\x06\x8ed%JV\xbbZ\x16"\x93\xcab\xe1\xb0\xd8 ~T\xddA\xcc\x8b\x1b\x92\x0bl\xc3}\x7f\xfdX\xac-\xfb\xc5/\xeb\xa9\xeb\xcai\xe0\xa7O\xb6\xbf\x8cW\xe5r\x96A$\xf2*X\xa4d\xc8\x00:\x1e\xaa{\xd7D\xa3ufx\x94k8M\xce;v\xee\x9e\xeb\xee-=\x98\x99D\xb6\xc1Jc\xe6\xf9\xb9_\xadUr\xaa\xa1\n\x9e\x0f\xde\x15\x9c*s\xabuGn+\t\x1c<\xdc\xd7\xc1%\xa3\xf9\x7fHz\xa4L\x01\x12\xed#\xae\xe1JQb\xce\xec3v\xe6\x9b\x9fN\xa4\xc3\n\x92U\x1b\xbc\x7f\x1f\xebr=\xed\x90s\x8f\xa7\x14\xed\xf2\x7fx\xfeu\\\xa8\xc9W\x93\xbd\x8bVL\x03\x1c\xaa\x16\xecH\xc8\xad;i\xda\xd6u\x98\r\xed\x9e\x9f\xd6\xb8q\x11\xbb\xb1\xf5\x99D\x92\xa0\xa5\xdb\x7f\xc4\xb7\x7fp\xb7\xac\x18G\xe5N\x13\xee\x9ew\xa8\xcf\x7fZ\xcb\x92\x19"\x80Jc>^J\x86#\xa9\xac(\xfb\xab\x95\xeez8\xa4\xa5\xefn\x92\x7f\xd7\xdcT\x0cX|\xdd\x052@r\x08\xe9]\xf1I3\xe6\xb1\x12\x95Jw\xea@\xd9Q\xd3\xad4\xa9\x00b\xb6G\x8bQ\xbd\x97A\xc1NA\x06\xac\x99H\x08\x08\'\xdc\xd4TW\xb5\x8e\xdc\x15_f\xa5\xcd\xaa\xff\x00\x82F\xc4n\xdd\x8c\x81\xebPL\xc4\xe7\x07\x8cS\x8a2\xc4\xd4\xd2\\\xbd_\xe0C\xc6i\xd9\xe3\x15\xb3<\xa8\xe8\xc7E#\xc4\xe1\xd1\x88"\xad<\x96\xf2\x8eU\xa3\xe3?(\xcf?\x8dc85.h\x9e\xa6\x17\x11\t\xd1t+=\x16\xdeW\xdf\xfc\xc6l\xb7PI\x95\x98\xf6P\xbc\xd2\x96\x85\x94\x06,1\xd0\xe34\x9c\xa4\xf5H\xb8R\xa1\x04\xe3*\x9f\x17\xf4\x88\xca(\xfb\xae\x18}1M\x18\x1dsZ\'s\x92PPv\xbe\x86\x85\x94,\xc8\\\x0e2\x07\xf3\xff\x00\x03Vf\x95Xn\x0b\x83\x8c\x0c\x1a\xe1\xab\xadM\x0f\xaf\xcb\xa3\xec\xf0\x9a\xf5\xd4B\xf21\x0c_\xe6\x8c\x8c\x03\xd7\xebW/o\x12M,\xc6\xca7y\xc3f:`\x03\xfe5\xcf({\xd1\xb7F\xbf3\xb9\xd4n\x95G.\xa9\xfe\t\xa7\xf9\x18\x84\xf1\xd7\xad\x0c\xd8LW\xa1c\xe69\xdd\x9f\xa7\xfc\x126\xc1\xc1\xa7\x02\xb8\xc6;Ut9R\x8f3o\xa8\xc1\x958\xc5+6\xd5\xcfq\xd2\x9b\xd5\x91\x07\xcb\x17\xe4F\xccH\xf9\x98\x93Q7O\xc2\xb4\x8a\xb1\xc5^\xa3\x9b\xbb\x10\x8e\x01\xf5\xa5\x15G2Z\xa0\xc6)rzR-h\xc5\x1c\x9e\xb4\xb8\xe4\x8c\xd2\xd8\xd1\'-Az\xf3N\xdb\x83\xd7\x8fZ]M\x12\xbcM\x18w\xad\xba\x84\x03q\'\'\xda\x86f_\xbd\xdcb\xb8\x9cW3\xf3>\xbe\x95G\x1a0V\xd1%\xf8\x8f\x87k\xb1\xec6\xf1\xfdi/\x19~\xcd\x14H\xd9\xdaX\x9e;\xf01\xfaP\xbe4\x8a\x9b\xbe\x1esO\xa3\xfclg\xe4\x8c\xf2)7d\xe3\xd6\xba\xac|\xc3\xa9ef\x04\xf6\xe2\x85\xe7\xad>\x84\xb7yXS\xc7O\xc2\x99\'^\xbcP\xb7\x14\xfe\x17a\x87\x90Nj3\xd2\xb5G\x9f;\x8b\xd8R\x8a,.k\xbb\xff\x00[\x05;\x07\x19\xe9H\xb5\xa8/\x19\xf5\xa3\xa8\x07\xa5\x03\x8e\xd6\x1d\x8e}\xaa`W\x01v\xe7\x1f\xadD\xaf\xd0\xec\xa1\xcbw\xcd\xb1~\'P\x81\x9d\xb2\x7f\xba*\xbc\xb2\x17l\x0e\x95\xc7\x18\xfb\xf7>\x9e\xbd~\\2\x8fV[\xd3\xd8\x12Up\x1c\x8e2~\xb9\xa3S\xb6d?\xbb\xc9U\xc7 pI\x15\nV\xadfm8)\xe5\xf7\x86\xeb\xf43\n\x9c\x1cs\xeaE0\x8fC]\xc9\x9f\'R-=@\x9anMU\x8c\x9c\xac\xf4\r\xc7\xa54\x9e1M#9M\xbb\x8d4\xd3\xd2\xa8\xe6a\x9a^)\x82c\xfa\x01\xefJ>`I5\x0c\xde=\x84\xfci\xf8R3\xcf\xe1C\x1c"\x9e\x8c\x06:\x02}\xaa\xf0\x81\xe1\xf2\xcc\x91\xb7\xef\x13p\x1e\xd9\xc7\xf4\xac\xaaJ\xc7\xa1\x83\xa2\xaaK]\x96\xff\x00z_\xa8\xc9$"C\x8e\x9d\xb1\xe9P\xee\x00\xf0ja\x1d\x0e\xccUd\xe6\xd2\xe8\xd8\xe4\x90\x06\x07\x15dL\xe7\x19vt\xe9\xeaqY\xce\x9arM\x9d\x18ld\xa3I\xc6/\xd5}\xdf\xe5\xf8\x91KnVW\x88\x90\xb2)\xe8x\x06\xa0t\x92#\x89\x10\xaf\xd4V\xb4\xe6\xa4pb\xf0\xd2\xa4\xef\xbaW\xf9\x111\xcd6\xb6G\x979]\x81\xa0\xfb\xd3!\xa1\xa4\x8ai\xe9M\x19HJx\x1d\xcfJl\x88+\x8b\x9c\x8a;T\x9b\xde\xfa\x8b\x8c\xf3K@\xd1$Q\xef\'\xe6\n\xa0d\xb1\xedV\xa1\x90m\x06L\xb6\x0f\xe9XUI\xfc\x8fc,\x94\xa1-v\x95\xd7\xdd\xa9Y\x8e*%`[\x93ZEhpV\x9f\xbc\x90\x8d&\x0f\x15f\xcac\xe6\xa8\xf7\xa5R\x17\x8b4\xc1b\xb9q1^e\xeb\xfb\x85\xbdu@\x80L\x99]\xe3\x8f3\xd35\x07\x9b\xe6\xdb\xb5\xbc\xa9\xfb\xd4_\x91\xbb\xf1\xd8\xfe\x1f\xc8W-8\xb5\x08\xf7Z\xfc\x8fo\x15R2\xc4T\xe5W\x8c\xef\x1f\xfbym\xf8\xfee\x03GA]\xa7\xcc\xf5\x1d\xc6\xc0I8&\xa3&\x9a\xdcS~\xea\x1bHj\x8ev \xa7f\x86(\xec(\xf5\xa7\x13\x9a\x96m\x1d\x80S\x95K0\x00d\x9e1AkRS\xc9\xf2\xe3\x19\x19\xea?\x8a\x96F\n6\x82=\xf1Yoo3\xd1\x8bt\xf9\x9f\xf2\xe9\xf3\xfe\xaeW/\x9e\xf5\x1f\xbdl\x91\xe5U\x9f3\xb8\x84w\x15=\x98\xcc\x99\xee\x07\x14M\xfb\xac0\x91\xe6\xc4Awh\x92l\x89\x0f\xa8\xa5I\x01?9\xe7\xfb\xde\x95\x8f-\xd5\xd1\xea\xaa\xdc\x95\\$\xf4\xbe\xbe\xbd\xc6J\xa1\\\x8e8\xf4\xa8\xc9\xc9\xab\x8b\xba\xb9\xc5^<\x93q\xf3\x06\'\xa7\xa50\xd5#\n\x9b\xd8\r5\xb8\xc8\xaaF,Jp\x19\xa6\xc9Z\x8e\xc8\xed\xd3\xde\x94\x1a\x8b\x1b\xa9!\xc0\xfd?*\xb1l\xb2J\xdbU\x80\xe3<\xd4N\xc96\xce\xcc/4\xaaF\x11Z\xb6Mp\x12\xd4\x10\x8c\x0b0\xc7\xd3\xd6\xb3\x1d\x89=jh\xfb\xde\xf1\xbek\xfb\x8bP[\xad_\xab\xff\x00\x81a\xb9\xa2\xba,xw\x14T\xb1\xb6\x0f\x1djd\x8d\xe8\xcb\x96J]\x89\xe6\x0c\xc7\xcc \xf3\xd4\xfb\xd4\\g\xadg\x1d\x15\x8fC\x11\xefUr}u\xfb\xc5\xde\x08\n\xdd\x07\xe9L\xdb\x9e\x9c\x8fj\xa5\xa1\x85G\xcf\xaa\xdck\x1c\x92i\xb5QZ\x18U\x95\xe4\xd8g\x1f\x854\xd3F-\xe88\x15\x1e\xff\x00Z7v\x1c\nM6T\\b\xb4\xdc\x05-0D\x88\xa5\x8e\x05\\\x8eh\xad\x83\x15\xf9\x99O\x04\x8e\xf5\x85k\xb5\xca\x8fc,\xe4\xa7?mSh\xff\x00\x93\xff\x00#>Y^V,\xc7$\xd3+hC\x96)\x1eN\'\x11,EYT\x97V%\x15g0S\x94\xe0\x8aL\xa8\xbdK\xca\xc5\xe2*\x0fj\xafX\xc1Z\xe8\xf5\xf12sP\x9f\x95\xbf_\xd4i\xa0\x1e\xb5v8\x94\xac\xee\x84\'\xda\x93\x00\xf1\x9c\x1fzd=Cc\x00IS\x8f\xa50\xe6\xa93)&\xb7\x12\x96\x99(ZQRh\x89\xd7\xf7}z\xd5wb\xccI\xa9\x8a\xbc\xaetV\x9b\x85%\x0e\xff\x00\xd7\xea\x00w4\x8c1Ws\x92\xda\\J)\x90\x14P\x05\xbbi\x00 \x13\x81\xde\x98\xe0\x06\xe38\xec+\x1d\xa4z\xbc\xcaxx\xf9?\xf2\x19A8\x15g*\x1aM&i\xa4d\xd8d\xf2sHY\x8f$\x93\x9fZ\x14P\xa5VOs\xff\xd9'}

and finally, weird_string is one of the weird entries of the metadata dicionary, precisely the MakerNote attribute of exif metadata:

weird_string = metadata['Exif'][37500]

Hope this clarifies better the question.

答案1

得分: 2

如果你通过删除所有非人类可读字符来“解码”TIFF/EXIF数据,你将丢失其中大部分有用的信息。你确定这就是你想要的吗?

话虽如此,解析/解码TIFF/EXIF是一场噩梦。如果你想手动完成,你需要阅读一些规范以弄清如何正确地解码它。或者你可以尝试看看pyexiv2包是否能帮到你,因为底层的Exiv2库似乎可以自动检测这些标签,甚至还提供了一个方便的在这个 Maker Note 中使用的标签列表

编辑

由于楼主已经说明他们希望从JPEG/TIF图像传输元数据到PNG图像,我在下面添加了一个使用PIL演示的代码片段:

import requests
from PIL import Image

# 从一个很棒的 GitHub 仓库获取一个标准的JPEG图像,其中包含exif示例图像
resp = requests.get(
    'https://raw.githubusercontent.com/ianare/exif-samples/master/jpg/Nikon_D70.jpg')
# 将其写入文件
with open('test.jpg', 'wb') as fp:
    fp.write(resp.content)

# 将其作为PIL图像读取
jpg = Image.open('test.jpg')
jpg_exif = jpg.getexif()

# 将图像保存为PNG
jpg.save('test.png', 'PNG', exif=jpg_exif)

# 读取新的PNG图像
png = Image.open('test.png')
png_exif = png.getexif()

# 它们真的一样吗?
if jpg_exif == png_exif:
    print('是的')
else:
    print('不是')

注意:由于EXIF元数据标签是PNG标准的一个“较新”的补充,不是每个图像查看器都会支持它(许多会忽略它)。将标签转录到标准PNG数据标签可能会更好,可以使用PIL.PngImagePlugin中的PngInfo,如此处所建议。

英文:

If you 'decode' TIFF/EXIF data by dropping all non-human readable characters, you're dropping most of the useful information from it. Are you sure this is what you want ?

That being said, parsing/decoding TIFF/EXIF is a nightmare. You'll need to do some specification reading to figure out how to decode it properly, if you want to do it by hand.
Or you could try and see if the pyexiv2 package might be able to help you, since the underlying Exiv2 library does seem to auto-detect these tags, and even has a handy list of the tags used in this Maker Note.

EDIT

As OP has stated they are looking to transfer metadata from a JPEG/TIF image to a PNG image, I'm adding a code snippet to demo this unsing PIL below:

import requests
from PIL import Image

# get a standard JPEG image from an awesome GitHub repo with exif sample images
resp = requests.get(
    'https://raw.githubusercontent.com/ianare/exif-samples/master/jpg/Nikon_D70.jpg')
# write it t a file
with open('test.jpg', 'wb') as fp:
    fp.write(resp.content)

# read it in as a PIL image
jpg = Image.open('test.jpg')
jpg_exif = jpg.getexif()

# save the image as a PNG
jpg.save('test.png', 'PNG', exif=jpg_exif)

# read the new PNG
png = Image.open('test.png')
png_exif = png.getexif()

# are they really the same ?
if jpg_exif == png_exif:
    print('Yay')
else:
    print('Nay')

Note : as the EXIF metadata tag is a 'recent' addition to the PNG standard, not every image viewer will support it (many will just ignore it). It might be better to transcribe the tags to standard PNG data tags, using PngInfo in PIL.PngImagePlugin, as suggested here.

答案2

得分: 0

你可以使用 str.maketrans 创建一个字典来替换所需的空格,然后使用 string.translate

另外,你可以尝试使用 string.printable(导入 string 模块),然后迭代你的字符串的每个字符,检查它是否在 string.printable 中 -

decode_string = "".join(ch if ch in string.printable else '' for ch in weird_string)
decode_string = decode_string.translate(str.maketrans({}))

你需要创建自己所需的 maketrans 字典

你可以参考 string.printablestr.maketrans / translate

英文:

You can use str.maketrans to create a dictionary to replace the required whitespaces and then use string.translate.

And also you can try using string.printable (import string), then iterate over each character of your string and check if it is in string.printable -

decode_string = "".join(ch if ch in string.printable else '' for ch in weird_string)
decode_string = decode_string.translate(str.maketrans({}))

You have to create your own desired maketrans dictionary.

You can refer to string.printable and str.maketrans / translate

huangapple
  • 本文由 发表于 2023年5月10日 19:05:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76217649.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定