I want to base-64 encode a PNG file, to include it in a data:url in my stylesheet. How can I do that?
I’m on a Mac, so something on the Unix command line would work great. A Python-based solution would also be grand.
I want to base-64 encode a PNG file, to include it in a data:url in my stylesheet. How can I do that?
I’m on a Mac, so something on the Unix command line would work great. A Python-based solution would also be grand.
This should do it in Python:
import base64
binary_fc = open(filepath, 'rb').read() # fc aka file_content
base64_utf8_str = base64.b64encode(binary_fc).decode('utf-8')
ext = filepath.split('.')[-1]
dataurl = f'data:image/{ext};base64,{base64_utf8_str}'
Thanks to @cnst comment, we need the prefix data:image/{ext};base64,
Thanks to @ramazanpolat answer, we need the decode('utf-8')
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAP0lEQVQY02P4/fv3f1z4ypUrcDYD\niIOMkQEyH6tCdDEQZkDWRZKJ6CajKEQ3BV0Mr4noGhiw6SbJjVhNJEYhAKztct58fLlaAAAAAElF\nTkSuQmCC\n
. In my CSS file, it looks like background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAP0lEQVQY02P4/fv3f1z4ypUrcDYD\niIOMkQEyH6tCdDEQZkDWRZKJ6CajKEQ3BV0Mr4noGhiw6SbJjVhNJEYhAKztct58fLlaAAAAAElF\nTkSuQmCC\n);
. –
Yandell \n
s definitely look out of place in there. –
Largo "data:image/png;base64,"
-- the code above alone doesn't do that. –
Mirabel .encode("base64")
and it seemed to work but the output was bigger than I thought. I investigated and noticed that it was putting unnecessary newline characters in the output. Also, the urllib.quote
call was URL-encoding the newlines, which was making them even bigger. I fixed this answer so it does not add unnecessary newlines. –
Handwork In python3, base64.b64encode
returns a bytes
instance, so it's necessary to call decode
to get a str
, if you are working with unicode text.
# Image data from [Wikipedia][1]
>>>image_data = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x05\x00\x00\x00\x05\x08\x06\x00\x00\x00\x8do&\xe5\x00\x00\x00\x1cIDAT\x08\xd7c\xf8\xff\xff?\xc3\x7f\x06 \x05\xc3 \x12\x84\xd01\xf1\x82X\xcd\x04\x00\x0e\xf55\xcb\xd1\x8e\x0e\x1f\x00\x00\x00\x00IEND\xaeB`\x82'
# String representation of bytes object includes leading "b" and quotes,
# making the uri invalid.
>>> encoded = base64.b64encode(image_data) # Creates a bytes object
>>> 'data:image/png;base64,{}'.format(encoded)
"data:image/png;base64,b'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='"
# Calling .decode() gets us the right representation
>>> encoded = base64.b64encode(image_data).decode('ascii')
>>> 'data:image/png;base64,{}'.format(encoded)
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
If you are working with bytes
directly, you can use the output of base64.b64encode
without further decoding.
>>> encoded = base64.b64encode(image_data)
>>> b'data:image/png;base64,' + encoded
b'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
import base64
def image_to_data_url(filename):
ext = filename.split('.')[-1]
prefix = f'data:image/{ext};base64,'
with open(filename, 'rb') as f:
img = f.read()
return prefix + base64.b64encode(img).decode('utf-8')
This should do it in Unix:
b64encode filename.png X | sed '1d;$d' | tr -d '\n' > b64encoded.png
The encoded image produced by b64encode
includes a header and footer and no line longer than 76 characters. This format is typical in SMTP communications.
To make the encoded image embeddable in HTML/CSS, the sed
and tr
commands remove the header/footer (first & last lines) and all newlines, respectively.
Then just simply use the long encoded string in HTML
<img src="data:image/png;base64,ENCODED_PNG">
or in CSS
url(data:image/png;base64,ENCODED_PNG)
b64encode
included. In that case, you'd want to use uuencode -m
, which is a synonym. –
Klarrisa b64encode is not installed by default in some distros (@Clint Pachl's answer), but python is.
So, just use:
python -mbase64 image.jpeg | tr -d '\n' > b64encoded.txt
In order to get base64 encoded image from the command line.
The remaining steps were already answered by @Clint Pachl (https://mcmap.net/q/269521/-how-do-you-base-64-encode-a-png-image-for-use-in-a-data-uri-in-a-css-file)
This should work in Python3:
from io import BytesIO
import requests, base64
def encode_image(image_url):
buffered = BytesIO(requests.get(image_url).content)
image_base64 = base64.b64encode(buffered.getvalue())
return b'data:image/png;base64,'+image_base64
Call decode to get str as in python3 base64.b64encode returns a bytes instance.
And just for the record, if you want to do it in Node.js instead:
const fs = require('fs');
const base64encodedString = fs.readFileSync('image_file.jpg', {encoding:'base64'});
© 2022 - 2024 — McMap. All rights reserved.