How to Base64 Encode Image in Linux Bash/Shell

How to base64 encode image in linux bash / shell

You need to use cat to get the contents of the file named 'DSC_0251.JPG', rather than the filename itself.

test="$(cat DSC_0251.JPG | base64)"

However, base64 can read from the file itself:

test=$( base64 DSC_0251.JPG )

How to use base64 encoded image as an argument?

Instead of accepting it as an argument, I would suggest you read it from standard in instead.

$ base64 someImage.jpg | ./myProgram

If this program is a shell script, you can save standard in into a variable with something like this:

#!/bin/sh

MY_BASE64_IMAGE_INPUT=$(cat -)
# do something with that info
echo $MY_BASE64_IMAGE_INPUT

BASH Base64 Encode script not encoding right

Ok, I'll add this as an answer for the records's sake:

Problem was in having /bin/sh as a default interpreter shell, which I assume, in this case was dash.

Test script used:

#!/bin/bash
user=myuser
pass=mypass
host=myhost.com

auth=$(echo -ne "\0$user@$host\0$pass" | base64);

echo $auth

Results:

[51][00:33:22] vlazarenko@alluminium (~/tests) > echo -ne "\0myuser@myhost.com\0mypass" | base64 
AG15dXNlckBteWhvc3QuY29tAG15cGFzcw==

[52][00:33:42] vlazarenko@alluminium (~/tests) > bash base64.sh
AG15dXNlckBteWhvc3QuY29tAG15cGFzcw==

[53][00:33:46] vlazarenko@alluminium (~/tests) > dash base64.sh
LW5lIAo=

Base64 encoding different in script

By using a #!/bin/sh shebang, you're most likely asking bash (or whichever shell is behind /bin/sh which nowadays is almost always a link to another shell) to execute your script in a POSIX-compliant mode :

If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well.

Your problem is that POSIX echo does not define a -n flag, so it is understood in your command as just another parameter to display in your output. Indeed, LW4gdXNlcjpwYXNzd29yZAo= is the base64 encoding of -n user:password.

You should use printf instead of echo, whose behaviour is much better defined and varies less between implementations.

Moreover, unless you need your script to be portable and possibly run on platforms where bash isn't available, I suggest you use a #!/usr/bin/env bash shebang instead of your #!/bin/sh one so you get to enjoy the bash goodies.

How do I convert a base64 image?

Updated Answer - now that I understand it better myself :-)

Basically, you can base64 encode an image using openssl like this:

openssl enc -base64 -in image.png > image.b64

However, if you want ImageMagick to be able to read it, you need a small header at the start, to tell ImageMagick what follows. The header must contain:

data:image/png;base64,

followed by your base64 encoded data generated using the openssl command above. So, depending on what features your shell has, you could do it like this with a compound statement in bash:

{ echo "data:image/png;base64,"; openssl enc -base64 -in input.png; } > image.b64

or like this in Windows:

echo data:image/png;base64,         > image.b64
openssl enc -base64 -in image.png >> image.b64

Once you have the image in that format, you can then proceed to process it with ImageMagick like this:

convert inline:image.b64 result.png

For those who use this in css, add -A flag to output in one line

openssl enc -base64 -A -in image.png > image.b64

Original Answer

After MUCH experimenting, I can do it!!! :-)

Start with Eric's (@emcconville) setup:

# For example
convert rose: rose.png
# Create base64 file
openssl enc -base64 -in rose.png -out rose.txt

and now add this mess as the last line:

{ echo "data:image/png;base64,"; cat rose.txt; } | convert inline:- out.jpg

I guess the data:image/png;base64, is not present in the base64 file created by openssl so I create a compound statement that sends that plus the file to stdin of ImageMagick.

Base64 encoding line by line faster way

It might help a little to open the output file only once:

while IFS= read -r line; do echo -n $line | base64; done < inputfile.txt > outputfile.txt

bash is not a good choice here, however, for two reasons: iterating over a file is slow to begin with, and you are starting a new process for each line. A better idea is to use a language that has a library for computing base64 values, so that everything is handled in one process. An example using Perl

perl -MMIME::Base64 -ne 'print encode_base64($_)' inputfile.txt > outputfile.txt

Linux Base64 encoded value produces spaces

base64(1) by default wraps lines at column 76. What you're seeing is the whitespace of those newlines.

If you add -w0 (disable wrapping altogether) to the base64 options, it will spit out its result without any wrapping.

Do man base64 for further information.



Related Topics



Leave a reply



Submit