Category: Uncategorized

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
Advertisements

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.