将图像数据字符串(str)转换为字节。

时间:2021-06-06 20:14:06

inputFile gets the image data from a image file input <input type="file"> and converts the data into a string (str) to be used in sessions. createView converts the image data string back into image data (bytes) so it can be saved.

inputFile从图像文件输入 <输入类型="文件"> 获取图像数据,并将数据转换为一个字符串(str),用于会话。createView将图像数据字符串转换为图像数据(字节),这样就可以保存它。

However when trying to convert the image data string back into image data bytes:

然而,当试图将图像数据字符串转换为图像数据字节时:

session_data = request.session.get('img_data')
data = base64.b64encode(bytes(session_data, 'utf-8'))
data2 = base64.decodestring(data)

It changes the original image data, img_data = request.FILES.get('image').read() witch raises an error when trying to save the image to a ImageField:

它改变了原始图像数据,img_data = request.FILES.get('image').read()在试图将图像保存到ImageField时引发了一个错误:

cannot identify image file <django.core.files.temp.TemporaryFile object at 0x0074B110>

so my question is how do i convert the image data string session_data = request.session.get('img_data') back into the original image data (bytes) without altering the data.

因此,我的问题是如何转换图像数据字符串session_data = request.session.get('img_data')返回原始图像数据(字节)而不改变数据。

And i know i could have saved the image using one view that would make it a lot simpler, but createView needs to use this image data in multiple places / forms. i tried doing it this way but i could only use the image data in one form.

我知道我可以用一个视图来保存图像,这样做会简单很多,但是createView需要在多个位置/表单中使用这个图像数据。我试着这样做,但我只能用一种形式的图像数据。

import base64
def inputFile(request):

    form = InputFile(request.POST or None, request.FILES or None)
    if form.is_valid():
        img_data = request.FILES.get('image').read()
        request.session['img_data'] = str(img_data)

        return redirect('picxs:create')

def createView(request):
    session_data = request.session.get('img_data')
    data = base64.b64encode(bytes(session_data, 'utf-8'))
    data2 = base64.decodestring(data)

    form_create = CreateForm(request.POST or None, request.FILES or None)
    if form_create.is_valid():

        # saves the image
        img_temp = NamedTemporaryFile()
        img_temp.write(data2)
        img_temp.flush()

        img = Image.open(img_temp)
        img_filename = img.format
        img.close()

Image data before encode / decode:

编码/解码前的图像数据:

b'GIF89ad\x00d\x00\xe6\x00\x00\x00\x18\x1e\xa5\xfa\xf4=r]\xf4#\x14\xa8\x0f\t\xba\x84Jm\x0e\x100\xa1\xea\x1b9?\xab\xe2\xe7a\xa5\x82\\\x0e\x0c\xd2\xb9\xa6\xff\xff\xd9\x7f7\x1
dG\x07\x0e\x94}J\xe1 \x12h\xc2\xd7I3G\xd3\x17\x08\x94\x9fv\x94\n\x07\xfe1\x183\x00\x00\xe8\xf6\xcb\xf7\xef\xde\xbf\'\x1c\xba\x9d\x83(\\N\x83\x08\x12>r\x8dH>,\xff\xff\xff\xf
4\'\x1a\x0b+/g\xa8\xba\xb0!\x1b\xef\xd6\xb8JTN\xdc\xe6\xd9[) \x97|m\x92\xa9\xb2q]V\xee\xff\xff\xd7\xfe\xe42JSC\xaa\xfdn"\x19\xad\xaaX$\x0f\x12.5(\x86%"\xf8\xc5\x98&\\\x8aLm
\x84\x9e\xea\xe0\xfe2 e^I\xc5\xce\xbd\xd8\xe7\xe4\xff(\x19_us\xc1\x1b\x10G\x1d\x1fZ\x1b"G\x93\xb0+;^\xef\xfe\xf4\xd4&\x17F\xab\xf7\xc5\xf0\xe6\x98"\x1b\xb55!\xff\xff\xf13ff
\xcc\xff\xff\xb8\xb0\x8c}\x8a\x8a{P=\xe0*\x1b\xd0\xa4|2\x1e!\x84q]BIQ\x87\x17\x19\xc0 \x19\x1a\x18\x11x\xd8\xc7Ja\x82Y\x1b\x1b_D-p)1-:$H\xa5\xe9\xff)\x10\xea\xe4\xa9\x92\x9
1\x8c\xdc\xff\xff\xc0\xd6\xa2\x94dSn\x18\x1d%\x1c \xa4\x85d\xb2\x07\nE\xb9\xff$Fp\xc1\xf7\xf7\xff;$\xabd77\x1a\x1a7\x8f\x868uo\x08Tv\xff\xff\xe8\xf1\xff\xe4B[o\x8c\xc5\xb5}
P+\xa9\x1b\x19\x8c\xca\xd6f\x83\x86C\x13\x1a\xc8\xf1\xc051A\x8c\xe6\xfb\x11 )!\xf9\x04\x04\x14\x00\xff\x00,\x00\x00\x00\x00d\x00d\x00\x00\x07\xff\x80!\x82\x83\x84\x85\x86\x
87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\x
b2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xa0ss\xc6\x99\r6\x05n\x05R&\xca\x95&\x05;k77U\\R\xd3\x92\x19\xd7\x07\x070\xe4r{\x0c\xde\x902\
x08\x07j\xee\xee\x07#h\xe9\x8et kj0G\xfbGj\x08)\xf4\x1a\xb9\xf0\x82\x8f\x1c\xbf#\x08\xb6,\t\xb8h\x8c\x17"\xf9\x0c\xee\x1b\xb1\x83a"\r\x82@\x10!\xc7Q\xcd\x97?b\x04\x99\xc0hQ
\x10\n1\x1c\xc2\xec \xf2\xe5\x9d\xbb\x0fg\x9cd@\x03\x05EIA-\x14\xfc\x01q\xe6\xcf\x8b:\x1f>\xc4\xa9\x83\x00\x00\x08\x10XB\x1aZ\x92\x0cX\x03\x13#\t\xcd\xa9@\xc3L\r3X\x85\x08\
xd9\x12\xa3k\x8d)\x7f*4(\x94A\x06\x04)\r\xe6d\x88\x9ak\x0e\x84\xaee\xffHf\x80\xe0`\x83\x8e\xbbw\xa3\xe8\xc5\xabcC\x8d\x14;84-Be\x81\x01!; p\x89\x11\xb7\x96Z\rK\xc8\xa4HC\x0
0\x83\x93\x10\x19~,0r\xa1\xb3\xe7\xcf\x9dEl\xf0a\xc4\xcc\x1e4c]\x80\xa0\xa0\xa3\x06\x80\x18@\x08<@7k\xae\x03(,:$\xb9\x8bAE\x03*f"\xf8\xd0\xeb\xa3\xb8q\x1fWD\x0c\x8f!\xa2s\x
12!T4\x8c\x11\x10\xa1o\x8a(:\xa2\xbc\xa1-\xcb\x8e\x01\n\x1bb\x08\x89rAG\x97\'\x15\xb6Dp>\x9at\x89\xe2F\xce\xbc\x17Q\xa2y\xe7\r\x0f\xa8dP\x90\xe4\x82\x08\xce\x17\xc4\xf0\x87
\x13\x0bu\xc7\x1ch\x17@\xf1\x03\x08@x\xb6A{5\x9c\xa1\x9c\x11S\x94\x80`g@\xec\xb1\x83\x005\x1c\'B\rBt\xc1\xc1,v\x8cP\x03h"t1B\x0c\xc7\xe9\xa5\\\x12A\x88\x00\x06\x18F\xd8wa\t
A\xd4\x10\xc5q\xc6y\xb0C\x81\xaf8qG\x0cJ \x18\x03\x16W\xcch\xdc\xff\x8e>\x0c`\xc4\x8cPB\xa9\x9c\x0fQF!\x82\x8cQ\x92\xf6\x80\n\xb1 \xe1E\x1a\xa0\x19\xd7\x95\x94~\x191@\x94h\
x82\x11\xc5\x06\x03\xb4\x99&\x9aFl1\x02\x12]v\x90\x06\x8f\xc6\xbd\x91\x04\x94\x03\x1c\x99\xe4\x9bPF\xb1\xc5\x16I<\t\xa8gxL@\x87,YT\xb1\xc5\x066^\x10\xc5\x19\x7f\xceh\xc4\x1
b%\x00\n\xa5\x0fA\x04q\xc5\x99pZ\x91D\x04`\\\x10\xc1\x1e<\xc82\x06\x1co\x90\')\x1eWX\x11#\x8fcjzA|V\xbc\t\xc4\x04\x1f\x0cq\x02\x05\x03\xa4\xd1\x87M\xb1,!\x00\x01x\x19@D\x1d
\x7ft\xc8#\x8e\xa4j\x9a\x04\x00{\xa6i\xc0\x0f-\x8c!\x01\x0b]L\xb0\xc2,E\xc4A@g\x04\xf4\x91G\x00\xba!\x18\x85\x10\xd5\xa6\xd9\x99\x19\x00T\xba\xe9\x02,\xe0\xc4F\x02\t\xb4@\x
0b\tf\xa4aA\x1f\xdf\x86 \xee\x85I\xbc\x01\x04\xa0"Lq\xc6\x00\xc6\xcd\x0bBS\xb8\xb01\x84\x16z\xe4\xa1\xaf\xff\xc0\x1e\xe0\xd9d\xa7\xa0\xa2y\x05\x00[\x14g-\r$\xe5\xd2D\x13\x1
7\x0b\x02\x07\x06\x80^\xa1g\x9a\x03l\x01\xc0{i\xea`\xc5\x04@\xfe\xa2\x00\x16\x9a^\xb1\x85\x19\x86F\x80\xa3\x9e<~f@\xbd\xc2\xd8\x01@\x83-\x0fj\xc6\x16o\x9c\xb1\x85\x11xz&\xc
2\x03J\x05\xd3\x84\x1c\x06\xf0\x88\xa6\xd0VtU\xdf\x85\x9e\x95\xdb\xc3/(0\xe0\x844Y\x9cA\x81\x92\x1a\x17M\xf6\x05\x03,\x905/d\xec\x10\xc3\x16)p\x80D\x1c{t\x0c\x06_q\x1f\xf7\
x99\x05\x13\x10\xcb\x0b\x1f;\xe0!B\x14xX\xa1\x82\x02#\\q\x9c\x0emd\xae\xb1\xbb\x17\x00\x11D\xc0\xbd(`@\xe6m\xe8`D\x174\xc4\x90\x1c\x96\x17\x90\xee\x99\xa6\xa5\x02\xf1\xc0\x
13)\xefR\x84\x00xd\x8eW\tI\\\xf98\x93>\xe8\xf0\x19\xec\x14\xa4\xa0G\x11\xbf\xb8\xc0\x04\x10\xa5\xf3\xa5\x83q\x1b\x08\x11C\x1a\x1d\xbf\x0e3\x01A\xd0\x0eL\x0bpx\xe0\xbc\xf35\
xe00\x84\xff61X@\x00\x01@\x08\xc7\xe3\x15B\xbc@B\xed\xbeH0Eu|\x91\x8eG\x15.\xb4\xc0\x86\x1f$|P\x07\x11D\x00\x01\x80B\x13\x84\x17\xb0\x81\x18M\x80C\x91\xea\x97\xb9\x07\xfc\x
a0\x10M`\xc3\xfe\x86\xd0.0\xf8`\x0b}`\x00\xc4\x82\x91\x80\x1f\x10\xa0T\xe5\xc1\x0b\x06\xeeV\x88\x1c\xf4\xe1`J\xda\x80\x19R\x80\x86\x92\x05#\x0fq\xb0\x02\xa9\xf0\x12\x81\x19
\xa4\xca\x10\r\xc8\x80\x13F\x80\x07\x1e\x89\xc0\n3\x18\x111\x12\xf0\x81\t\x10 \x02\x03\xa0\x80\x01\xf4\x00\xbf\x10\x84A\x06wPB\t\x80W\x9c\xbbl\xc9\x18M\x90\x00\x0eNp\x82*<a
\x0c\x86 \xc3\x1d\x92@\x01\x1f\xcc\rk\xd3`C\x0er\x90\x00\xe4\x15\x82\x0e\x02\xf0\x80\x08\xeeB6\x02\xfcAq7qA\x15(\xd0\xbc\x0bE\xe0\x01z\xb8\t!\x90\xc0\x04\n\xcc\x8d\x02[\xf8
\x81\x1b\x05\x19\x82\x16\x90`\x02oCP\x1a\x82\xa0\x07\x170\x92\x10Y\xac\x83\x19\x08@\x81N\x12\xc0F\x0cD \x01\x18/I\x88\x16$\xa0\x7fu\xa8B\x15p\xb0\x02$4\x91\x94\x8dlB\x00r\x
80\x84Q\xc2\xf2\x96\xb8\xcc\xa5.w\xc9\xcb^\xfa\xf2\x97\xc0\x0c\xa60\x87I\xccb\x1a\xf3\x98\xc8L\xa62\x97\xc9\xccf:\xf3\x99\x8a\x08\x04\x00;'

image data after converting to base64

转换到base64后的图像数据。

b'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'

1 个解决方案

#1


1  

The problem is that calling str on a bytes instance, which you do when you write to the session, doesn't result in a string that can be converted back to the original bytes1, it produces string version of the bytes instance's repr:

问题是,在一个字节实例上调用str,当您写入会话时,它不会导致一个字符串可以被转换回原来的bytes1,它会生成字节实例的repr的字符串版本:

>>> foo = b'abc'
>>> bar = str(foo)
>>> bar
"b'abc'"

>>> baz = bytes(bar, 'utf-8')
>>> baz == foo
False
>>> baz
b"b'abc'"

>>> bar == repr(foo)
True

To convert the image data to a json-serializable string, base64-encode img_data to get a bytestring of ascii characters then decode the bytestring to str and write that to the session; decode from base64 to get the original bytes.

为了将图像数据转换为json-serializable字符串,base64编码的img_data获得一个字节字符串,然后将bytestring解码为str并将其写入会话;从base64解码以获得原始字节。

>>> session_data = base64.b64encode(img_data).decode()
>>> base64.b64decode(session_data) == img_data
True

1In fact the conversion can be reversed by calling eval on the string, but this is a security risk and should never be done. Using ast.literal_eval would be safe, but decoding from base64 is much faster.

实际上,通过调用eval在字符串上可以逆转转换,但这是安全风险,不应该这样做。使用ast.literal_eval是安全的,但是从base64解码的速度要快得多。

#1


1  

The problem is that calling str on a bytes instance, which you do when you write to the session, doesn't result in a string that can be converted back to the original bytes1, it produces string version of the bytes instance's repr:

问题是,在一个字节实例上调用str,当您写入会话时,它不会导致一个字符串可以被转换回原来的bytes1,它会生成字节实例的repr的字符串版本:

>>> foo = b'abc'
>>> bar = str(foo)
>>> bar
"b'abc'"

>>> baz = bytes(bar, 'utf-8')
>>> baz == foo
False
>>> baz
b"b'abc'"

>>> bar == repr(foo)
True

To convert the image data to a json-serializable string, base64-encode img_data to get a bytestring of ascii characters then decode the bytestring to str and write that to the session; decode from base64 to get the original bytes.

为了将图像数据转换为json-serializable字符串,base64编码的img_data获得一个字节字符串,然后将bytestring解码为str并将其写入会话;从base64解码以获得原始字节。

>>> session_data = base64.b64encode(img_data).decode()
>>> base64.b64decode(session_data) == img_data
True

1In fact the conversion can be reversed by calling eval on the string, but this is a security risk and should never be done. Using ast.literal_eval would be safe, but decoding from base64 is much faster.

实际上,通过调用eval在字符串上可以逆转转换,但这是安全风险,不应该这样做。使用ast.literal_eval是安全的,但是从base64解码的速度要快得多。