Tuesday 7 July 2020

Heads and tails - manipulating images as text using the command-line and sed

I discovered that working on a batch of files in a fashion akin to the word pad effect it was possible to use basic text manipulation on the command line thus opening up a wider range of sorting and manipulation and possibilities for glitching

The most complicated method is to treat the files as text but to protect the header and footer (which tells whatever program is accessing it what kind of a file it is and how to read) it by stripping those away and  re-adding at the end of the process . To do that I take a sample header and footer from a single file in the batch ( given that the batch are all of the same size and type and as near to raw as possible ) . Its probably good practice to have your source, intermediate and destination folders setup ( you need 3 folders to avoid overwriting existing files and thus rendering them useless) – so redirect or copy paste the header and footer into the destination folder to avoid overwriting or accident ) .

To get the header – do ‘head -n 5 somefile.extension > head.extension’

To get the footer – do ‘tail -n 5 somefile.extension > tail.extension’

Delete the first and last line of each file in the folder ( excluding header and footer) with ‘sed '1d;$d'’

After whatever operations I’ve carried out on the files I’ll rewrite the header and the footer to the files in the destination folder .

How does that work in practice

The above is just an outline of the process, below is an attempt to put that into scripts for use on the command line. *Note – if you cut and paste from here remember to miss out the ‘’ at beginning and end .

So we get our header and footer with;

‘head -n 5 somefile.ppm > head.ppm’

‘tail -n 5 somefile.ppm > tail.ppm’

Notice that I use the file extension of the format I’m working with ( in this case ppm) – this is important as the head and tail describe what the file is.

Then we need to strip the first and last lines from each file and redirect the output into our intermediate directory with this;

‘for file in *; do sed '1d;$d' "$file" > /home/ian/test/intermediate/"$file" ; done’

(We need to strip the first and last lines so that the file stays the same size and thus readable when we have worked on it and re-added the head an tail at the end )

now we exit from the source folder and go into the intermediate folder and open a terminal and think about what to do with each file . As this is a batch process and we are treating the images as text lets swap every other line with this command;

‘sed -n '{h;${p;q;};n;G;p;}'’

or we could choose to reverse each character on each line with this ‘sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'’ - but we will stick to the first example here.

As a script it will look like this

‘for file in *; do sed -n '{h;${p;q;};n;G;p;}' "$file" > /home/ian/test/destination/"$file" ; done’

so now I change into the destination folder and I want to make the files readable again by adding the header and footer back onto the files.

‘for file in *; do cat head.ppm 1<> "$file" ; done’

*Note that the terminal complains at the end of that ‘cat: head.ppm: input file is output file’ - ignore that its just telling you it doesn’t want to overwrite the head.ppm file.

And remember we also have to add a tail to the file so with tail.ppm lets do that.

‘for file in *; do cat tail.ppm >> "$file" ; done’ ( notice arrow redirection is different to first one for a fuller explanation of redirection look here https://www.guru99.com/linux-redirection.html )

*And once again the terminal complains ‘cat: tail.ppm: input file is output file’ - ignore that.

All being well we should now have a folder full of readable but glitched files . What you do with them after that is up to you – you can either turn them back into video with ‘ffmpeg -i image-%03d.ppm video.mp4’ or a gif ( find information on methods here - https://stackoverflow.com/questions/3688870/create-animated-gif-from-a-set-of-jpeg-images#29542944) or you could just pick the ones you like the most and upload to your forum of choice.

( As a side note I have found that this can be done with mpeg video by getting and saving the head and tail then stripping the head and tail then using the above process to swap every other line, without cutting it into single images – its quite flexible, try it on different formats) .

This is a video of the above in practice.



Or we could just run a simple bash script like this, remember to make it executable before running (Warning, this operates within the working directory and directly alters the files within that directory there is no redirection , always always make back ups). 

#!/bin/bash

  find . -type f -name '*.bmp'|while read filename; do echo ${filename};

#get header
  head -n 3 ${filename} > head.bmp;

#strip header and footer ( though you might get away with just the head)
  sed '1d;$d'  ${filename} > swap.bmp
 
#swap every other line
  #sed -n '{h;${p;q;};n;G;p;}' swap.bmp > swap2.bmp;
 
 #delete empty lines ( like standard wordpad)
 #sed '/^$/d' swap.bmp > swap2.bmp;
 
 #the original blocky hex !!
 sed 's/[a-z]*/(&)/' swap.bmp > swap2.bmp;

  cat head.bmp swap2.bmp > ${filename};
 
   rm head.bmp;
   rm swap.bmp;
   rm swap2.bmp  
   
   done



ikillerpulse ( requires tomato.py in working directory)

I've been working on this script for the last week or so. What does it do? It takes an input video/s,  converts to a format we can use f...