A simple script to upload images that are blog-friendly
I am currently using GCS for the images in my blog, and I usually never resized images before uploading them to the bucket. I always thought that everything would be handled for me once I upload images to the bucket, thinking that there was already a built-in CDN on top of GCS.
This resulted in a couple of my blog posts loading large images that take quite some time to fully load.
I’ll manually set up Google CDN for my blog, but apart from that, I’ll make it a habit to resize my images down to a maximum of 1,200 pixels, either width or height, preserving the aspect ratio.
Resizing the image
I did some research on a couple of ways to resize images (aside: I created a tool for resizing images a few years back, but that was during the time I was using Linux as my daily driver), and found out that MacOS already had one built-in called as
sips, with the usage as:
sips -Z 1200 $file -o $output # example sips -Z 1200 ~/Pictures/a-huge-image.jpeg -o ~/Pictures/blog/a-huge-image.jpeg
It just works without much fanfare, so I’ll stick to this for a while until I find a reason not to. An alternative that I’d like to explore sometime in the future is pngquant, which optimizes the image somehow.
Uploading to GCS
gcloud command to upload files to my google cloud storage bucket with the following command:
gcloud storage cp ~/Pictures/blog/$file gs://$bucket
It’s pretty straightforward too.
Packaging it all up
But to take it a step further, saving me extra keypresses moving forward, I decided to wrap these all up in a fish function. The idea would be:
Creating fish functions was straightforward as I’ve done a couple already before. What was new was figuring out how to:
- get the named arguments/flags
- verify if the variable exists
- use a fallback value if the variable is empty
To get values passed in flags, we could use
argparse. I only wanted to support two flags: output and input.
argparse 'i/image'= 'o/output'= -- $argv
To access those flags, we use a predefined
$_flag_ local variable, prefixed with the flag name.
echo $_flag_i # for the i/image flag echo $_flag_o # for the o/output flag
Now, what I wanted is that the input should be required, while the output would be optional, falling back to the input value if it does not exist. Unfortunately, I haven’t yet figured out how to define default values for these flags, so I ended up using if statements:
if test -z $_flag_i echo "Missing -i, please specify which image to share" return 1 end # set output default value as the -o flag value set -l output $_flag_o # if output (which uses -o flag value) is empty, then we use -i flag's value if test -z "$output" set output $_flag_i end
Next, I use the two commands I shared earlier: resize -> upload:
# resize image and save to ~/Pictures/blog/ sips -Z 1200 $_flag_i -o ~/Pictures/blog/$output # we upload to gcp gcloud storage cp ~/Pictures/blog/$output gs://$bucket
Lastly, we copy it to the clipboard:
echo "https://storage.googleapis.com/$bucket/$output" | pbcopy
The link is now in your clipboard and ready to be pasted to the blog post.
function shareimg argparse 'i/image'= 'o/output'= -- $argv if test -z $_flag_i echo "Missing -i, please specify which image to share" return 1 end set -l output $_flag_o if test -z "$output" set output $_flag_i end # resize image and save to ~/Pictures/blog/ sips -Z 1200 $_flag_i -o ~/Pictures/blog/$output # we upload to gcp gcloud storage cp ~/Pictures/blog/$output gs://$bucket # copy to clipboard echo "https://storage.googleapis.com/$bucket/$output" | pbcopy end
Here’s some demonstration of it’s actual usage:
Aaand, this is the image that I uploaded using the script :)