GNOME Bugzilla – Bug 76096
Improve zoomed-out display
Last modified: 2007-08-15 22:25:55 UTC
I found a problem when I was trying to display a special image at 50% zoom. Most of this image is made up of background and foreground layers, blended by alternating their rows to create a flat image. At 50% zoom, every second row is removed (?), causing the foreground part to disapear entirely. A part of the image can be seen at http://www.garandnet.net/gimp-problem.png (look at it at 100% and 50% zoom using The GIMP to get a very good demonstration of the problem). This bug can be even more surprising; since it was originally a full-screen screenshot, it opened at 50% zoom and I wondered what had gone completely wrong until I tried zooming in. This specific image would only be displayed wrong when every second row is removed (offsetting the start by one row would cause a more "correct" look), but it could affect other images differently. Any way to select the lines to display in a non-uniform way should work.
I wouldn't consider this is a bug. It is a well-known side effect of the zoom implementation we use. It works by omitting rows and columns when showing the image zoomed out. The advantage of this implementation is that it is very fast. I'm not sure if the fact that it introduces artefact makes a change worthwhile.
Some other well-known proprietary program solves this problem by generating a scaled down version of the image on-the-fly (with interpolation) whenever you zoom out. This can be enabled or disabled by the user and this is very convenient because if you keep the same zoom level for a while, then it offers a much better quality for the preview and it allows you to move around the image much faster. This is interesting for very large images if the user has enough memory. Some people think that it is one of the reasons why the GIMP seems to be slower than that other program when working on large images. Maybe this bug report could be changed into an improvement proposal (enhancement) for the implementation of a similar feature?
This zooming/scaling problem was mentioned again in the newsgroup comp.graphics.apps.gimp. I am changing the summary of this bug report and converting it to an enhancement proposal. - Add an option to cache a scaled-down version of the image in order to have a better display when zoomed out (and better speed when scrolling). - To be extra nice, have an optional two-pass rendering of the image: when zooming out for the first time, display the image with the current method (skip every Nth pixel) so that it appears fast. Then start an idle thread that renders the scaled down version of the image using linear or bicubic interpolation and displays it over the first version (and keeps the scaled down image in the cache so that it can be used from then on).
Having a high-quality view scaler would indeed be very useful. There are situations where I would work on an image in higher resolution than the final output would be. It's extremely helpful to have a high quality preview in the second view at, say 1:2 to be able to see the expected output. One solution (as suggested in bug #57811) would be to use the dgk-pixbuf scaler. It is fast, very high quality and, to my knowledge, wouldn't create further dependencies, since it's in gtk2. This would of course be a preference - choosing between quality (gdk-pixbuf) or speed (current). Although I believe gdk-pixbuf includes more interpolation methods too.
*** Bug 90421 has been marked as a duplicate of this bug. ***
Quick summary of the bugs depending on this one (as of today): - bug #114268: preview color transformations using the scaled-down image - bug #108172: preview image transformations such as rotation or perspective using the scaled-down image
*** Bug 55598 has been marked as a duplicate of this bug. ***
A comment about the comments that Sven has just added to bug #114268, bug #108172 and bug #90421: I assumed that a good way to fix this bug would be to compute scaled-down previews of all layers and then create the preview of the image by merging the previews of the layers. So the compositing code (using the opacity, layer modes and so on) would be the same as it is now, but it would use the previews instead of the original layers. That's why I marked the other bugs as depending on this one, even though I realize now that my previous comments in this bug report talk about the image and do not mention the individual layers. It would also be possible to merge the original layers first and then generate the scaled-down preview from the image after compositing, but this would require the preview to be re-generated from the full-scale layers every time some layers are moved, shown, hidden or raised in the layers stack. Since toggling the visibility or modifying the opacity of layers is an operation that I perform frequently while working on images, I thought that it would be better to compute the scaled-down versions of the layers first. This would probably avoid a lot of disk trashing when working on large images. If this is the solution that is chosen for fixing this bug, then the dependencies and duplicates make sense. Otherwise, I agree with the comments made by Sven and the dependencies could be changed.
Changes at the request of Dave Neary on the developer mailing list. I am changing many of the bugzilla reports that have not specified a target milestone to Future milestone. Hope that is acceptable.
*** Bug 126484 has been marked as a duplicate of this bug. ***
Changing the summary because this can be implemented without introducing scaled-down previews of the layers. That's an implementation detail and I don't even think that it's a good way to address the problem.
*** Bug 148193 has been marked as a duplicate of this bug. ***
Bug 148193 was marked as a duplicate of this bug (hi, Sven) -- but it is actually a different nuance -- that is to say, there are reasonably fast algorithms around that can solve the aliasing problem not only for affine transformations (such as zooming) but also for nonlinear filtering.
Well, there are lots of places where non-linear filterring can be used in The GIMP. Your bug report should be about a specific one or it is simply not helpful.
*** Bug 162493 has been marked as a duplicate of this bug. ***
*** Bug 170427 has been marked as a duplicate of this bug. ***
Not surprisingly the missing interpolation has an effect when you draw a grid: 1. Create a new image with height=width=1000 pixels, for example. On my screen this images is shown at 66% magnification. 2. Choose Filters -> Render -> Pattern -> Grid... 3a. In the Grid window set Width=2, Spacing=100 and OK. Now the 1st, 4th and 7th line in the grid are thicker than the other grid lines. 3b. If instead you choose Width=1, then the 2nd, 5th and 8th grid lines seem to be missing.
Yes, of course. That's a known problem of nearest neighbor interpolation. What's your point?
*** Bug 315285 has been marked as a duplicate of this bug. ***
is there any progress on this point? Will it ever be fixed? At this moment I have to use another program to fix the colors of large photos because in the gimp it is just too difficult to judge the results with this bad view.
Ruth, if it bothers you, why don't you fix it? Or alternatively, get someone else to fix it for you.
Perhaps I should have stated my question differently, I didn't mean to offend anyone, I was only curious to know. Personally I think that it would be _very_ helpful if this was fixed, but I get the impression that this has gotten a very low priority, since it has the status of 'enhancement'. I am not able to fix it myself. I realise that there is a lot of hard work put into the gimp and I am very glad that there are people like you putting so much energy into it.
I have found a work-around for this problem: I now use the navigation window to view the image. The display in the navigation window is smoother.
This can get REALLY confusing. I was previewing images with the gimp, and they looked to be pure white. If you really need to cut corners for speed: Each display pixel can be mapped to an NxM rectangle of user pixels. For non-integer scaling factors, N and M will vary across the image. Fine. Just take either: a. the average of the NxM region b. a random pixel from the NxM region Either way, the worst of the aliasing problem will go away.
I'm sure the developers can think of a way to fix it - pretty much anything except what the program does now would work, although the quality may vary (that wasn't a concern with my original report as I was just surprised the image looked completely different when I opened it). Maybe a solution would be to look at the image with 66% or 33% zoom, so it can't just skip every other pixel. Can you get to those zoom levels in gimp? Now I can't decide if I should just stop the emails or see how long it takes until someone actually fixes this...
The display code won't be touched until we start porting things to GEGL and Cairo. That will happen after 2.4. Whether that new display code will act differently on zoomed-out displays remains to be seen. It depends on whether someone actually implements the filtered view in GEGL. Albert, can you please stop adding your comments to bug reports? You are not adding any value and the noise you are creating is more than annoying.
*** Bug 422111 has been marked as a duplicate of this bug. ***
Created attachment 89229 [details] [review] GimpProjection-Image-Pyramid-sketch.patch This is a sketch of a patch. There are some assertions when it is run and it contains debugging code and output, but it does not crash GIMP when used. Note that the code is modified only for rgb_a images. This patch is meant as a base to evaluate whether it is feasible to incorporate an image pyramid for the 2.4 release. I'm interested in feedback on the structural approach on the patch, and if it is worth an attempt to polish and finalize it.
Created attachment 89230 [details] [review] GimpProjection-Image-Pyramid-sketch.patch Without po/Makefile.in.in this time...
Created attachment 89272 [details] [review] GimpProjection-Image-Pyramid-sketch2.patch Major clean-up of scetch1; it seems to be fairly stable now even. * Works (should work) for all images. * Removed debugging code and ouput. There are still rooms for improvements, but I won't be able to work on the patch in 2 weeks, which is why I want it to be available. Feel free to restructure the patch in the meantime.
Created attachment 89273 [details] [review] GimpProjection-Image-Pyramid-sketch2.patch There was one obvious cleanup that could be made, sorry for being hasty :) Within the two weeks of having no spare time for GIMP development I will still be able to discuss the patch though, so feel free to comment.
Created attachment 89469 [details] [review] GimpProjection-Image-Pyramid-final-1.patch Two weeks, right... Couldn't even stay away for 2 days. Changes since sketch 2: * Fixed-size pyramid level array instead of dynamically allocating it with constant length. * gimp_projection_source_width_height -> gimp_projection_level_size_from_scale * write_quarter -> gimp_projection_write_quarter * Removed unnecessary tile_lock/release in _write_quarter (source tiles are already locked). * Make sure that invalidations propagate all the way up in the pyramid (this fixes failure to update view correctly when painting with small brushes on zoomed out views). * Update gimp_projection_estimate_memsize.
Commited to trunk (after some modifications), revision 22726: 2007-06-06 Martin Nordholts <martinn@svn.gnome.org> Implemented an image pyramid for the GimpProjection. An image pyramid caches a projection at several sizes, causing the rendering code not to have to swap in all tiles of a (potentially) large image; it can use small versions of the projection if the user is zoomed out. The image pyramid also imroves visual quality, especially at zoom levels where there is a pyramid level that matches perfectly (i.e. at e.g. 50%, 25%, and 12.5% zoom). A step on the right track for bug #76096. * app/core/gimpprojection.[ch]: Adjusted to make use of an image pyramid. GimpProjection now keeps an array of TileManager:s, one per pyramid level. Renamed _alloc_tiles to _alloc_levels. * app/display/gimpdisplayshell-draw.c: (gimp_display_shell_draw_area): Use the right GimpProjection level when drawing * app/display/gimpdisplayshell-render.c: (render_image_init_info_full): Setup RenderInfo with level in mind * app/base/tile-manager.[ch]: Extended API a bit, nothing complicated. * app/base/tile-manager-private.h (struct _TileManager): Keep a pointer to the level below for use in an image pyramid.
This has undergone further minor changes in the meantime. We can however still not close this report as the display code still uses nearest-neighbour "interpolation" to draw the projection. The image pyramid improves this a lot but there are still artefacts for most zoom ratios. For 67% percent zoom for example, nothing has changed. We should keep this report open until this has been addressed.
Could someone attach sample images for testing/evaluating this? I can imagine that the stripes pattern can be used, but there may be better ones.
Good test case is line art. Just scribble something with a paintbrush tool, using a hard edged brush.
Created attachment 89819 [details] Good test image This is my favorite test image. It has many solid lines and much text.
2007-08-15 Øyvind Kolås <pippin@gimp.org> Improve resampling when zooming out of the image for zoom-ratios that are not powers of two. * app/display/gimpdisplayshell-render.c: added a bilinear filtering like weighting of neighbourhood pixels for approximating the downsampling from the next larger level in the projection mipmap. Also some general code cleanup. Closes bug #76096. The display can still be improved, but at least source data is not thrown away anymore.