Search code examples
rubycommand-linesyntaxrubygemspng

Looking for an explanation of how to use PNGlitch


I have installed the Ruby environment manager rbenv, Ruby, RubyGems, and PNGlitch (on macOS). Now how do I use PNGlitch?

The best documentation I have been able to find is on this page, and here's an example of the syntax given:

How to use this library: The Simple Way

png = PNGlitch.open '/path/to/your/image.png'
png.glitch do |data|
  data.gsub /\d/, 'x'
end
png.save '/path/to/broken/image.png'
png.close
    

Okay, great. When I insert my file paths, save that code as an .rb file, and open it, I just get:

test.rb: command not found

If I paste it directly into Terminal I get:

png = PNGlitch.open '/Users/username/Documents/testimage.png'
-bash: png: command not found
ComputerName:~ username$ png.glitch do |data|
>   data.gsub /\d/, 'x'
-bash: png.glitch: command not found
-bash: data: command not found
-bash: data.gsub: command not found
ComputerName:~ username$ end
-bash: end: command not found
ComputerName:~ username$ png.save '/Users/username/Documents/testimage_glitched.png'
-bash: png.save: command not found
ComputerName:~ username$ png.close

I also tried the syntax given on this page and entered:

pnglitch /Users/username/Documents/testimage.png –filter=Sub /Users/username/Documents/testimage_glitched.png

...this resulted in getting the following message:

tried to create Proc object without a block

Usage:
  pnglitch <infile> [--filter=<n>] <outfile>

Options:
  -f, --filter=<n>  Fix all filter types as passed value before glitching.
                    A number (0..4) or a type name (none|sub|up|average|paeth).
  --version         Show version.
  -h, --help        Show this screen.

↑ I guess this is the developer's idea of documentation. 🤣

Well, trying to follow that example I also did this:

pnglitch </Users/username/Documents/testimage.png> [--filter=<2>] </Users/username/Documents/testimage_glitched.png>

...but that only resulted in:

-bash: syntax error near unexpected token 2

(I chose 2 because apparently that corresponds to the "Sub" filter.)

I tried variants of this syntax as well, including omitting characters <> and [].

There must be some assumed knowledge here that I don't have. So what I would like to know is:

  1. How can I actually use PNGlitch to glitch a PNG image?
  2. How can I use PNGlitch to glitch all the PNG images in a folder?

Any additional advice on using different filters would also be appreciated.

Thank you.


Solution

  • There's a lot going on here that needs to be cleared up.

    Ruby scripts need Ruby to run

    You can't just paste these into bash and expect anything useful to happen.

    The usual procedure is one of two variants. Either:

    1. Create a .rb script, like example.rb
    2. Run ruby example.rb where that's your script name at the end.

    Or use the "hash-bang" method:

    1. Create a script with #!/usr/bin/env ruby as the very first line.
    2. Make this script executable with chmod +x example.rb
    3. Run this script directly, ./example.rb or whatever path it has.

    Note that example.rb by itself will not work unless it is in your path, hence the ./ is necessary.

    Command line example syntax

    Here <name> has special meaning, where it's just a way of saying name as if it had italics or special formatting. On a text-mode terminal it's not practical to add syntax like that, it's limited to ASCII in most cases, so this tradition evolved.

    Within the POSIX shell > and < have special meaning, they're used to, respectively, redirect input to or from a file. For example, ls > ls.txt dumps the output of ls into a file called ls.txt, while cat < ls.txt reads in the contents of ls.txt and displays it.

    Things like [name] mean optional arguments, like [--help] means the --help argument is optional.

    Within the POSIX shell [ and ] have special meaning. They can be used in an if construct, but more commonly in file wildcards, like l[abc].txt means any of la.txt, lb.txt or lc.txt.

    Putting this together it's possible to understand the notation used here:

    pnglitch <infile> [--filter=<n>] <outfile>
    

    Where that means infile is your "input file" argument, and outfile is your "output file" argument, and --filter is an optional argument taking n as an input.

    So you call it like this:

    pnglitch input.png output.png
    

    Or with an option, like you did:

    pnglitch testimage.png --filter=sub testimage_glitched.png
    

    Though note I've used lower-case sub as that's precisely what's in the help output and following casing conventions usually matters.