How to use GIFKR 2: The basics

First off: What is GIFKR and how do I run it?

GIFKR is a program that lets you customize, keyframe, and apply filters to images, GIFs, and videos, mainly tailored to the glitch art community. If you know a little code you can create your own filters too. To run it:

  1. Install Java
  2. Download GIFKR and launch it

How do I use it?

The simplest way to use the GIFKR is to drop, filter, and save a still image:

Drag the image/video/GIF that you’d like to filter directly onto the program.DecentTightErmineSelect your filter and adjust your settingsAdorableTartAldabratortoise.gifSave your image

flippantdisfiguredgoosefishexample

The same process can be used with animated content:

diligentgleefulbagwormexample
It is also possible to keyframe image filters

This can be done for both animated and still source images.

  1. Click the “animate” checkbox
  2. Select your filter, and unlock the variable(s) that you would like to animate
  3. Click the button and draw a graph of how you would like it to change over time

This process sounds complicated but to prove it is not, here’s the entire thing being done in less than 15 seconds:bestshorttermaegeancat

Hopefully this has helped you if you got stuck. I’ll be providing more advanced guides here in the near future.

I’m still alive: Cool stuff coming soon!

Yes, I disappeared for the past several months. Programming becomes slightly less exciting when you’re doing it as a job, in school, and as a hobby. And one of those is significantly easier to take a break from than the others.

In order to fill my time while not constantly writing code I decided to play around with other things… and may have gotten a bit carried away with some of them…

Screen Shot 2017-03-14 at 11.47.13 PM.png

I really do wish this was fake

Regardless, I’m back now. I’ve created GIFKR 2, which has so, so many cool features that hopefully at least a handful of people actually manage to make useful, and now it’s just a matter of getting everything all nice and pretty for the actual release (which takes a surprising amount of work).

Since you have been so patient, why don’t you treat yourself to the rat’s nest source code, while I put together the website and blog, Reddit, and Facebook posts. Also some random stuff that may or may not interest you:

Screen Shot 2017-03-14 at 11.20.23 PM

Sneak peak of some of the new stuff

new features:

  • Kernel convolutions
  • Keyframe all variables
  • New filters
  • Video support
  • Keyframe interpolators for floats, doubles, ints, colors, booleans, and strings
  • Custom filter plugin support
  • Other cool stuff

How to Make a GIFKR Filter

One new thing in GIFKR 2 is the ability to create and import your own image filters. The cool thing about GIFKR is that it does the hard work for you. UI controls are created using reflection, so all you have to do is declare a variable and use it. For example the tiny amount of code in the multiply filter gives the user a de-camel-cased keyframe (or simply a number spinner when not in animation mode) controller that automatically re-renders the preview whenever the value is changed.

 

This post will show you how to write your own using the API available here. In this tutorial I will be using the Eclipse IDE, but you can use whatever you like. I will also assume you have a basic understanding of Java programming. Before we get to actually creating an image filter, we first need to look at how this whole process works on the inside.

All image filters extend from the class ImageFilter (or a class that extends ImageFilter). Since the real ImageFilter class is quite messy and confusing, I have provided in the API a stripped down version that only includes the method signatures and instance variables that you need to worry about. So let’s get started:

The Apply() Function

    protected abstract BufferedImage apply(BufferedImage img);

This is the most important function in the ImageFilter class. This is where you define what your filter does. It takes an image and returns one. You are free to modify and/or return the original image, as the program copies every image before filtering anyways.You also are welcome to create a new image and return that. The only requirement is that the new image should have the same dimensions as the original.

I have also provided several subtypes of ImageFilter that you can extend from that already implement this method, but require you to define your filter in terms of other simpler functions. I will go through these individually later in this post.

Defining Variables in Filters

If you want to make your own image filter, it’s quite likely that you’d like to allow the user to control variables that might influence how the filter behaves. This is where GIFKR shines. If you’d like an interface control for a Number, Boolean, Color, String, Convolution Matrix, or any Enum type, all you have to do is declare it as public. For example if you want an integer variable named “variable name” with a default value of 7, simply write

    public int variableName = 7;

and GIFKR will take care of the rest:

Screen Shot 2017-03-06 at 12.35.35 PM

Then you can use variableName just like you would any other instance variable in your apply() method, or anywhere else. Some guidelines:

  • Float/float variables ALWAYS are between 0 and 1. Always. If you want a decimal variable that can take a larger range, use a double. Since GIFKR is only working with 8 bits per color channel, the difference between precision is effectively meaningless.
  • If you change the value of a variable, the UI controls will not (at this time) reflect the change. For that reason it is recommended that you do not modify public instance variables in code.
  • If you’d like to create a drop-down with many options (see pixel sorting filters) simply define your enum type within the filter class.
  • You can also make a custom UI controller for whatever type you like by making a public JComponent. Unfortunately however these cannot be keyframed.
  • doubles and ints by default are within the range [0, 2,147,483,647]. You can override this using the following format:
    @ControlOverride(min = "-255", max = "255")
    public int constant;

Random Numbers in Image Filters

The following line is included in the ImageFilter class:

    protected final Random rand;

Do not create your own Random or use Math.rand() to use random numbers in any ImageFilter. Simply call rand.nextInt(), rand.nextDouble() etc.. Using the included rand instance variable allows the user to control the seed of the RNG. Here is the javadoc for Random. If you do not use any random numbers in your ImageFilter, include the following function to hide the controls for random numbers:

    @Override
    protected boolean randomControls() {
        return false;
    }

Similarly, there exist controls for rotating, filtering, and then un-rotating the image. This allows for things like pixel sorting to be applied at an angle (example) but does pretty much nothing for many filters. If you’d like to hide the built in angle controls (and they are not already hidden by the subclass of ImageFilter that you are extending from), include the following function in your filter:

    @Override
    protected boolean angleControls() {
        return false;
    }

Types of Image Filters

GIFKR includes several subclasses of ImageFilter for you to extend to make creating your own filters even simpler.

Algebraic Image Filter

AddFilter, ColorLimitFilter, DivideFilter, MultiplyFilter, NoiseFilter, ReplacementFlilter, SubtractFilter

An “algebraic image filter” is the simplest type of ImageFilter. These are defined by the function:

    public abstract int apply(int channel);

effectively, it takes values from 0-255 representing the red, green, or blue channel of each pixel and returns the new value. Values greater than 255 will behave as that number mod 255. Despite its simplicity, this class can define very interesting effects. For example the MultiplyFilter looks like:

public class MultiplyFilter extends AlgebraicImageFilter {

    public double multiplicationFactor = 1d;
    
    @Override
    public int apply(int channel) {
        return (int) (channel * multiplicationFactor);
    }
    
    @Override
    protected boolean randomControls() {
        return false;
    }
}

and can create things like:

psychadelic

Pixel Image Filter

HSBFilter, MonochromeNoiseFilter

This class is very similar to the Algebraic Image Filter, but allows you to work with an entire pixel at a time using the method:

    public abstract int apply(int color);

where color is an integer where the first 8 bits are for alpha, and the following for red, green, and blue respectively. If you are not comfortable with bitshifting, feel free to work with it as a color object by using new Color(color) and then returning the getRGB() method in the color class, but do be aware this results in a significant performance hit.

Convolution Filter

BoxBlurFilter, EdgeDetectFilter, MatrixFilter, SharpenFilter

Many filters from edge detection to blurs can be succinctly described using a simple matrix. To learn more about how this works, I highly recommend reading the wikipedia article on kernel convolutions. Essentially the method

    public abstract float[][] getMatrix();

is called before the image is filtered. So you can simply define a constant matrix like I did in the EdgeDetectFilter:

    @Override
    public float[][] getMatrix() {
        return new float[][] {
            { 0f,-1f, 0f},
            {-1f, 4f,-1f},
            { 0f,-1f, 0f}
        };
    }

or do something more fancy like in the GaussianBlurFilter where the matrix is dependent on other variables.

public class GaussianBlur extends ConvolutionFilter {

    public double sigma = 1;
    
    @Override
    public float[][] getMatrix() {
        
        int dim = dim();
        float[][] matrix = new float[dim][dim];
        
        for(int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                matrix[i][j] = gaussianDistribution(Math.sqrt(Math.pow(dim/2 - j, 2) + Math.pow(dim/2 - j, 2)));
            }
        }
        
        normalize(matrix);
        return matrix;
    }

    private float gaussianDistribution(double x) {
        return (float) (Math.exp(-x*x/(2 * sigma * sigma)) * (1d/Math.sqrt(2 * Math.PI) * sigma));
    }
    
    private int dim() {
        return 2 * (int) sigma + 1;
    }
}

I have also created a interpolator for matrices, so simply writing “public float[][] varName = new Float[][]…” is perfectly valid, and will give the user complete control over the matrix. This is utilized in the MatrixFilter class.

Text Filter

ASCIIFilter, MessageFilter, TheMatrixFilter

The text filter takes care of font, drawing text, etc for you. All you have to define is what character and color to use given the color at the location of the character and the index of the character.

    public abstract char getChar(int color, int count);

    public abstract Color getColor(int color, int count);

Pixel Sort Filter

LinePixelSort, StandardPixelSort, RandomPixelSort

The pixel sort filter requires you to implement the Apply() method from ImageFilter. It provides you with methods and variables to control pixel sorting, but ultimately the implementation is up to you. If you would like to implement your own, I highly suggest you take a look at the source code to the built-in pixel sorting filters.

Actually Creating, Using and Sharing Your Filter

Finally, it’s time to actually create a filter. I’ll pretend you didn’t just skim past all the stuff above.

First: Download the API and open it in Eclipse. You can do this by unzipping the file and opening it via File>Open projects from filesystem.

Your project should look something like this:

Screen Shot 2017-03-06 at 2.53.59 PM

click on the “default package” and then go to File>New>Class

Enter a name for your filter, and choose a type of ImageFilter you want to extend from. Be sure to selected “Inherited abstract methods” to have stubs generated for you.

Screen Shot 2017-03-06 at 2.57.19 PM.png

Then write the code for your filter using the information above. I’m going to leave mine pretty simple by just returning the original image, but I’ll add some variables just to make sure they show up:

Screen Shot 2017-03-06 at 8.48.04 PM

Now save it. In order to test, your filter, open the project in your file viewer:

Screen Shot 2017-03-06 at 3.04.13 PM

Navigate to the “bin” folder, and drag .class onto GIFKR.

Screen Shot 2017-03-06 at 3.16.54 PM

Finally, test your filter. If you’re satisfied with it, share it with the world! The .class file is entirely your property, and is free to be distributed (sold even if you want I guess?) however you feel.

The Power of GIFKR

So this blog post is just going to go through some of my favorite GIFKR based art. If you want to try it out yourself, download GIFKR here. It’s currently in beta so it’s still improving and changing quite a bit, but despite being a bit rough around the edges everything should work okay. Here’s what the program looks like as of now: gifkr.png

Even just playing around with filters on the default image can make some pretty awesome looking stuff. This one is just a standard Total RGB Pixel Sort but instead of filling the areas between the threshold with sorted pixels, it’s a gradient from the first pixel to a turquoise color. GIFKR includes regular pixel sorting, but also a few options to tweak the basic algorithm. Also notice how the filter is applied at an angle and the image isn’t cropped. I’m not sure if I invented this technique but I can’t find it anywhere else.

reglitched logo

Let’s get into some art, shall we? This is one of my favorites. Pixel sorting by hue, but the boundaries are simply lines. Another variant of pixel sorting included in GIFKR. Pixel sorting can turn a beach sunset into a New York sunrise.

newyorkbeach

Now I’m not going to try and tell you the next one is a masterpiece. But this gives you an idea of what I mean by sorting at an arbitrary angle. And don’t mind the slight shake, I implemented a fix for that after I made this GIF.

sand

The other feature that I thought was unique about GIFKR is the ability to apply a filter at different angles on RGB channels. So this is my friend mark and the translate filter with each channel set at 90° from any other. This feature seems to add a lot of power without much complexity, and I find it very handy at times.

mark

The gradient pixel sort filters can be pretty creepy on certain subjects.

eyebrows

Honestly I think it’s one of the most powerful in the program.

snowwy.png

Don’t forget about the non-sort based effects. They can do cool things too.

psychadelic

I find that explosion gifs make good subjects.

I’ll let you in on a secret. GIFKR + Memes = reddit karma.

The filters, for better or worse, let you take them to the absolute extreme. This was once a picture of squidward.

glitch(2)

If you do it with intent, sometimes making an image entirely incomprehensible can create really neat looking abstract art. This was originally a pic of my brother skiing.

snow1

Also combining it with my Klauber Triangle wallpaper making program can produce some awesome looking stuff.

Really it’s hard to find something that can’t be made into an interesting GIFKR image or GIF.

So there are ton’s of image filterers and pixel sorters out there, what makes GIFKR not just another Glitch in the Wall?

glitchinthewall

There are things out there that are more powerful than GIFKR. Processing, for example. However, you have to write code or at the very least edit scripts to produce anything. There’s no live preview, so you have to enter your variables, render, and hope it looks good. If it doesn’t, you have to try again. The pixel sorters that don’t require coding seem to have this issue as well. In fact, the first article about pixel sorting that shows up on google tells you to tweet a picture and get your pixel sorted result tweeted back. A neat trick, but artists deserve better than that. There’s also just the unique features of the program that others simply don’t have: GIFs are supported natively. You can pixel sort at any arbitrary angle. You can filter by channel. You can make keyframe-like animations. Even though you’re not coding, there’s a lot of power just a few clicks and drags away.

Channel Sorting

So by now there’s a decent chance you’ve seen art involving pixel sorting:

Pixel sorting is a very simple image manipulation technique where you compare every pixel in an image to the one adjacent to it, and if they are within a given tolerance, make the second pixel the same color as the first. It is worth noting that the algorithm doesn’t actually involve any sorting, though there are variations of it that do. Here’s a GIF of me being pixel sorted and increasing the tolerance on each frame:

vid2gif

Neat right? Well I thought to myself, pixels can be separated int red, green, and blue components, what would happen if I pixel sorted them in different directions? This is what I call channel sorting. And it also makes some cool stuff happen:

In this case red is sorted right, green left, and blue down.

So how did I make these cool GIFs? I’m using a program called GIFKR, but it’s not quite finished yet. It’ll be ready soon™, so follow this blog or my twitter to be one of the first people to try it out. It also can do crazy stuff like this:

glitch(1)

glitch(6)

 

So yeah it supports GIFs, changing the angle and value of the filter over time, and includes some cool custom filters.

Abusing toString()

So I’m working on a program that has some /r/Glitch_Art inspired image filters for fun, and even has a fancy little GUI. I love thinking of new algorithms to screw up images, but hate having to write GUI code for every new filter I add. My solution? Let toString() do the work by un-camel-casing and spacing the class names.

public String toString() {
    String s = this.getClass().getName();
    s = s.replace(this.getClass().getPackage().getName()+".", "");
        
    for(int i = 1; i < s.length(); i++)
        if (Character.isUpperCase(s.charAt(i))) {
            s = s.substring(0, i)+" "+s.substring(i);
            i++;
        }
    s = s.toLowerCase(); 
    return Character.toUpperCase(s.charAt(0)) + s.substring(1);    
}

The result:

Screen Shot 2016-02-11 at 4.42.10 PM

Unfortunately it seems there’s no way to dynamically get all subclasses of something in a running program, so i still have to manually add an instance of each filter to a list. What a chore. I’ll keep looking for a way to misuse reflection to do it though, and will let you know if I figure something out.

Test posts

Every blog has to have one, and in honor of Cosmo Kramer’s coffee table book about coffee tables, I felt I should make a test post about test posts. Also to make sure any readers know the importance of the topics that I will be discussing in the future, and how I plan to fill them with only the most interesting and succinct commentary possible.

Famously, the r/pics subreddit debuted with what was for a long time the top post on reddit. It has since been dethroned by a picture of a kid holding a banana and a Nazi Swastika, among other things. This is the purpose of the test post though, they aren’t meant to sit on a throne. They are meant to be forgotten, and sit there until someone gets curious about the now famous site’s humble beginnings. (Or more likely the unsuccessful blogger is looking back at their old posts desperately trying to figure out what went wrong, and why nobody ever cared about it). Regardless, test posts have a purpose of making sure everything is working right, and that the vision the creator had in mind is close enough to how the post appears on the page. Occasionally, some break the stereotype and achieve greatness. There isn’t a rule that test posts have to be full of Lorem ipsum dolor shit. They don’t have to contain only gibberish or otherwise worthless text. They can even serve as symbols of rebellion and community like the r/pics one. This test post however, is perfectly content being a boring piece of text that nobody should waste their time reading.