Bug 152192 - resize really bad qualitatively
Summary: resize really bad qualitatively
Status: RESOLVED FIXED
Alias: None
Product: digikam
Classification: Applications
Component: Plugin-Editor-Resize (show other bugs)
Version: unspecified
Platform: openSUSE Linux
: NOR normal
Target Milestone: ---
Assignee: Digikam Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-11-12 05:10 UTC by Cristian Tibirna
Modified: 2017-08-06 19:15 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In: 0.9.3


Attachments
Resized image using CImg::resize and bi-cubic interpolation (139.19 KB, image/png)
2007-11-19 11:54 UTC, caulier.gilles
Details
Resized image using CImg::resize and linear interpolation (141.05 KB, image/png)
2007-11-19 11:54 UTC, caulier.gilles
Details
Resized image using Gimp and linear interpolation (17.26 KB, image/png)
2007-11-19 11:55 UTC, caulier.gilles
Details
Resized image using Digikam::DImg::resize (modified smoothScale algorithm from imlib2 to support 16 bits color depth) (127.35 KB, image/png)
2007-11-19 11:56 UTC, caulier.gilles
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Cristian Tibirna 2007-11-12 05:10:26 UTC
Version:           0.9.2-final (using KDE KDE 3.5.5)
Installed from:    SuSE RPMs

I'm almost ashamed to report this, as it is more a wish than a bug and I can't hold forth nothing but qualitative observations in support.

Digikam's resize functionality is really bad qualitatively compared to the resize function found in other programs (like GIMP). The problem sits in the really ugly jagged diagonal lines appearing after resizes in contours of highly contrasting images. No matter what options I choose in the cimg plugin's configurations, the jagging is immediately visible and almost insulting.

Thanks for your understanding.
Comment 1 Arnd Baecker 2007-11-12 09:19:10 UTC
Hi Christian,

I assume that you use the Image editor, "Transform/resize"?

This is the same issue we discussed a couple of days on the IRC.
Only if "Restore photograph" is ticked, cimg is used.
Otherwise  DImg::smoothScale() is used to resize image, http://websvn.kde.org/branches/extragear/kde3/graphics/digikam/libs/dimg/dimgscale.cpp?revision=675631&view=markup
(the code comes frome imlib2 + 16 bits color depth support).

User cryos (in the IRC) wrote that "It used to perform a lot better",
but nothing has changed  in the underlying code for ages.
Therefore Gilles suspected:
"perhaps it is a compilation option (optimization ?) used to compile digiKam which breaks something"

This sounds like it needs a thorough investigation...
Comment 2 Cristian Tibirna 2007-11-12 13:21:52 UTC
Yes, the "Transform/Resize..." menu item from the editor.

No matter if cimg is checked or not, the result is extremely jagged.

Here is an example:

Original (4.3 MiB!): http://cristian.tibirna.org/sandbox/dsc_0520.jpg
Resized: http://cristian.tibirna.org/sandbox/dsc_0520_resized.jpg

Really bad jagging can be seen in the resized one on the Python and Tkinter text and on the vertical (slanted) contour of the Python Programming book. 
Comment 3 Arnd Baecker 2007-11-12 13:33:49 UTC
Yes, I can confirm the problem. It is really bad, 
and even worse for smaller output sizes.
(and gimp does better, even without cubic interpolation ...)

((At least you seem to have the C++ books on your shelf as well
to solve that issue on your own  - sorry, couldn't resist ... ;-))

Gilles, can you reproduce the problem as well?
Comment 4 Fabien 2007-11-13 14:36:11 UTC
Hi,
I can confirm the problem as I already faced it in the past.
This bug entry is also related to this one I think :
http://bugs.kde.org/show_bug.cgi?id=149284

I don't think it's only about C++ coding but also about maths (algorythms used behind it). If you look at image processing softwares, they often have different possibilities for that (bilinear, bicubic, ...).
If you look at krita, they have many different filters. Maybe digikam could "borrow" some code from Krita ?

I think this is really important and will be more and more with this stupid Mpx race manufacturers still play (look at the latest 12 Mpx compact cameras).
Comment 5 caulier.gilles 2007-11-13 14:46:20 UTC
Fabien, 

the algorithm to resize image come from imlib2 and have been ported to digiKam core by Renchi Raju (he have added 16 bits color depth support and removed all assembler code to be more portable). 

This code is also used in Gwenview as well, without removing assembler code. If i remember Krita have planed to do it. 

Few portion of code have been also ported by Mosfet originally to Qt...

Code is very complex... but very fast to render image on screen. Look here :

http://websvn.kde.org/branches/extragear/kde3/graphics/digikam/libs/dimg/dimgscale.cpp?revision=675631&view=markup

This code is used everywhere to render zoom and resizement. There is no plan to replace it. To have tried to understand how it's work, it's not simple.

Of course, we can use another algorithm _only_ for image editor resize tool. 

I'm waiting your proposals for the better one (url to source code will be very appreciate)

Gilles
Comment 6 Fabien 2007-11-13 18:17:37 UTC
But, imlib code is just used to display pictures on screen, isn't it ?
Or is the same code used to resize the picture in Image Editor and Kipi resize plugin ?

I was talking (as the bug report) about resizing the picture to create a new file.
My remark about the new cameras is because I think it's stupid to keep so big pictures, so it could be a good solution to resize them to something more convenient (in term of disk space, speed and quality), eg 6 Mpxels.

About krita algorithms, it seems to be here :
http://websvn.kde.org/trunk/koffice/krita/image/kis_filter_strategy.cc?view=markup

see also
http://websvn.kde.org/trunk/koffice/krita/image/kis_filter_strategy.h?view=markup
Comment 7 Fabien 2007-11-13 18:35:25 UTC
Also found interesting pages :
* image resizing :
http://www.cambridgeincolour.com/tutorials/image-resize-for-web.htm
http://www.cambridgeincolour.com/tutorials/image-interpolation.htm

There are also some research papers on that, but maybe not so easy to understand and use :)
Comment 8 Fabien 2007-11-13 18:45:23 UTC
From one research paper (A New Image Scaling Algorithm Based on the Sampling Theorem of...)


Most popular resizing algorithms 
- nearest neighbour
- bilinear algorithm
- bicubic
- Bell
- Hermite
- Mitchell,
- Hanning
- Gauss
- Lanczos

Photoshop uses interpolations based on bilinear, bicubic and nearest neighbour.
Krita uses Mitchell, Lanczos, BSpline, Bell, triangle/bilinear and Hermite.
Comment 9 Fabien 2007-11-13 18:52:58 UTC
And finally last links :

* The myth of infinite detail: Bilinear vs. Bicubic
http://www.codinghorror.com/blog/archives/000367.html

* Better Image Resizing
http://www.codinghorror.com/blog/archives/000903.html

<<
After some experimentation, I came up with these rules of thumb:

    * When making an image smaller, use bicubic, which has a natural sharpening effect. You want to emphasize the data that remains in the new, smaller image after discarding all that extra detail from the original image.
  
    * When making an image larger, use bilinear, which has a natural smoothing effect. You want to blend over the interpolated fake detail in the new, larger image that never existed in the original image. 
>>


This is why I think we should have a choice of a few algorithms...
Comment 10 Fabien 2007-11-13 18:57:53 UTC
Taken from Adobe coldfusion docs :


Interpolation algorithms

Interpolation algorithms let you fine-tune how images are resampled. Each algorithm balances image quality against performance: in general, the higher the image quality, the slower the performance. Quality and peformance differ based on image type and the size of the source file. The following table describes the algorithms and their named equivalents based on average test results:

Highest image quality with low performance : lanczos
	
Good image quality with slightly higher performance: mitchell, quadratic

Medium quality image with medium performance : hamming, hanning, hermite
	
Slightly distored image quality with high performance : blackman, bessel
	
Poor image quality with highest performance : nearest, bicubic, bilinear
	
Comment 11 Cristian Tibirna 2007-11-13 19:35:05 UTC
Fabien

Thanks a lot for a really great research. This is a good basis to start in case it proves to be necessary.

Yes, indeed, I speak of the image scaling algo, not of the on-screen zoom algo. Speaking of which, I should have mentioned it, the on-screen zoom is really really good. It's better than GIMP's default image scaling. 

To explain: a 3000x2000 photo shown as "fit to screen" (about 25% zoom -- on my screen at least) is about the same (pixel) size _on screen_ as the same photo, resized at 800x600 photo and shown 100% on screen. But the 3000x2000 photo at 25% zoom looks way better (i.e. with almost no visible resizing artifacts) than the 800x600 at 100%.

I know this doesn't help much, but perhaps hints to comparing on-screen zooming (i.e. temporary resizing) with actual image scaling (permanent resizing).

And yes, time permitting, I will try to look at the kipi code too.

Thanks a lot.
Comment 12 caulier.gilles 2007-11-16 07:55:34 UTC
I have found a speed way to fix this problem. In CImg library, there is an algorithm to resize image like we want. This one do not dependant of Greystoration algorithm used in Restoration mode.

To be clear, CImg is a low level image manipulation library. Greystoration is an algorithm witch use CImg.

In my Qt Greycstoration interface, there is already a simpleResize() method witch do not use Greycstoration algorithm. There is a parameter to set the interpolation method: 

    //! Return a resized image.
    /**
       \param pdx = Number of columns (new size along the X-axis).
       \param pdy = Number of rows (new size along the Y-axis).
       \param pdz = Number of slices (new size along the Z-axis).
       \param pdv = Number of vector-channels (new size along the V-axis).
       \param interp = Resizing type :
       - -1 = no interpolation : raw memory resizing.
       - 0 = no interpolation : additional space is filled with 0.
       - 1 = bloc interpolation (nearest point).
       - 2 = mosaic : image is repeated if necessary.
       - 3 = linear interpolation.
       - 4 = grid interpolation.
       - 5 = bi-cubic interpolation.
       \note If pd[x,y,z,v]<0, it corresponds to a percentage of 
       the original size (the default value is -100).
    **/
    CImg get_resize(const int pdx=-100, const int pdy=-100, 
                    const int pdz=-100, const int pdv=-100,
                    const int interp=1, const int border_condition=-1);

I will provide a patch to test this way...

Gilles
Comment 13 caulier.gilles 2007-11-16 07:59:56 UTC
#11 ==> Christian, in kipi-plugins :

- Batch resize tool use ImageMagick (8 and 16 bits color depth). There is no problem here.
- Resize operations in others place use QImage method (8 bits color depth only). No problem here too (HTMLExport, SendImages, etc...)

Gilles
Comment 14 caulier.gilles 2007-11-16 08:09:56 UTC
Arnd,

I'm too wrong !!! Do you know ??? Perhaps i need aspirin...

Forget all that i said before... It's wrong (:=)))

Image Editor resize tool use everywhere CImg library !

1/ If "Restoration" mode is _not_ use, CImg::resize() method is called with a linear interpolation.

2/ If "Restoration" mode is used, Greycstoration algorithm is used. (But here it's not the problem)

This is want mean than Digikam::Dimg::smoothScale() is not used in this tool (imlib2 based algorithm), and the bug is on CImg algorithm !!!

Sorry for the confusion. I really time to leaves the team...

Gilles





The resize bug is in CImg 

Comment 15 caulier.gilles 2007-11-16 08:14:50 UTC
SVN commit 737358 by cgilles:

digiKam from KDE3 branch: Image editor Resize tool in Simple Mode (not Restoration)

==> use CImg::resize() bicubic interpolation, not linear, witch will give normally a better result to resize an image to a smaller size

Feedback is welcome. Thanks in advance...

CCBUGS: 152192



 M  +1 -1      greycstorationiface.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&revision=737358
Comment 16 Arnd Baecker 2007-11-16 08:38:29 UTC
I checked with the original example, and it is still not good at all.
Does it work for you Gilles?
Important: also the "Restoration mode" produces the same type of horrible output!?

Independent of this, I think that Fabien's investigation, c#6 to c#10 above,
might lead to even better results
(in particular to allow for using a different algorithm for down-scaling
vs. up-scaling).
Maybe there is a possibility to make use of any of the existing codes?
Comment 17 caulier.gilles 2007-11-16 08:46:18 UTC
> Important: also the "Restoration mode" produces the same type of horrible output!? 

The restoration mode is completely different and not adapted to scaled-down an image, but to scaled-up... for ex. a very small picture to a huge picture.

I will add a text in dialog to warm users about this point...

Gilles
Comment 18 Arnd Baecker 2007-11-16 09:03:41 UTC
> I will add a text in dialog to warm users about this point...


That would be good - users like me don't read manuals
(or forget ...), or both ;-)
Comment 19 caulier.gilles 2007-11-16 10:41:22 UTC
SVN commit 737465 by cgilles:

add warning message on dialog about resize Restoration Mode 
CCBUGS: 152192


 M  +26 -18    imageresize.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&revision=737465
Comment 20 caulier.gilles 2007-11-18 09:17:46 UTC
To everybody witch use svn version of digiKam (KDE3 branch):

Please test again. no resize tool use a bicubic interpolation instead a simple linear interpolation (from CImg library)

Please give me a feedback. If all is fine now, this file will be closed...

Thanks in advance

Gilles Caulier
Comment 21 Arnd Baecker 2007-11-18 10:22:22 UTC
Gilles, nothing is fine for me, see c#16.
Does it work for you (taking the original example and scale down to 200x300,
looks really bad!)
Comment 22 caulier.gilles 2007-11-19 11:31:40 UTC
Arnd,

Yes, it still bad. I have tried to play with all parameter from CImg::resize(), but without better result.

Sound like a bug in CImg. I need to find another way to solve this problem

Gilles
Comment 23 caulier.gilles 2007-11-19 11:49:56 UTC
ok, this is the issue of this file: using DigiKam::DImg::resize() method witch use smoothScale algorithm (imlib2). Result is very similar than Gimp.

I will attach few images resized with different algorithm to compare.

And of course, i will commit changes in svn...

Gilles
Comment 24 caulier.gilles 2007-11-19 11:54:20 UTC
Created attachment 22116 [details]
Resized image using CImg::resize and bi-cubic interpolation
Comment 25 caulier.gilles 2007-11-19 11:54:47 UTC
Created attachment 22117 [details]
Resized image using CImg::resize and linear interpolation
Comment 26 caulier.gilles 2007-11-19 11:55:27 UTC
Created attachment 22118 [details]
Resized image using Gimp and linear interpolation
Comment 27 caulier.gilles 2007-11-19 11:56:35 UTC
Created attachment 22119 [details]
Resized image using Digikam::DImg::resize (modified smoothScale algorithm from imlib2 to support 16 bits color depth)
Comment 28 caulier.gilles 2007-11-19 11:57:56 UTC
Note : the original image is a PNG file using 16 bits color depth:

http://digikam3rdparty.free.fr/TEST_IMAGES/PNG/5-16bits-photo.png

gilles
Comment 29 caulier.gilles 2007-11-19 12:10:34 UTC
SVN commit 738645 by cgilles:

digiKam from KDE3 branch : With Simple resize mode, use DImg::resize() intead CImg::resize() to have the most image quality result.
CCBUGS: 152192


 M  +29 -21    imageresize.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&revision=738645
Comment 30 caulier.gilles 2007-11-19 12:28:01 UTC
SVN commit 738655 by cgilles:

backport commits #738645 from KDE3 branch
BUG: 152192


 M  +42 -32    imageresize.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&revision=738655
Comment 31 Cristian Tibirna 2007-11-19 12:46:20 UTC
This is most excellent. Thank you.
Comment 32 caulier.gilles 2007-11-21 09:54:06 UTC
To be clean in digiKam code about CImg, i have contacted David Tschumperlé (Cimg author) to have tips around this problem. 

Sound like we cannot use directly a simple CImg::resize(), but an iteration of progressive half resizements :

void GreycstorationIface::simpleResize()
{
    const unsigned int method = 3;      // Initial estimate (0, none, 1=block, 3=linear, 4=grid, 5=bicubic).

    int w = m_destImage.width();
    int h = m_destImage.height();

    while (d->img.dimx() > 2*w &&
           d->img.dimy() > 2*h)
    {
        d->img.resize_halfXY();
    }

    d->img.resize(w, h, -100, -100, method);
}

I have patched my Digikam::CImg interface and now result is similar than others algorithm...

Gilles... Who love clean code (:=)))
Comment 33 Mikolaj Machowski 2007-11-21 18:11:17 UTC
I wonder if it would be possible to put weak unsharp mask sharpening
between each resize. This is the best way to get good resize results,
especially big ones. Resize, USM (radius 1, amount - something small,
eg. 40%, threshold - 0 or 0.05 (when max is 1)), repeat.

OTOH this may be rather task for new batch queue editor.
Comment 34 Cristian Tibirna 2007-11-22 14:39:54 UTC
Re #33. I don't think so. Sharpening is a creative choice. But I think this is a thing to experiment with in the realm of configurable "advanced" resize, the kind that CImg offers if you choose to "restore image (slow)"  ;-)
Comment 35 Cristian Tibirna 2007-11-22 14:44:58 UTC
Bonjour Gilles, thanks again for the great work. 

Concerning #32, I'd compare the two methods before preferring clean code to good result code. The cimg-based method you describe in #32 might give still unsatisfying results because of blurring. I didn't try the code in my local digikam sources to thoroughly test, but I tried a few consecutive 50% resizes and the final image, while less jagged, is much more blurred than the screen-zoomed image. Thus, once again, the screen-zooming algorithm seems to be better than what cimg has to offer. So, just a bit of warning, if allowed...

Thanks again.
Comment 36 caulier.gilles 2007-11-22 15:05:56 UTC
Christian,

Don't be afraid, digiKam still to use the screen-zooming algorithm (imlib2 based + 16 bits color depth support). It more fast.

I have just patched the code in digiKam CImg interface to have a code ready to use in the future...if necessary.

Gilles
Comment 37 Kamil Stepinski 2008-03-16 11:26:26 UTC
Guys,

The image resizing quality is _really bad_ in digiKam (I have 0.9.2 installed).
It's so bad that the output is just unacceptable for me. :(

I really think you should add a selection box with a few algorithms (Hermite, Mitchell, Lanczos, etc.) with Lanczos as a default one because it provides the best results.
Currently I'm resizing all pictures with IrfanView (runs well with Wine) and the rest of postprocessing is done in digiKam. It's not the most convenient method but it works.
I think you should consider the current resize quality as a major issue - as it is a tool that is used very frequently.

Here's the link to the example of the resize quality comparison:

http://picasaweb.google.com/kamil.stepinski/Digikam/photo#5178275271094829746

Please observe car window edges.

1 - digiKam 0.9.2 to the left, IrfanView 4.10 to the right
2 - resizing from 5Mpix camera to 800x600, IrfanView is using Lanczos filter, digiKam is using I-don't-know-what.

That's the only major problem I have with digiKam. I think the resize has been working much better in 0.8.x version.

At the end -> Thanks guys for the great piece of software! The applications is really great!
Comment 38 caulier.gilles 2008-03-16 11:37:54 UTC
Kamil,

This problem have been fixed with 0.9.3 release. Please update digiKam....

Gilles Caulier