.. method:: data(format=None, *, from_coords=None, background=None, \
- grayscale=False)
+ grayscale=False, metadata=None)
Return the image data.
If *grayscale* is true, the data does not contain color information; all
pixel data is transformed into grayscale.
+ *metadata* is a dictionary passed to the image format driver.
+ It requires Tcl/Tk 9.0 or newer.
+
.. versionadded:: 3.13
+ .. versionchanged:: next
+ Added the *metadata* parameter.
+
- .. method:: get(x, y)
+ .. method:: get(x, y, *, withalpha=False)
Return the color of the pixel at coordinates (*x*, *y*) as an
``(r, g, b)`` tuple of three integers between 0 and 255, representing the
red, green and blue components respectively.
+ If *withalpha* is true, the returned tuple has a fourth element giving
+ the alpha (opacity) value of the pixel.
+
+ .. versionchanged:: next
+ Added the *withalpha* parameter, which requires Tcl/Tk 9.0 or newer.
- .. method:: put(data, to=None)
+ .. method:: put(data, to=None, *, format=None, metadata=None)
Set pixels of the image to the colors given in *data*, which must be a
string or a nested sequence of horizontal rows of pixel colors (for
bottom-right corner, of the region.
The default position is ``(0, 0)``.
+ *format* specifies the format of the image *data*, so that only image
+ file format handlers whose names begin with it are tried.
+
+ *metadata* is a dictionary passed to the image format driver.
+ It requires Tcl/Tk 9.0 or newer.
+
+ .. versionchanged:: next
+ Added the *format* and *metadata* parameters.
+
.. method:: read(filename, format=None, *, from_coords=None, to=None, \
- shrink=False)
+ shrink=False, metadata=None)
Read image data from the file named *filename* into the image.
*format* specifies the format of the image data in the file.
+ *metadata* is a dictionary passed to the image format driver.
+ It requires Tcl/Tk 9.0 or newer.
+
*from_coords* specifies a rectangular sub-region of the image file data
to be copied to the destination image.
It must be a tuple or a list of 1 to 4 integers ``(x1, y1, x2, y2)``.
.. versionadded:: 3.13
+ .. versionchanged:: next
+ Added the *metadata* parameter.
+
.. method:: subsample(x, y='', *, from_coords=None)
.. method:: write(filename, format=None, from_coords=None, *, \
- background=None, grayscale=False)
+ background=None, grayscale=False, metadata=None)
Write image data from the image to the file named *filename*.
If *grayscale* is true, the data does not contain color information; all
pixel data is transformed into grayscale.
+ *metadata* is a dictionary passed to the image format driver.
+ It requires Tcl/Tk 9.0 or newer.
+
.. versionchanged:: 3.13
Added the *background* and *grayscale* parameters.
+ .. versionchanged:: next
+ Added the *metadata* parameter.
+
.. method:: zoom(x, y='', *, from_coords=None)
badge) and :meth:`~tkinter.Wm.wm_stackorder` (toplevel stacking order).
(Contributed by Serhiy Storchaka in :gh:`151874`.)
+* Added support for more options in :class:`!tkinter.PhotoImage` methods: the
+ *format* parameter of :meth:`~tkinter.PhotoImage.put`, the *metadata*
+ parameter of :meth:`~tkinter.PhotoImage.put`, :meth:`~tkinter.PhotoImage.read`,
+ :meth:`~tkinter.PhotoImage.write` and :meth:`~tkinter.PhotoImage.data`, and
+ the *withalpha* parameter of :meth:`~tkinter.PhotoImage.get`.
+ (Contributed by Serhiy Storchaka in :gh:`151890`.)
+
* Added the :meth:`~tkinter.PhotoImage.redither` method which recalculates the
dithered image when its data was supplied in pieces.
(Contributed by Serhiy Storchaka in :gh:`151888`.)
self.assertEqual(image.get(0, 1), self.colorlist(0, 0, 255))
self.assertEqual(image.get(1, 1), self.colorlist(255, 255, 0))
+ def test_put_format(self):
+ image = self.create()
+ with open(self.testfile, 'rb') as f:
+ data = f.read()
+ image2 = tkinter.PhotoImage(master=self.root)
+ image2.put(data, format='gif')
+ self.assertEqual(image2.width(), 16)
+ self.assertEqual(image2.height(), 16)
+ self.assertEqual(image2.get(4, 6), image.get(4, 6))
+
def test_get(self):
image = self.create()
self.assertEqual(image.get(4, 6), self.colorlist(62, 116, 162))
self.assertRaises(tkinter.TclError, image.get, 16, 15)
self.assertRaises(tkinter.TclError, image.get, 15, 16)
+ @requires_tk(9, 0)
+ def test_get_withalpha(self):
+ image = self.create()
+ rgb = image.get(4, 6)
+ rgba = image.get(4, 6, withalpha=True)
+ if self.wantobjects:
+ self.assertEqual(rgba[:3], rgb)
+ self.assertEqual(len(rgba), 4)
+ self.assertIn(rgba[3], (0, 255)) # GIF alpha is fully on or off
+ else:
+ self.assertTrue(rgba.startswith(rgb + ' '))
+
+ @requires_tk(9, 0)
+ def test_metadata(self):
+ image = self.create()
+ # The -metadata configuration option holds the image's metadata.
+ image.configure(metadata=('Comment', 'spam'))
+ self.assertIn('Comment', str(image.cget('metadata')))
+ # put() and data() accept a metadata dictionary, passed to the image
+ # format driver. put() does not change the image's own metadata.
+ image.put('{red green} {blue yellow}', metadata={'Comment': 'spam'})
+ self.assertTrue(image.data(metadata={'Comment': 'spam'}))
+
def test_read(self):
# Due to the Tk bug https://core.tcl-lang.org/tk/tktview/1576528
# the -from option does not work correctly for GIF and PNG files.
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."""
- return self.tk.call(self.name, 'get', x, y)
+ @staticmethod
+ def _metadata(metadata):
+ # A Tcl dict is a flat list of alternating keys and values. A Python
+ # dict passed directly would expand to its keys only, so flatten it.
+ flat = ()
+ for key, value in metadata.items():
+ flat += (key, value)
+ return flat
+
+ def get(self, x, y, *, withalpha=False):
+ """Return the color of the pixel at X,Y as a tuple of its red, green
+ and blue components.
+
+ If WITHALPHA is true, the returned tuple has a fourth element giving
+ the alpha (opacity) value of the pixel. This requires Tcl/Tk 9.0 or
+ newer.
+ """
+ args = (self.name, 'get', x, y)
+ if withalpha:
+ args += ('-withalpha',)
+ return self.tk.call(args)
- def put(self, data, to=None):
+ def put(self, data, to=None, *, format=None, metadata=None):
"""Put row formatted colors to image starting from
- position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))"""
+ position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))
+
+ The FORMAT option specifies the format of the image DATA, so that only
+ image file format handlers whose names begin with it are tried.
+
+ The METADATA option, a dictionary passed to the image format driver,
+ requires Tcl/Tk 9.0 or newer.
+ """
args = (self.name, 'put', data)
+ if format is not None:
+ args += ('-format', format)
+ if metadata is not None:
+ args += ('-metadata', self._metadata(metadata))
if to:
if to[0] == '-to':
to = to[1:]
- args = args + ('-to',) + tuple(to)
+ args += ('-to',) + tuple(to)
self.tk.call(args)
- def read(self, filename, format=None, *, from_coords=None, to=None, shrink=False):
+ def read(self, filename, format=None, *, from_coords=None, to=None,
+ shrink=False, metadata=None):
"""Reads image data from the file named FILENAME into the image.
The FORMAT option specifies the format of the image data in the
file.
+ The METADATA option, a dictionary passed to the image format driver,
+ requires Tcl/Tk 9.0 or newer.
+
The FROM_COORDS option specifies a rectangular sub-region of the image
file data to be copied to the destination image. It must be a tuple
or a list of 1 to 4 integers (x1, y1, x2, y2). (x1, y1) and
options = ()
if format is not None:
options += ('-format', format)
+ if metadata is not None:
+ options += ('-metadata', self._metadata(metadata))
if from_coords is not None:
options += ('-from', *from_coords)
if shrink:
self.tk.call(self.name, 'read', filename, *options)
def write(self, filename, format=None, from_coords=None, *,
- background=None, grayscale=False):
+ background=None, grayscale=False, metadata=None):
"""Writes image data from the image to a file named FILENAME.
The FORMAT option specifies the name of the image file format
handler to be used to write the data to the file. If this option
is not given, the format is guessed from the file extension.
+ The METADATA option, a dictionary passed to the image format driver,
+ requires Tcl/Tk 9.0 or newer.
+
The FROM_COORDS option specifies a rectangular region of the image
to be written to the image file. It must be a tuple or a list of 1
to 4 integers (x1, y1, x2, y2). If only x1 and y1 are specified,
options = ()
if format is not None:
options += ('-format', format)
+ if metadata is not None:
+ options += ('-metadata', self._metadata(metadata))
if from_coords is not None:
options += ('-from', *from_coords)
if grayscale:
self.tk.call(self.name, 'write', filename, *options)
def data(self, format=None, *, from_coords=None,
- background=None, grayscale=False):
+ background=None, grayscale=False, metadata=None):
"""Returns image data.
+ The METADATA option, a dictionary passed to the image format driver,
+ requires Tcl/Tk 9.0 or newer.
+
The FORMAT option specifies the name of the image file format
handler to be used. If this option is not given, this method uses
a format that consists of a tuple (one element per row) of strings
options = ()
if format is not None:
options += ('-format', format)
+ if metadata is not None:
+ options += ('-metadata', self._metadata(metadata))
if from_coords is not None:
options += ('-from', *from_coords)
if grayscale:
--- /dev/null
+Add the *format* parameter to the :meth:`tkinter.PhotoImage.put` method, the
+*metadata* parameter to the :meth:`~tkinter.PhotoImage.put`,
+:meth:`~tkinter.PhotoImage.read`, :meth:`~tkinter.PhotoImage.write` and
+:meth:`~tkinter.PhotoImage.data` methods, and the *withalpha* parameter to the
+:meth:`~tkinter.PhotoImage.get` method. The *metadata* and *withalpha*
+parameters require Tcl/Tk 9.0 or newer.