UPDATE: 22nd November, 2019 Added version that uses 'mpv'. Details at bottom of blog-post
Personal notes on seven programs that provide some ability to display images in a POSIX terminal interface [bash environment specifically]. This is in no way an exhaustive list, nor does it claim to highlight the best applications available. These are merely notes made recently while investigating a solution for such a task.
High above the Olympic village, dastardly Vova Putin flies upon his diabolical meldonium powered Dope Rocket™, sprinkling athletes with his dope juice. - February 26, 2018
The 'Games' this year seemed a bit dull and uninspiring. Perhaps that is just my own perception though. Perhaps there weren't enough Time magazine covers with barbed wire Olympic rings, stories about weird toilets, warnings of 'Black Widows' blowing up planes with toothpaste bombs, or comparisons to the 1936 Berlin Games with premonitions of homosexuals being exterminated, to heighten my attention and excitement. The only bit of drama came from the ever persistent 'Russian Doping Scandal' story.
'Doping' seems to mean a lot of things these days. If you rub the wrong boil ointment on your arse, it's classed as 'doping'. It doesn't mean unusual amounts of asthma medication, or Japanese figure skaters winning gold medals 'doped' up on pain killers though.* Sport is filled with the dopes: the athletes, the officials, the journalists.¹
I liked the pre-recorded 'drones' section of the opening ceremony. Although what I missed was the outrage and accusations of 'State media censorship' when they switched to it, like there was when a back-up recording was used in the 2014 Sochi Games after there was a malfunction in the most important image of the Games: The appearance of the Olympic rings. That meant there was no similar 'feel-good' moment in the closing ceremony, like in Sochi when the organisers mocked themselves over the malfunctioning Olympic rings and the West collectively gasped: 'oh my goodness, Russians must be human too?'.
I thought it very nice that the USA sent vice-president Pence to the games, to sit next to the DPRK representative. The DPRK; the most sanctioned country in the world; the country, we're told, who might blow up the planet at any moment! The USA were unable to send anyone to Sochi though, because "Russia".²
There was no snow in the Republic of Korea, so they manufactured it all. Again [like a broken record]: Four years ago, we heard complaint, ridicule, and mockery, about how the Sochi snow wasn't 'real snow' and how embarrassing it was to have to put it there artificially.³
Alpine skiing: Not bad. Personally, it was a bit of a flop due the German women's team not doing so well. More importantly, their racesuit was the worst I've ever seen (and we thought the 'go faster stripes' of Sochi were bad!). Highlights: Poor American performance; Super-G race where Ester Ledecká pipped Anna [Fenninger] Veith for the gold medal.
All in all, a lackluster Games; very utilitarian. Russia didn't exist; America and China results were woeful.
¹ I find the whole topic of "drug" use in sport difficult to resolve. Humans are electro-chemical machines, we exist in, and are, chemistry. We can't be measured like the length of a ski, or number of bullets in the magazine of a biathlon rifle. "Drugs" seem like an intangible thing to track without some level of hypocrisy. As an example, there's already a potent stimulant that's classed as uncontrollable: Trimethylxanthine, aka, caffeine. Maybe its legal status is helped by the fact that all these sporting events are sponsored by caffeinated beverages.
² "the 1980's are now calling to ask for their foreign policy back" - Barack Obama.
³ How much energy was used to generate this snow? We'll be lambasted with Global Warming warnings, and how traditionally snowy areas are now snowless due to rising temperatures, meanwhile we'll burn up the planet to put snow back into these places. It seems like a downward spiral.
⁴ How uninspired do you have to be to write "Germany" in faux Hangul script and stick it down the front of a racesuit 4 times. This is truly their worst. The blank one in 2010 was sublime in comparison. pic.twitter.com/rwuG1a8yOK
A demonstration of an image masking procedure using ImageMagick, presented as a Bash script. The concept is to obfuscate an image such that it becomes meaningless to the observer (human or machine) but that can be easily recovered using the correct steps. Since it is based on visual alterations rather than altering the file itself, it does not suffer from informational corruption if the image is resaved and/or resized.
In its current form, it's deemed as weakly cryptographic. It could be reversed via brute force study of patterns and edges (as was seen with VideoCrypt, the analogue video encryption used with satellite television¹). Image masking is an old idea that may still have some value today. Further notes are found within the bash script below.
#!/bin/bash
# Demo implementation of reversible image obfuscation for lossy file formats
# (jpeg), based on ImageMagick[6] command chains.
#
# USAGE: imageMask.sh ['hide'/'recover'] ['image']
# (Images cropped to multiples of 64 in this implementation.)
#
# * See 'NOTES' at bottom of script for further information and ideas.
#
# N.B. Regarding cryptography: reversible by brute force, edge-analysis ,etc.
# Designed for privacy from casual scanning (human/machine). Inspired by
# previously developed image masking systems: (GMask, JMask, VideoCrypt, etc.)
#
# Source: https://oioiiooixiii.blogspot.com
# Version: 2018.02.19.05.02.27
function obsfucate() # Takes: 'filename', 'width', and 'height'
{
local width="$2" height="$3"
# Crop into 64x64 blocks, rotate 90 degrees, and negate 1/4.
# Tile blocks in reversed image orientation (Height x Width).
# Crop into 16x16 blocks, rotate 90 degrees, and negative 1/4.
# Tile blocks in reversed image orientation (Height x Width).
# One extra 'rotate' at end to return to original orientation.
convert "$1" -crop 64x64 -rotate 90 \
\( +repage -region 32x32+0+0 -negate \) miff:- \
| montage miff:- -mode concatenate \
-tile "$((height/64))"x"$((width/64))" miff:- \
| convert miff:- -crop 16x16 -rotate 90 \
\( +repage -region 8x8+0+0 -negate \) miff:- \
| montage miff:- -mode concatenate \
-tile "$((height/16))"x"$((width/16))" miff:- \
| convert miff:- -rotate 90 ${1%.*}_HIDDEN.jpg
}
function deobfuscate() # Takes: 'filename', 'width', and 'height'
{
local width="$3" height="$2"
# width,height values swapped, 270 rotate to match 'obfuscate' re-orientation
convert "$1" -rotate 270 -crop 64x64 -rotate 270 \
\( +repage -region 32x32+0+32 -negate \) miff:- \
| montage miff:- -mode concatenate \
-tile "$((height/64))"x"$((width/64))" miff:- \
| convert miff:- -crop 16x16 -rotate 270 \
\( +repage -region 8x8+8+8 -negate \) miff:- \
| montage miff:- -mode concatenate \
-tile "$((height/16))"x"$((width/16))" ${1%.*}_RECOVERED.jpg
}
function main()
{
local width="$(identify -format "%w" "$2")"
local height="$(identify -format "%h" "$2")"
# Crude method of making the image dimensions multiples of 64
if [[ "$((width%64))" -gt 0 || "$((height%64))" -gt 0 ]]
then
local width="$(((width/64)*64))"
local height="$(((height/64)*64))"
convert "$2" -crop "$width"x"$height"+0+0 +repage "${2%.*}_CROPPED.png"
local filename="${2%.*}_CROPPED.png"
fi
[[ "$1" == "hide" ]] && obsfucate "${filename:-$2}" "$width" "$height"
[[ "$1" == "recover" ]] && deobfuscate "${filename:-$2}" "$width" "$height"
}
main "$@"
exit
### NOTES ###################################################################
# The command chain 'algorithm' demonstrated here, is just one particular way of
# rearranging an image, using rotation, negation, and altering aspect ratios.
# More complex chaining as well as extra measures will result in more obscurity.
# Saving files at interim stage and reordering blocks allows for greater
# manipulation and security (e.g. unique block ordering based on pass phrases).
#
# Advantages and uses: survives rescaling and re-compression, with minimal
# additional losses due to principles of DCT quantisation. It allows for images
# to be stored on-line using public/private 'cloud' services that destroy
# cryptographic information by rescaling/compressing the image. Reversible via
# alternate means (e.g. Python PIL etc.) if software becomes unavailable.
# Cons: Relatively slow, cumbersome, non-dynamic way to browse images.
#
# A side-effect of the procedure is the removal of EXIF information from the
# image, thus no need for including the '-strip' argument such was desired.
To show the differences created when the image is resaved [with heavy compression] while in a state of obfuscation, the following was completed: The image was masked and saved as a jpeg with quality set to '25'. The original image was also saved as a jpeg with quality set to '25'. Both of these images were 'differenced' with the original, and the result of each were 'differenced' with each other. This image was then normailised for clarity. N.B. "Difference" does not imply quality loss but variance in compression artifacting.
Below left: Differences between original and image that underwent obfuscation then deobfuscation.
Below right: Differences [normalised] between heavily compressed images, as mentioned above.
It is with great regret to inform you that I believe I have killed your cat by accident yesterday evening. I am dreadfully sorry about this. It happened when I was reversing my ride-on lawnmower out of my garage to get better access to the blades underneath which needed sharpening. I believe the recent humid weather has had an extreme blunting effect on mild steel. I think I will attempt to temper the metal the next time they need sharpening, lowering their need for maintenance, and thus, creating fewer chances to inadvertently dispatch neighborhood creatures.
Until yesterday I was not aware that you even owned a cat, but upon close inspection of the cat's remains, it bares an uncanny resemblance to your good self, so I am without doubt to the identity of its owner. I would be delighted to return the cat's body to you at your soonest convenience. If you would rather deal with the remains on your own, you can find them in the ditch, next to Frank Tanner's gate (to the left had side). You can't miss it, it's just behind a clump of nettles (I also marked the spot with an old choc-ice wrapper I saw lying around).
The cat's body was in quite good condition the last time I saw it and I'm sure if you retrieved it quickly it will still be good enough to have it stuffed. By co-incidence, my wife's cousin is a very well trained taxidermist and if you wish I can give you his number. I will, of course, ask for you to receive a modest discount (it is the least I can do).
Again, I am very sorry about all this. Rest assured your cat did not suffer at all during the incident. I was very quick to dispatch it with a nearby length of garden hose when I saw its face trapped under one of my wheels.
If there is anything else I can help you with, please let me know!
The following are some very rough notes on moving a blog from Tumblr to Blogger, including rehosting images and preserving source links. They are presented in a fashion for personal use, but may provide help to others. They make use of Bash and GNU tools. The generic procedures as documented in links below work perfectly fine, and should provide satisfactory results for most people.
The procedures in those links leave the images hosted on Tumblr, and also strip the 'source' URLs to content from each post. The bash snippets included here successfully fix these issues, with only a few potential flaws that can be easily cleaned up manually. It would have been more proper to create the XML files from scratch, or at least manipulate the resultant XML objects directly. This was something contemplated during but was abandoned for simple Bash (sed et al.). Some alternate XML manipulation instructions are listed below