Over the Rainbow – Colour Filters

Preface

I know, many of you were expecting a next post on RxVMS but you will need a bit more patience. I didn't have time for most of this year due to projects and my repeatedly manifesting depression. I'm very open with that because I know many in our industry struggle with mental issues and they should know they are not alone.
The other reason is that I continuously collect experience with RxVMS in projects and want to consolidate this experience before updating and extending the blog series.

So here comes a post about a totally different topic that I had to solve not long ago and about that I'm really exited because it features a widely unknown Widget.

ColorFilters

Some weeks ago I was looking for a way to invert the colours of a monochrome icon and at first it looked like that it wouldn't be possible with Flutter. Luckily one of my Twitter followers mentioned a ColorFiltered widget, a thing I never had heard of before.
Looking at the API docs I had no clue how to use it. In the mean time the docs got a bit extended after I reported it to the Flutter team, but still I think it might be worth to give you a more thorough explanation.

In short ColorFiltered applies a ColorFilter on its child (who would have guessed that šŸ˜‰ ). So far so good, but what is a ColorFilter. A ColorFilter can be created by numerous constructors from which ColorFilter.matrix is the most powerful and versatile. It applies 4x5 matrix on every pixel of the child's screen area.

Instead of trying to explain how this works with words or maths, I have some examples that should make the principle clear:

Identity Filter

The easiest one is the identity which doesn't change the content at all. I include it because it makes the principle easier to understand:

identity

Radical different colour

This one modifies all components of the colours

random-filter

Inverting

And finally the inverting filter

invers

Sample App

To let you get some experience with matrix filters, I made a small sample App that lets you apply filters to your own images

colorfiltered_demo_small

The important parts of the code are where the filters are defined

Map<String, List<double>> predefinedFilters = {
  'Identity': [
    //R  G   B    A  Const
    1, 0, 0, 0, 0, //
    0, 1, 0, 0, 0, //
    0, 0, 1, 0, 0, //
    0, 0, 0, 1, 0, //
  ],
  'Grey Scale': [
    //R  G   B    A  Const
    0.33, 0.59,0.11, 0,0,//
    0.33,0.59,0.11, 0,0,//
    0.33, 0.59,0.11, 0,0,//
    0, 0, 0, 1, 0, //
  ],
  'Invers': [
    //R  G   B    A  Const
    -1, 0, 0, 0, 255, //
    0, -1, 0, 0, 255, //
    0, 0, -1, 0, 255, //
    0, 0, 0, 1, 0, //
  ],
  'Sepia': [
    //R  G   B    A  Const
    0.393, 0.769, 0.189, 0,0, //
    0.349,0.686,0.168,   0,0, //
    0.272,0.534,0.131,0,0, //
    0, 0, 0, 1, 0, //
  ],
};

The matrixes are defined as List<double> that is in row-major order which means the rows are concatenated to one large list.

Using the Filter is as easy as any other widget:

child: GestureDetector(
    onTap: pickImage,
    child: imageFile != null
        ? ColorFiltered(
            colorFilter: ColorFilter.matrix(matrixValues
                .map<double>((entry) => entry.value)
                .toList()),
            child: Image.file(
            imageFile,
            fit: BoxFit.cover,
            ),
        )
        : Center(child: Text('Tap here to select image')),
),

As a side note, you can apply this filter to any type of child widget, not only to an Image.

The code of the demo app can be found here:
https://github.com/escamoteur/color_filtered_demo

Have fun with it. Just to mention I tried to make the layout responsive and not based on any fixed values.

Contact me:

8 thoughts on “Over the Rainbow – Colour Filters

  1. Bret Johnson says:

    This post was actually quite topical & handy for me. Thanks for writing it.

    A question, though: Where did you get the matrix values from, like for Sepia? Do you have suggestions on web resources that may give some other useful color transform matrices?

    • Thomas Burkhart says:

      Hi,

      Thanks a lot.

      I googled a lot to find good values. unfortunately I didn’t book mark them.
      Search for color matrix filter.

      Cheers
      Thomas

  2. Bwolf says:

    Are you thinking about finishing the RXvms series? or did the idea die?

    • Thomas Burkhart says:

      Yes, please have a look at the beginning at the post. I will continue, but I can’t say when yet.

  3. Valter Barbosa says:

    Hey, stay strong! One more time, thank you for share your experience. Yes, any in our industry struggle with mental issues and they should know they are not alone. This week was hard to me too.

    RxVMS is simple to learn but we need you to explain to us. Simple, no easy šŸ™‚

    I’m starting a important project (to me), and I will try to use your ideia. I believe this will help me to finish this job. I need it.

    One more time, thank you!

  4. Jimmy says:

    Is there any way to apply a colorfilter to half of the image and a separate color filter to the other half?

    • Thomas Burkhart says:

      Hi,

      as the colorfilter applies to it’s child, I have no idea how you could achieve this without splitting you image into two parts .

  5. Javier Garcia says:

    Very good post! Greetings from Mexico!

Leave a Reply to Valter Barbosa Cancel reply

Your email address will not be published. Required fields are marked *