Colorset that dynamicly matches wallpaper

Sascha: thanks…
will see how my little prog looks after using this.

but imlib2 doesnt seem to have a function to convert between color spaces.
when i get a color by query_pixel_hsva, i have to convert it back to rgb. or does fvwm support hsv(a) in colorsets? like hsv:hh/ss/vv?

float h, s, v; int r = 128, g = 32, b = 255, a = 127; imlib_context_set_color(r, g, b, a); imlib_context_get_color_hsva(&h, &s, &v, &a);

float h = 12.0, s = 40.0, v = 100.0; int r, g, b, a = 127; imlib_context_set_color_hsva(h, s, v, a); imlib_context_get_color(&r, &g, &b, &a);

Pixelbrei, does the apply_gtk_theme() work? How to invoke it?

Thanks

no, up to now it does not work.
it was just an idea, and only by accident i left the gtk-thingie in the online-version of the code :smiley:
i took the code out of gtk-chtheme. and for now, i first want the main program to work smoothly before i add gtk-theme-support :slight_smile:

take a look at the gtk-chtheme source code… first you have to write a config file, which contains all the colors you want, then this apply-thing should work somehow…

Are there any suggestions for color-aquire-algorithms?
as you can see, i use the following:

-find “bright” pixels where saturation and value are greater then a “border” value.
-decrease the “border” value and repeat, until i have enough “bright” pixels.

-see which hue, say color, is taken most often upon the bright pixels.
and currently in devel: -get some more hues that are not too close to the first value, but still appear in the picture relatively often

-compute some different colors from this hue, changing the saturation and value for contrast

this does not work with b/w or greyscale pictures, because there is no “hue” for grey. so it ends up with hue=0, which is red, and most probably not what you want.

what about this? first get some general info about the picture:
-is it b/w/greyscale, or mainly one color, or is it real multicolor, is it dark or bright, etc.
-based on this info, select different computation algorithms

i’d appreciate suggestions :slight_smile:

ok, the promised new version of this weekend :slight_smile:
blubb.at/pixelbrei/fitcolor-0.0.2.c
uses Imlib2 where appropriate, but is still optimized for one color in different blends.

it has some serious contrast issues with dark wallpapers, though.

btw. i use it with this colorsets:

#default
Colorset 0 bg $[MED2],  fg #dcdcdc,     hi #0071e2,     sh #0071e2,     fgsh $[MED2]
#inactive window
Colorset 1 bg $[MED2],  fg $[TEXT],     hi $[MEDIUM],   sh $[MEDIUM],   fgsh $[DARK]
#active window
Colorset 2 bg $[MED2],  fg #ffffff,     hi $[LIGHT],    sh $[LIGHT],    fgsh $[MED2]
#inactive menu
Colorset 3 bg $[MED2],  fg $[TEXT],     hi $[MEDIUM],   sh $[MEDIUM],   fgsh $[MEDIUM]
#active menu
Colorset 4 bg $[MEDIUM],        fg #ffffff,     hi $[LIGHT],    sh $[LIGHT],    fgsh $[DARK]
#Modules and Icons in manager
Colorset 6 bg $[DARK],  fg $[MED2],     hi $[MED2],     sh $[MED2],     fgsh #006622
#focus in manager
Colorset 7 bg $[MEDIUM],        fg #ffffff,     hi $[LIGHT],    sh $[LIGHT],    fgsh $[MED2]
#focus-and-select in manager
Colorset 8 bg $[MEDIUM],        fg #ffffff,     hi $[LIGHT],    sh $[LIGHT],    fgsh $[MED2]
#plain in manager
Colorset 9 bg $[DARK],  fg $[TEXT],     hi $[MED2],     sh $[MED2],     fgsh $[MED2]
#select in manager
Colorset 10 bg $[MED2], fg $[TEXT],     hi $[LIGHT],    sh $[LIGHT],    fgsh $[MED2]
#manager himself
Colorset 11 bg $[DARK], fg $[TEXT],     hi $[MED2],     sh $[MED2],     fgsh $[DARK]
#inactive titlebar
Colorset 12 bg $[DARK], fg $[TEXT],     hi $[MED2],     sh $[MED2],     fgsh $[DARK]
#active titlebar
Colorset 13 bg $[MEDIUM],       fg #ffffff,     hi $[LIGHT],    sh $[LIGHT],    fgsh $[MED2]
#inactive buttons
Colorset 14 bg $[DARK], fg $[TEXT],     hi $[MED2],     sh $[MED2],     fgsh $[DARK]
#active buttons
Colorset 15 bg $[MED2], fg #ffffff,     hi $[LIGHT],    sh $[LIGHT],    fgsh $[MED2]

some screenshots:
blubb.at/pixelbrei/pictures/1.jpg
blubb.at/pixelbrei/pictures/2.jpg
blubb.at/pixelbrei/pictures/3.jpg

Hi Pixel,

Good job. Howerver a few things:

Instead of going through all the pixels in the picture why not just sample the picture? That reduces a lot of computations.

Also, the do loop is an overkill. A dark image will have to scan the images multiple times before it find a grey color as the brilliant color. There must be some way to reduce the loop (or at lease reduce the scanning) since you get all the information in the first scan.

Third, when get the dark color from the bright color, satuation is devided too, which makes the color not only darker, but also duller. IMHO, by just reducing value, it gives a better result, and black and white picture works well too.

The last one, when the bright color is dark itself, probably instead of reduce the value to get a darker color, it is better to increase the value to get a brighter color.

Thanks,

Thanks for your answer!

Only reducing the value is really a good idea, just testet it, looks better :slight_smile:

I’m going to think about a solution to the do-loop, which annoys me too…
I think i will leave it with going through all the pixels, but as an option.
thats why i wrote this in the first place, i wanted to consider every pixel.
An option, telling how much percent of the pixels should be scanned, should be a good way to go.

And of course im going to do something about the dark image problem.

And i had a new idea: I’ll split the output colors up into two groups: “normal” colors and “text” colors, so that every text color has enough contrast to any normal color.

So there i got myself some work to do…

Use hue-lightness-saturation. More tuitive than rgb space. To compile, do

gcc `imlib2-config --libs --cflags` -Wall -o getcolor getcolor.c
/**
 *
 * $Id: getcolor.c,v 1.2 2005/12/21 00:31:53 jchen Exp $
 *
 * Algorithm:
 * Get four points from the picture from the one third and two thirds
 * cross points. Find out the lightest and the darkest color.
 * If the dark color is too dark (<10%), it may be too dark to represent
 * the charastic of the picture. Set the dark color to the light color.
 * If both the hue and the lightness of the two colors are too close,
 * adjust their lightness to make the light lighter and the dark darker.
 *
 * Author:
 * Jingshao Chen (jingshaochen at yahoo com)
 *
 */

#include <X11/Xlib.h>
#include <Imlib2.h>
#include <stdio.h>
#include <string.h>

typedef struct {
  float h;
  float l;
  float s;
  int a;
} hlsa_color;

void print_color (char * message, hlsa_color c)
{
  // For debug
  fprintf (stderr, "%s h=%f, l=%f, s=%f, a=%d\n",
           message, c.h, c.l, c.s, c.a);
}


float hue2rgb (float m1, float m2, float h)
{
  if (h<0) h=h+1;
  if (h>1) h=h-1;
  if ((h*6)<1) return m1+(m2-m1)*h*6;
  if ((h*2)<1) return m2;
  if ((h*3)<2) return m1+(m2-m1)*(2.0/3-h)*6;
  return m1;
}

Imlib_Color hls2rgb (hlsa_color hls)
{
  /** from http://www.w3.org/TR/2003/CR-css3-color-20030514/
      HOW TO RETURN hsl.to.rgb(h, s, l):
      SELECT:
       l<=0.5: PUT l*(s+1) IN m2
       ELSE: PUT l+s-l*s IN m2
      PUT l*2-m2 IN m1
      PUT hue.to.rgb(m1, m2, h+1/3) IN r
      PUT hue.to.rgb(m1, m2, h    ) IN g
      PUT hue.to.rgb(m1, m2, h-1/3) IN b
      RETURN (r, g, b)

      HOW TO RETURN hue.to.rgb(m1, m2, h):
      IF h<0: PUT h+1 IN h
      IF h>1: PUT h-1 IN h
      IF h*6<1: RETURN m1+(m2-m1)*h*6
      IF h*2<1: RETURN m2
      IF h*3<2: RETURN m1+(m2-m1)*(2/3-h)*6
      RETURN m1
  */
  float h, l, s;
  Imlib_Color rgb;
  float m1, m2;

  h = hls.h/360.0;
  l = hls.l;
  s = hls.s;
  if (l<=0.5)
    m2=l*(s+1);
  else
    m2 = l+s-l*s;
  m1 = l*2-m2;
  rgb.red = (int)(255*hue2rgb(m1, m2, h+1.0/3));
  rgb.green = (int)(255*hue2rgb(m1, m2, h));
  rgb.blue = (int)(255*hue2rgb(m1, m2, h-1.0/3));
  return rgb;
}

int main(int argc, char **argv) {
  const int SAMPLE=3;
  Imlib_Image image;
  int stepx, stepy, i, j;
  hlsa_color light, dark, sample;
  Imlib_Color rgb_light, rgb_dark;
  float dh;

  if ( argc != 2 ) {
    fprintf(stderr, "Usage: getcolor imageFile\n");
    printf("Function DefaultColorset\n");
    return 1;
  }
  image = imlib_load_image(argv[1]);
  if (image) {
    imlib_context_set_image(image);
    stepx = imlib_image_get_width()/SAMPLE;
    stepy = imlib_image_get_height()/SAMPLE;

    for (i = 1; i<SAMPLE; i++) {
      for (j = 1; j<SAMPLE; j++) {
        imlib_image_query_pixel_hlsa(stepx*i, stepy*j,
                                     &sample.h, &sample.l,
                                     &sample.s, &sample.a);
        print_color("sample color = ", sample);
        if (i==1 && j==1) {
          dark = sample;
          light = sample;
        }
        if (dark.l > sample.l)
          dark = sample;
        if (light.l < sample.l )
          light = sample;
      }
    }

    print_color ("After sample, light color is", light);
    print_color ("              dark color is", dark);

    if (dark.l < 0.1) {
      print_color ("Too dark, dark is", dark);
      dark = light;
    }

    dh = (light.h>dark.h)? light.h-dark.h : dark.h-light.h;
    dh = (dh>180)? 360-dh : dh;

    if (dh<30 && (light.l - dark.l) < 0.2) {
      print_color ("Too close, light is ", light);
      print_color ("           dark is ", dark);
      if (light.l < 0.618 && light.l > 0.382 )
        light.l = 0.618;
      else if (light.l < 0.382)
        light.l = 0.382;
      dark.l = light.l*0.382;
    }
    print_color ("Final light color is", light);
    print_color ("      dark color is", dark);

    rgb_dark = hls2rgb(dark);
    rgb_light = hls2rgb(light);

    printf ("Function DynColorSet rgb:%02X/%02X/%02X rgb:%02X/%02X/%02X\n",
            rgb_dark.red, rgb_dark.green, rgb_dark.blue,
            rgb_light.red, rgb_light.green, rgb_light.blue);

    imlib_free_image();
    return 0;
  }
  printf ("Function DefaultColorset\n");
  return 1;
}

/**
 * History:
 *
 * $Log: getcolor.c,v $
 * Revision 1.2  2005/12/21 00:31:53  jchen
 * Added some explaination on the algorithm.
 *
 * Revision 1.1  2005/12/21 00:07:57  jchen
 * Initial revision
 *
 *
 */

So you, too, found out that you can’t convert from hls to rgb via Imlib2 properly? Should this be commited as a bug to Imlib2?

I feel free to take the hls2rgb code from you, thanx for that :slight_smile:

You are welcome.