5151 pixels_as_float ,
5252 pixels_as_ubyte ,
5353 pixels_as_uint ,
54+ resize_width_height ,
5455)
5556
5657SymbolColorQuantize = Symbol ("ColorQuantize" )
8586from io import BytesIO
8687
8788# The following classes are used to allow inclusion of
88- # Buultin Functions only when certain Python packages
89+ # Builtin Functions only when certain Python packages
8990# are available. They do this by setting the `requires` class variable.
9091
9192
@@ -399,7 +400,6 @@ def eval(self, minval, maxval, w, h, evaluation, options):
399400
400401class ImageResize (_ImageBuiltin ):
401402 """
402-
403403 <url>:WMA link:https://reference.wolfram.com/language/ref/ImageResize.html</url>
404404
405405 <dl>
@@ -410,38 +410,37 @@ class ImageResize(_ImageBuiltin):
410410 <dd>
411411 </dl>
412412
413- S> ein = Import["ExampleData/Einstein.jpg"]
414- = -Image-
415-
416- S> ImageDimensions[ein]
417- = {615, 768}
418- S> ImageResize[ein, {400, 600}]
419- = -Image-
420- S> ImageDimensions[%]
421- = {400, 600}
422-
423- S> ImageResize[ein, {256}]
424- = -Image-
425-
426- S> ImageDimensions[%]
427- = {256, 256}
428-
429413 The Resampling option can be used to specify how to resample the image. Options are:
430414 <ul>
431415 <li>Automatic
432416 <li>Bicubic
433- <li>Gaussian
417+ <li>Bilinear
418+ <li>Box
419+ <li>Hamming
420+ <li>Lanczos
434421 <li>Nearest
435422 </ul>
436423
437- The default sampling method is Bicubic.
424+ See <url>
425+ :Pillow Filters:
426+ https://pillow.readthedocs.io/en/stable/handbook/concepts.html#filters</url>\
427+ for a description of these.
438428
439- S> ImageResize[ein, 256, Resampling -> "Bicubic "]
429+ S> alice = Import["ExampleData/MadTeaParty.gif "]
440430 = -Image-
441431
442- S> ImageResize[ein, 256, Resampling -> "Gaussian"]
443- = ...
444- : ...
432+ S> shape = ImageDimensions[alice]
433+ = {640, 487}
434+
435+ S> ImageResize[alice, shape / 2]
436+ = -Image-
437+
438+ The default sampling method is "Bicubic" which has pretty good upscaling \
439+ and downscaling quality. However "Box" is the fastest:
440+
441+
442+ S> ImageResize[alice, shape / 2, Resampling -> "Box"]
443+ = -Image-
445444 """
446445
447446 messages = {
@@ -480,7 +479,7 @@ def eval_resize_width_height(self, image, width, height, evaluation, options):
480479 ):
481480 resampling_name = "Bicubic"
482481 else :
483- resampling_name = resampling .get_string_value ()
482+ resampling_name = resampling .value
484483
485484 # find new size
486485 old_w , old_h = image .pixels .shape [1 ], image .pixels .shape [0 ]
@@ -507,66 +506,14 @@ def eval_resize_width_height(self, image, width, height, evaluation, options):
507506 h , w = int (round (h )), int (round (w ))
508507
509508 # perform the resize
510- if resampling_name == "Nearest" :
511- return image .filter (
512- lambda im : im .resize ((w , h ), resample = PIL .Image .NEAREST )
513- )
514- elif resampling_name == "Bicubic" :
515- # After Python 3.6 support is dropped, this can be simplified
516- # to for Pillow 9+ and use PIL.Image.Resampling.BICUBIC only.
517- bicubic = (
518- PIL .Image .Resampling .BICUBIC
519- if hasattr (PIL .Image , "Resampling" )
520- else PIL .Image .BICUBIC
521- )
522- return image .filter (lambda im : im .resize ((w , h ), resample = bicubic ))
523- elif resampling_name != "Gaussian" :
524- return evaluation .message ("ImageResize" , "imgrsm" , resampling )
525-
526- try :
527- from skimage import __version__ as skimage_version , transform
528-
529- multichannel = image .pixels .ndim == 3
530-
531- sy = h / old_h
532- sx = w / old_w
533- if sy > sx :
534- err = abs ((sy * old_w ) - (sx * old_w ))
535- s = sy
536- else :
537- err = abs ((sy * old_h ) - (sx * old_h ))
538- s = sx
539- if err > 1.5 :
540- # TODO overcome this limitation
541- return evaluation .message ("ImageResize" , "gaussaspect" )
542- elif s > 1 :
543- pixels = transform .pyramid_expand (
544- image .pixels , upscale = s , multichannel = multichannel
545- ).clip (0 , 1 )
546- else :
547- kwargs = {"downscale" : (1.0 / s )}
548- # scikit_image in version 0.19 changes the resize parameter deprecating
549- # "multichannel". scikit_image also doesn't support older Pythons like 3.6.15.
550- # If we drop suport for 3.6 we can probably remove
551- if skimage_version >= "0.19" :
552- # Not totally sure that we want channel_axis=1, but it makes the
553- # test work. multichannel is deprecated in scikit-image-19.2
554- # Previously we used multichannel (=3)
555- # as in the above s > 1 case.
556- kwargs ["channel_axis" ] = 2
557- else :
558- kwargs ["multichannel" ] = multichannel
559-
560- pixels = transform .pyramid_reduce (image .pixels , ** kwargs ).clip (0 , 1 )
561-
562- return Image (pixels , image .color_space )
563- except ImportError :
564- evaluation .message ("ImageResize" , "skimage" )
509+ return resize_width_height (image , w , h , resampling_name , evaluation )
565510
566511
567512class ImageReflect (_ImageBuiltin ):
568513 """
569- <url>:WMA link:https://reference.wolfram.com/language/ref/ImageReflect.html</url>
514+ <url>
515+ :WMA link:
516+ https://reference.wolfram.com/language/ref/ImageReflect.html</url>
570517 <dl>
571518 <dt>'ImageReflect[$image$]'
572519 <dd>Flips $image$ top to bottom.
0 commit comments