I have been working on improving the thumbnail view appearance lately. I recently added shadows behind thumbnails. It currently looks like this:
![]()
I am not totally happy with the shadow generation code. It uses Qt radial and linear gradients, but they do not align exactly (have a look at the corners with KMag to see what I mean). Any idea for a smarter way to generate shadows?
I’d probably just be lazy and generate the shadows in the Gimp or similar once and then just cut and paste them under the images, (with apropriate resizing/cropping of course).
Unless you plan to let the user customize their look of course.
looks great… don’t know what you want more ^^
Just take the alpha component of the image and gaussian blur it. A bit slow but it’s the right thing to do as you don’t only operate on photo-like fully opaque images.
If you really wanna do a specialcase optimization for the common JPEG case (where there’s no alpha), I think you need to increase the radius of the corner gradients so they line up.
Hm, to be honest I just see that it does not really work out via kmag.
In general, the effect looks very nice, and I’m really looking forward to the new Gwenview in KDE 4!
@Tirpen: I am not sure it would look great if I scale them. Plus, it’s nice to be able to tweak the shadow without modifying an image, even if the shadow parameters aren’t accessible from the user interface.
@LordBernhard: Thanks!
@Stefan: Right now no shadows are drawn being images which aren’t fully opaque.
@Liquidat: Thanks!
Ok let’s see, on second thought non-opaque images shouldn’t have a shadow indeed. Just go ahead and increase the corner radius to fix the glitch.
What about: start with the image’s QRect, offset it in x and y, fill it with black, and apply a Gaussin blur?
@Jason: I tried this, using ImageBlitz blur implementation, but I couldn’t get a decent result. It’s also a bit overkill to gaussian blur an almost uniform image, even if I cache the generated shadow.
1. Grab the code making shadows in kshadowengine.cpp of Kicker KDE3 library code base.
2. Do all this once at the application start:
- Create an image of say 500×500 pixels (bigger than any shadowed box you have to draw later on)
- Must draw a square of 490×490 pixels on the middle of the image
- Call the shadow method: the Kicker code will generate a shadow for you
- Finally, break the image in 9 parts: the four corners, the four borders, and the center part.
3. When you need to draw a shadow:
- Paint the four corners arround your image
- Paint the four borders arround your image, by clipping the drawing so that they are cutted down
Except that the application startup is slowed down, every drawings are then very fast.
I use that render,split&cache technics for Kirocker Music Display frame drawings (except that I have to stretch the borders and the middle part, which is slow).
As an optimization, you can create 2 images:
- A 500×30 pixels one for the four corners and the top & bottom borders
- A 30×500 pixels one for the left & right borders
No need to crate a shadow of a 490×490 uniform pixels.
Or glossian blur, for that matter…
I think it’s a very good optimization to both caching the corners&borders and to generate them using two small rectangles!
[...] Thumbnail shadows I have been working on improving the thumbnail view appearance lately. I recently added shadows behind thumbnails. It […] [...]
@Sébastien Laoût: Thanks for the tips, will have a look at kshadowengine.cpp.
Well, the blurring code may do the trick as well, and may be more optimized (using GPU in the future, or now).
Oh, and another optimization to not make application startup slower, you can generate the shadow parts only the first time a shadow need to be drawn (the corners and borders are pointers, if they are null, it’s the first time, generate them. The next times, the pointers are not null, simply use them).
So if the user starts Gwenview to view an image, no shadow has to be computed, so no time is lost.
I didn’t mean that you should just scale them. Obviously you should cut out the areas near the corners and the edges and then just scale the edges. Sorry to be unclear.