Domanda

I have a base64 string that I've acquired from KineticJS toDataURL(). It's a valid base64 string. This fiddle shows that it is: http://jsfiddle.net/FakRe/

My Problem: I'm sending this dataURI up to my server, decoding using python, and saving on the server. However, I'm getting a padding error. Here's my code:

def base64_to_file(self, image_data, image_name):

    extension = re.search('data\:image\/(\w+)\;', image_data)
    if extension:
        ext = extension.group(1)
        image_name = '{0}.{1}'.format(image_name, ext)
    else:
        # it's not in a format we understand
        return None

    image_data = image_data + '=' #fix incorrect padding
    image_path = os.path.join('/my/image/path/', image_name)
    image_file = open(image_path, 'w+')
    image_file.write(image_data.decode('base64'))
    image_file.close()
    return image_file

I can get around this padding error by doing this at the top of my function:

image_data = image_data + '=' #fixes incorrect padding

After I add the arbitrary padding, it decodes successfully and writes to the filesystem. However, whenever I try and view the image, it doesn't render, and gives me the 'broken image' icon. No 404, just a broken image. What gives? Any help would be greatly appreciated. I've already spent way too much time on this as it is.

Steps to recreate (May be pedantic but I'll try and help)

  • Grab the base64 string from the JSFiddle
  • Save it to a text file
  • Open up the file in python, read in the data, save to variable
  • Change '/path/to/my/image' in the function to anywhere on your machine
  • Pass in your encoded text variable into the function with an name
  • See the output

Again, any help would be awesome. Thanks.

È stato utile?

Soluzione

If you need to add padding, you have the wrong string. Do make sure you are parsing the data URI correctly; the data:image/png;base64, section is metadata about the encoded value, only the part after the comma is the actual Base64 value.

The actual data portion is 223548 characters long:

>>> len(image_data)
223548
>>> import hashlib
>>> hashlib.md5(image_data).hexdigest()
'03918c3508fef1286af8784dc65f23ff'

If your URI still includes the data: prefix, do parse that out:

from urllib import unquote

if image_data.startswith('data:'):
    params, data = image_data.split(',', 1)
    params = params[5:] or 'text/plain;charset=US-ASCII'
    params = params.split(';')
    if not '=' in params[0] and '/' in params[0]:
        mimetype = params.pop(0)
    else:
        mimetype = 'text/plain'
    if 'base64' in params:
        # handle base64 parameters first
        data = data.decode('base64')
    for param in params:
        if param.startswith('charset='):
            # handle characterset parameter
            data = unquote(data).decode(param.split('=', 1)[-1])

This then lets you make some more informed decisions about what extension to use for image URLs, for example, as you now have the mimetype parsed out as well.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top