summaryrefslogtreecommitdiffstats
path: root/Lib/tkinter
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2024-05-06 14:33:15 (GMT)
committerGitHub <noreply@github.com>2024-05-06 14:33:15 (GMT)
commit1b639a04cab0e858d90e2ac459fb34b73700701f (patch)
treea76e34ec01d564451def7ddbe8dc7da2940848c0 /Lib/tkinter
parent09871c922393cba4c85bc29d210d76425e076c1d (diff)
downloadcpython-1b639a04cab0e858d90e2ac459fb34b73700701f.zip
cpython-1b639a04cab0e858d90e2ac459fb34b73700701f.tar.gz
cpython-1b639a04cab0e858d90e2ac459fb34b73700701f.tar.bz2
gh-118225: Support more options for copying images in Tkinter (GH-118228)
* Add the PhotoImage method copy_replace() to copy a region from one image to other image, possibly with pixel zooming and/or subsampling. * Add from_coords parameter to PhotoImage methods copy(), zoom() and subsample(). * Add zoom and subsample parameters to PhotoImage method copy().
Diffstat (limited to 'Lib/tkinter')
-rw-r--r--Lib/tkinter/__init__.py111
1 files changed, 95 insertions, 16 deletions
diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py
index 70a1ed4..35da831 100644
--- a/Lib/tkinter/__init__.py
+++ b/Lib/tkinter/__init__.py
@@ -4278,33 +4278,112 @@ class PhotoImage(Image):
def __getitem__(self, key):
return self.tk.call(self.name, 'cget', '-' + key)
- # XXX copy -from, -to, ...?
- def copy(self):
- """Return a new PhotoImage with the same image as this widget."""
+ def copy(self, *, from_coords=None, zoom=None, subsample=None):
+ """Return a new PhotoImage with the same image as this widget.
+
+ The FROM_COORDS option specifies a rectangular sub-region of the
+ source image to be copied. It must be a tuple or a list of 1 to 4
+ integers (x1, y1, x2, y2). (x1, y1) and (x2, y2) specify diagonally
+ opposite corners of the rectangle. If x2 and y2 are not specified,
+ the default value is the bottom-right corner of the source image.
+ The pixels copied will include the left and top edges of the
+ specified rectangle but not the bottom or right edges. If the
+ FROM_COORDS option is not given, the default is the whole source
+ image.
+
+ If SUBSAMPLE or ZOOM are specified, the image is transformed as in
+ the subsample() or zoom() methods. The value must be a single
+ integer or a pair of integers.
+ """
destImage = PhotoImage(master=self.tk)
- self.tk.call(destImage, 'copy', self.name)
+ destImage.copy_replace(self, from_coords=from_coords,
+ zoom=zoom, subsample=subsample)
return destImage
- def zoom(self, x, y=''):
+ def zoom(self, x, y='', *, from_coords=None):
"""Return a new PhotoImage with the same image as this widget
- but zoom it with a factor of x in the X direction and y in the Y
- direction. If y is not given, the default value is the same as x.
+ but zoom it with a factor of X in the X direction and Y in the Y
+ direction. If Y is not given, the default value is the same as X.
+
+ The FROM_COORDS option specifies a rectangular sub-region of the
+ source image to be copied, as in the copy() method.
"""
- destImage = PhotoImage(master=self.tk)
if y=='': y=x
- self.tk.call(destImage, 'copy', self.name, '-zoom',x,y)
- return destImage
+ return self.copy(zoom=(x, y), from_coords=from_coords)
- def subsample(self, x, y=''):
+ def subsample(self, x, y='', *, from_coords=None):
"""Return a new PhotoImage based on the same image as this widget
- but use only every Xth or Yth pixel. If y is not given, the
- default value is the same as x.
+ but use only every Xth or Yth pixel. If Y is not given, the
+ default value is the same as X.
+
+ The FROM_COORDS option specifies a rectangular sub-region of the
+ source image to be copied, as in the copy() method.
"""
- destImage = PhotoImage(master=self.tk)
if y=='': y=x
- self.tk.call(destImage, 'copy', self.name, '-subsample',x,y)
- return destImage
+ return self.copy(subsample=(x, y), from_coords=from_coords)
+
+ def copy_replace(self, sourceImage, *, from_coords=None, to=None, shrink=False,
+ zoom=None, subsample=None, compositingrule=None):
+ """Copy a region from the source image (which must be a PhotoImage) to
+ this image, possibly with pixel zooming and/or subsampling. If no
+ options are specified, this command copies the whole of the source
+ image into this image, starting at coordinates (0, 0).
+
+ The FROM_COORDS option specifies a rectangular sub-region of the
+ source image to be copied. It must be a tuple or a list of 1 to 4
+ integers (x1, y1, x2, y2). (x1, y1) and (x2, y2) specify diagonally
+ opposite corners of the rectangle. If x2 and y2 are not specified,
+ the default value is the bottom-right corner of the source image.
+ The pixels copied will include the left and top edges of the
+ specified rectangle but not the bottom or right edges. If the
+ FROM_COORDS option is not given, the default is the whole source
+ image.
+
+ The TO option specifies a rectangular sub-region of the destination
+ image to be affected. It must be a tuple or a list of 1 to 4
+ integers (x1, y1, x2, y2). (x1, y1) and (x2, y2) specify diagonally
+ opposite corners of the rectangle. If x2 and y2 are not specified,
+ the default value is (x1,y1) plus the size of the source region
+ (after subsampling and zooming, if specified). If x2 and y2 are
+ specified, the source region will be replicated if necessary to fill
+ the destination region in a tiled fashion.
+
+ If SHRINK is true, the size of the destination image should be
+ reduced, if necessary, so that the region being copied into is at
+ the bottom-right corner of the image.
+
+ If SUBSAMPLE or ZOOM are specified, the image is transformed as in
+ the subsample() or zoom() methods. The value must be a single
+ integer or a pair of integers.
+
+ The COMPOSITINGRULE option specifies how transparent pixels in the
+ source image are combined with the destination image. When a
+ compositing rule of 'overlay' is set, the old contents of the
+ destination image are visible, as if the source image were printed
+ on a piece of transparent film and placed over the top of the
+ destination. When a compositing rule of 'set' is set, the old
+ contents of the destination image are discarded and the source image
+ is used as-is. The default compositing rule is 'overlay'.
+ """
+ options = []
+ if from_coords is not None:
+ options.extend(('-from', *from_coords))
+ if to is not None:
+ options.extend(('-to', *to))
+ if shrink:
+ options.append('-shrink')
+ if zoom is not None:
+ if not isinstance(zoom, (tuple, list)):
+ zoom = (zoom,)
+ options.extend(('-zoom', *zoom))
+ if subsample is not None:
+ if not isinstance(subsample, (tuple, list)):
+ subsample = (subsample,)
+ options.extend(('-subsample', *subsample))
+ if compositingrule:
+ options.extend(('-compositingrule', compositingrule))
+ self.tk.call(self.name, 'copy', sourceImage, *options)
def get(self, x, y):
"""Return the color (red, green, blue) of the pixel at X,Y."""