1

I have a cairo_t cr which I can draw upon with cairo. I want to try to create a highlighting effect on this cairo graphic that should do one of the things:

  • Lighten up the whole image so it looks a little brighter
  • Change the background, that is the transparent parts of the image to some brighter color (e.g white)
  • Maybe add a slight blur on the background

How can I do that with cairo?

[Edit] I have a widget that displays an icon and I want to highlight it when I move the mouse over the widget. Additionally to the highlight I also want to have some white background drawn, so that it is more clear which icon is highlighted. [/Edit]

lanoxx
  • 12,249
  • 13
  • 87
  • 142

1 Answers1

3

I think you should check out some of the operators that cairo has:

http://cairographics.org/operators/

Lightening up the whole image should be doable with SOFT_LIGHT or LIGHTEN and a bright source color. I guess. I'll do some experiments on that.

Why exactly do you want to change the transparent parts of the image? I would guess that most surfaces don't have any transparent parts. Anyway, I think that the DEST_OVER with a white source should do that.

Bluring is something that cairo cannot do for you. However, you can draw your image to an image surface and use some of the code that is floating around the internet for blurring that. For example, google just lead me this way: http://taschenorakel.de/mathias/2008/11/24/blur-effect-cairo/

Edit: I did some experiments (this is the oocairo lua bindings, http://oocairo.naquadah.org/). I think that you want the operator CAIRO_OPERATOR_ATOP with a solid source of e.g. rgba(1, 1, 1, 0.25). This seems to indeed lighten up the image.


oocairo = require("oocairo")

s = oocairo.image_surface_create("argb32", 600, 400)
img = oocairo.image_surface_create_from_png("/usr/share/icons/wesnoth-1.8-icon.png")
local w, h = img:get_width(), img:get_height()

cr = oocairo.context_create(s)

function before()
    cr:save()
    cr:rectangle(0, 0, w, h)
    cr:clip()
    cr:set_source(img)
    cr:paint()
end
function after()
    cr:restore()
    cr:translate(w, 0)
end

function try_operator(op, alpha)
    before()
    cr:set_operator(op)
    cr:set_source_rgba(1, 1, 1, alpha)
    cr:paint()
    after()
end

function try_alpha(alpha)
    cr:save()
    before()
    after()
    try_operator("atop", alpha)
    try_operator("color-dodge", alpha)
    try_operator("soft-light", alpha)
    try_operator("hard-light", alpha)
    try_operator("hsl-hue", alpha)
    try_operator("hsl-saturation", alpha)
    try_operator("hsl-color", alpha)
    try_operator("hsl-luminosity", alpha)
    cr:restore()
    cr:translate(0, h)
end

try_alpha(1)
try_alpha(0.75)
try_alpha(0.5)
try_alpha(0.25)
try_alpha(0)

s:write_to_png("/tmp/t.png")
Uli Schlachter
  • 9,337
  • 1
  • 23
  • 39
  • Thanks. I should have mentioned that I am programing in C. Which language is your example in? What I am trying to do is highlight an icon when I move over it with the mouse. The icons are mostly round and have a lot of transparent parts around them, so I want to draw some kind of white (or any other color) halo around them. This would make it very recognizable when the mouse moves over an icon. – lanoxx Mar 31 '12 at 21:36
  • the language is lua, but just because IMHO it's easier to experiment in that. Most of that maps 1:1 to the C-api, except that this makes use of lua's garbage collector. I don't know about adding a white halo, but cairo_set_operator(cr, CAIRO_OPERATOR_ATOP); cairo_set_source_rgba(cr, 1, 1, 1, 0.2); cairo_paint(cr); should lighten stuff up. For a white background: cairo_set_operator(cr, CAIRO_OPERATOR_DEST_OVER); cairo_set_source_rgb(cr, 1, 1, 1); cairo_paint(cr); (All of this can be confined to some region via cairo_clip) – Uli Schlachter Apr 01 '12 at 17:52
  • OT - ported to python for my own testing: https://gist.github.com/stuaxo/5773269 – Stuart Axon Jun 13 '13 at 12:22