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
Delete .Ds_Store Files in Current Folder and All Subfolders from Command Line on MAC
How to Enable Scrolling in Tmux Panels with Mouse Wheel
Shell Script to Count Files, Then Remove Oldest Files
New to Linux Kernel/Driver Development
How to Pipe Output from Grep to Cp
How to Check That Two Folders Are the Same in Linux
Elasticsearch Can't Write to Log Files
How to Remove Jenkins Completely from Linux
How to Get the Current Network Interface Throughput Statistics on Linux/Unix
How to Create a Script to Save and Restore Permissions
How I Should Run My Golang Process in Background
How to Determine the Current Ip from a Known MAC Address
Shared Libraries: Windows VS Linux Method