diff --git a/docs/releasenotes/2.7.0.rst b/docs/releasenotes/2.7.0.rst new file mode 100644 index 000000000..bf3f163f2 --- /dev/null +++ b/docs/releasenotes/2.7.0.rst @@ -0,0 +1,143 @@ +Pillow 2.7.0 +============ + +Image resizing filters +---------------------- + +Image resizing methods :py:meth:`~PIL.Image.Image.resize` and +:py:meth:`~PIL.Image.Image.thumbnail` take a `resample` argument, which tells +which filter should be used for resampling. Possible values are: +:py:attr:`PIL.Image.NEAREST`, :py:attr:`PIL.Image.BILINEAR`, +:py:attr:`PIL.Image.BICUBIC` and :py:attr:`PIL.Image.ANTIALIAS`. +Almost all of them were changed in this version. + +Bicubic and bilinear downscaling +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +From the beginning :py:attr:`~PIL.Image.BILINEAR` and +:py:attr:`~PIL.Image.BICUBIC` filters were based on affine transformations +and used a fixed number of pixels from the source image for every destination +pixel (2x2 pixels for :py:attr:`~PIL.Image.BILINEAR` and 4x4 for +:py:attr:`~PIL.Image.BICUBIC`). This gave an unsatisfactory result for +downscaling. At the same time, a high quality convolutions-based algorithm with +flexible kernel was used for :py:attr:`~PIL.Image.ANTIALIAS` filter. + +Starting from Pillow 2.7.0, a high quality convolutions-based algorithm is used +for all of these three filters. + +If you have previously used any tricks to maintain quality when downscaling with +:py:attr:`~PIL.Image.BILINEAR` and :py:attr:`~PIL.Image.BICUBIC` filters +(for example, reducing within several steps), they are unnecessary now. + +Antialias renamed to Lanczos +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A new :py:attr:`PIL.Image.LANCZOS` constant was added instead of +:py:attr:`~PIL.Image.ANTIALIAS`. + +When :py:attr:`~PIL.Image.ANTIALIAS` was initially added, it was the only +high-quality filter based on convolutions. It's name was supposed to reflect +this. Starting from Pillow 2.7.0 all resize method are based on convolutions. +All of them are antialias from now on. And the real name of the +:py:attr:`~PIL.Image.ANTIALIAS` filter is Lanczos filter. + +The :py:attr:`~PIL.Image.ANTIALIAS` constant is left for backward compatibility +and is an alias for :py:attr:`~PIL.Image.LANCZOS`. + +Lanczos upscaling quality +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The image upscaling quality with :py:attr:`~PIL.Image.LANCZOS` filter was +almost the same as :py:attr:`~PIL.Image.BILINEAR` due to bug. This has been fixed. + +Bicubic upscaling quality +^^^^^^^^^^^^^^^^^^^^^^^^^ + +The :py:attr:`~PIL.Image.BICUBIC` filter for affine transformations produced +sharp, slightly pixelated image for upscaling. Bicubic for convolutions is +more soft. + +Resize performance +^^^^^^^^^^^^^^^^^^ + +In most cases, convolution is more a expensive algorithm for downscaling +because it takes into account all the pixels of source image. Therefore +:py:attr:`~PIL.Image.BILINEAR` and :py:attr:`~PIL.Image.BICUBIC` filters' +performance can be lower than before. On the other hand the quality of +:py:attr:`~PIL.Image.BILINEAR` and :py:attr:`~PIL.Image.BICUBIC` was close to +:py:attr:`~PIL.Image.NEAREST`. So if such quality is suitable for your tasks +you can switch to :py:attr:`~PIL.Image.NEAREST` filter for downscaling, +which will give a huge improvement in performance. + +At the same time performance of convolution resampling for downscaling has been +improved by around a factor of two compared to the previous version. +The upscaling performance of the :py:attr:`~PIL.Image.LANCZOS` filter has +remained the same. For :py:attr:`~PIL.Image.BILINEAR` filter it has improved by +1.5 times and for :py:attr:`~PIL.Image.BICUBIC` by four times. + +Default filter for thumbnails +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In Pillow 2.5 the default filter for :py:meth:`~PIL.Image.Image.thumbnail` was +changed from :py:attr:`~PIL.Image.NEAREST` to :py:attr:`~PIL.Image.ANTIALIAS`. +Antialias was chosen because all the other filters gave poor quality for +reduction. Starting from Pillow 2.7.0, :py:attr:`~PIL.Image.ANTIALIAS` has been +replaced with :py:attr:`~PIL.Image.BICUBIC`, because it's faster and +:py:attr:`~PIL.Image.ANTIALIAS` doesn't give any advantages after +downscaling with libjpeg, which uses supersampling internally, not convolutions. + +Image transposition +------------------- + +A new method :py:attr:`PIL.Image.TRANSPOSE` has been added for the +:py:meth:`~PIL.Image.Image.transpose` operation in addition to +:py:attr:`~PIL.Image.FLIP_LEFT_RIGHT`, :py:attr:`~PIL.Image.FLIP_TOP_BOTTOM`, +:py:attr:`~PIL.Image.ROTATE_90`, :py:attr:`~PIL.Image.ROTATE_180`, +:py:attr:`~PIL.Image.ROTATE_270`. :py:attr:`~PIL.Image.TRANSPOSE` is an algebra +transpose, with an image reflected across its main diagonal. + +The speed of :py:attr:`~PIL.Image.ROTATE_90`, :py:attr:`~PIL.Image.ROTATE_270` +and :py:attr:`~PIL.Image.TRANSPOSE` has been significantly improved for large +images which don't fit in the processor cache. + +Gaussian blur and unsharp mask +------------------------------ + +The :py:meth:`~PIL.ImageFilter.GaussianBlur` implementation has been replaced +with a sequential application of box filters. The new implementation is based on +"Theoretical foundations of Gaussian convolution by extended box filtering" from +the Mathematical Image Analysis Group. As :py:meth:`~PIL.ImageFilter.UnsharpMask` +implementations use Gaussian blur internally, all changes from this chapter +are also applicable to it. + +Blur radius +^^^^^^^^^^^ + +There was an error in the previous version of Pillow, where blur radius (the +standard deviation of Gaussian) actually meant blur diameter. For example, to +blur an image with actual radius 5 you were forced to use value 10. This has +been fixed. Now the meaning of the radius is the same as in other software. + +If you used a Gaussian blur with some radius value, you need to divide this +value by two. + +Blur performance +^^^^^^^^^^^^^^^^ + +Box filter computation time is constant relative to the radius and depends +on source image size only. Because the new Gaussian blur implementation +is based on box filter, its computation time also doesn't depends on the blur +radius. + +For example, previously, if the execution time for a given test image was 1 +second for radius 1, 3.6 seconds for radius 10 and 17 seconds for 50, now blur +with any radius on same image is executed for 0.2 seconds. + +Blur quality +^^^^^^^^^^^^ + +The previous implementation takes into account only source pixels within +2 * standard deviation radius for every destination pixel. This was not enough, +so the quality was worse compared to other Gaussian blur software. + +The new implementation does not have this drawback. diff --git a/docs/releasenotes/2.7.rst b/docs/releasenotes/2.7.rst deleted file mode 100644 index 8b6daab6c..000000000 --- a/docs/releasenotes/2.7.rst +++ /dev/null @@ -1,144 +0,0 @@ -Pillow 2.7 -========== - -Image resizing filters ----------------------- - -Image resizing methods :py:meth:`~PIL.Image.Image.resize` and -:py:meth:`~PIL.Image.Image.thumbnail` takes `resample` argument, which tells -what filter should be used for resampling. Possible values are: -:py:attr:`PIL.Image.NEAREST`, :py:attr:`PIL.Image.BILINEAR`, -:py:attr:`PIL.Image.BICUBIC` and :py:attr:`PIL.Image.ANTIALIAS`. -Almost all of them was changed in this version. - -Bicubic and Bilinear downscaling -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -From very begining :py:attr:`~PIL.Image.BILINEAR` and -:py:attr:`~PIL.Image.BICUBIC` filters was based on affine transformations -and uses fixed number of pixels from source image for every destination pixel -(that was 2x2 pixels for :py:attr:`~PIL.Image.BILINEAR` and 4x4 for -:py:attr:`~PIL.Image.BICUBIC`). This gave an unsatisfied result for downscaling. -At the same time high quality convolutions-based algorithm with flexible kernel -was used for :py:attr:`~PIL.Image.ANTIALIAS` filter). - -Starting from 2.7 high quality convolutions-based algorithm is used for all of -these three filters. - -If you have previously used any tricks to maintain quality when downscaling with -:py:attr:`~PIL.Image.BILINEAR` and :py:attr:`~PIL.Image.BICUBIC` filters -(for example, reducing within several steps), they a unnecessary now. - -Antialias renamed to Lanczos -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -New :py:attr:`PIL.Image.LANCZOS` constant was added instead of -:py:attr:`~PIL.Image.ANTIALIAS`. - -When :py:attr:`~PIL.Image.ANTIALIAS` was initially added, it was the only -high-quality filter based on convolutions. It's name was supposed to reflect -this. Starting from 2.7 all resize method are based on convolutions. All of them -are antialias from now. And the real name of :py:attr:`~PIL.Image.ANTIALIAS` -filter is Lanczos filter. - -:py:attr:`~PIL.Image.ANTIALIAS` constant is leaved for backward compatibility -and is an alias for :py:attr:`~PIL.Image.LANCZOS`. - -Lanczos upscaling quality -^^^^^^^^^^^^^^^^^^^^^^^^^ - -Image upscaling quality with :py:attr:`~PIL.Image.LANCZOS` filter was almost -the same as :py:attr:`~PIL.Image.BILINEAR` due to bug. This was fixed. - -Bicubic upscaling quality -^^^^^^^^^^^^^^^^^^^^^^^^^ - -:py:attr:`~PIL.Image.BICUBIC` filter for affine transformations produced -sharp, slightly pixelated image for upscaling. Bicubic for convolutions is -more soft. - -Resize performance -^^^^^^^^^^^^^^^^^^ - -In most cases convolution is more expensive algorithm for downscaling because -it takes in account all pixels of source image. Therefore -:py:attr:`~PIL.Image.BILINEAR` and :py:attr:`~PIL.Image.BICUBIC` filters -performance can be lower than before. On the other hand quality of -:py:attr:`~PIL.Image.BILINEAR` and :py:attr:`~PIL.Image.BICUBIC` was close to -:py:attr:`~PIL.Image.NEAREST`. So if such quality is suitable for your task -you can switch to :py:attr:`~PIL.Image.NEAREST` filter for downscaling, -that will give huge win in performance. - -At the same time performance of convolution resampling for downscaling was -improved in about two times compared to previous version. -Upscaling performance of :py:attr:`~PIL.Image.LANCZOS` filter remained the same. -For :py:attr:`~PIL.Image.BILINEAR` filter it grew in 1.5 times and -for :py:attr:`~PIL.Image.BICUBIC` in 4 times. - -Default filter for thumbnails -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -In Pillow 2.5 default filter for :py:meth:`~PIL.Image.Image.thumbnail` was -changed from :py:attr:`~PIL.Image.NEAREST` to :py:attr:`~PIL.Image.ANTIALIAS`. -Antialias was chosen because all other filters gave poor quality for reduction. -Starting from Pillow 2.7 :py:attr:`~PIL.Image.ANTIALIAS` replaced with -:py:attr:`~PIL.Image.BICUBIC`, because it faster and -:py:attr:`~PIL.Image.ANTIALIAS` doesn't give any advantages after -downscaling with libJPEG, which uses supersampling internally, not convolutions. - -Image transposing ------------------ - -New method :py:attr:`PIL.Image.TRANSPOSE` was added for -:py:meth:`~PIL.Image.Image.transpose` operation in addition to -:py:attr:`~PIL.Image.FLIP_LEFT_RIGHT`, :py:attr:`~PIL.Image.FLIP_TOP_BOTTOM`, -:py:attr:`~PIL.Image.ROTATE_90`, :py:attr:`~PIL.Image.ROTATE_180`, -:py:attr:`~PIL.Image.ROTATE_270`. :py:attr:`~PIL.Image.TRANSPOSE` is algebra -transpose, when image reflected over its main diagonal. - -Speed of :py:attr:`~PIL.Image.ROTATE_90`, :py:attr:`~PIL.Image.ROTATE_270` -and :py:attr:`~PIL.Image.TRANSPOSE` was significantly improved for large images, -which doesn't fit in processor cache. - -Gaussian blur and unsharp mask ------------------------------- - -:py:meth:`~PIL.ImageFilter.GaussianBlur` implementation was replaced with -sequential applying of series of box filters. New implementation is based on -"Theoretical foundations of Gaussian convolution by extended box filtering" from -Mathematical Image Analysis Group. As :py:meth:`~PIL.ImageFilter.UnsharpMask` -implementations uses Gaussian blur internally, all changes from this chapter -also applicable to it. - -Blur radius -^^^^^^^^^^^ - -There was an error in previous version of PIL, when blur radius (the standard -deviation of Gaussian) is actually meant blur diameter. -For example for blurring image with actual radius 5 you were forced -to use value 10. This was fixed. For now the meaning of the radius -is the same as in other software. - -If you used a Gaussian blur with some radius value, you need to divide this -value by two. - -Blur Performance -^^^^^^^^^^^^^^^^ - -Box filter computation time is constant relative to the radius and depends -on source image size only. Because new Gaussian blur implementation -is based on box filter, it's computation time is also doesn't depends on blur -radius. - -If before execution time for the same test image was 1 second for radius 1, -3.6 seconds for radius 10, 17 seconds for 50. Now blur with any radius on same -image is executed for 0.2 seconds. - -Blur quality -^^^^^^^^^^^^ - -Previous implementation takes in account only source pixels within -2 * standard deviation radius for every destination pixel. This was not enough, -so quality was worse compared to other Gaussian blur software. - -The new implementation does not have this drawback. diff --git a/docs/releasenotes/index.rst b/docs/releasenotes/index.rst index ce3bfe9bf..c2f95f670 100644 --- a/docs/releasenotes/index.rst +++ b/docs/releasenotes/index.rst @@ -4,4 +4,4 @@ Release Notes .. toctree:: :maxdepth: 2 - 2.7 + 2.7.0