3232
3333from . import Image , ImageFile
3434
35+ if TYPE_CHECKING :
36+ from ._typing import CapsuleType
37+
3538# --------------------------------------------------------------------
3639# Check for Tkinter interface hooks
3740
38- _pilbitmap_ok = None
39-
40-
41- def _pilbitmap_check () -> int :
42- global _pilbitmap_ok
43- if _pilbitmap_ok is None :
44- try :
45- im = Image .new ("1" , (1 , 1 ))
46- tkinter .BitmapImage (data = f"PIL:{ im .im .id } " )
47- _pilbitmap_ok = 1
48- except tkinter .TclError :
49- _pilbitmap_ok = 0
50- return _pilbitmap_ok
51-
5241
5342def _get_image_from_kw (kw : dict [str , Any ]) -> ImageFile .ImageFile | None :
5443 source = None
@@ -62,18 +51,18 @@ def _get_image_from_kw(kw: dict[str, Any]) -> ImageFile.ImageFile | None:
6251
6352
6453def _pyimagingtkcall (
65- command : str , photo : PhotoImage | tkinter .PhotoImage , id : int
54+ command : str , photo : PhotoImage | tkinter .PhotoImage , ptr : CapsuleType
6655) -> None :
6756 tk = photo .tk
6857 try :
69- tk .call (command , photo , id )
58+ tk .call (command , photo , repr ( ptr ) )
7059 except tkinter .TclError :
7160 # activate Tkinter hook
7261 # may raise an error if it cannot attach to Tkinter
7362 from . import _imagingtk
7463
7564 _imagingtk .tkinit (tk .interpaddr ())
76- tk .call (command , photo , id )
65+ tk .call (command , photo , repr ( ptr ) )
7766
7867
7968# --------------------------------------------------------------------
@@ -142,7 +131,10 @@ def __init__(
142131 self .paste (image )
143132
144133 def __del__ (self ) -> None :
145- name = self .__photo .name
134+ try :
135+ name = self .__photo .name
136+ except AttributeError :
137+ return
146138 self .__photo .name = None
147139 try :
148140 self .__photo .tk .call ("image" , "delete" , name )
@@ -185,15 +177,14 @@ def paste(self, im: Image.Image) -> None:
185177 the bitmap image.
186178 """
187179 # convert to blittable
188- im .load ()
180+ ptr = im .getim ()
189181 image = im .im
190- if image .isblock () and im .mode == self .__mode :
191- block = image
192- else :
193- block = image .new_block (self .__mode , im .size )
182+ if not image .isblock () or im .mode != self .__mode :
183+ block = Image .core .new_block (self .__mode , im .size )
194184 image .convert2 (block , image ) # convert directly between buffers
185+ ptr = block .ptr
195186
196- _pyimagingtkcall ("PyImagingPhoto" , self .__photo , block . id )
187+ _pyimagingtkcall ("PyImagingPhoto" , self .__photo , ptr )
197188
198189
199190# --------------------------------------------------------------------
@@ -225,18 +216,13 @@ def __init__(self, image: Image.Image | None = None, **kw: Any) -> None:
225216 self .__mode = image .mode
226217 self .__size = image .size
227218
228- if _pilbitmap_check ():
229- # fast way (requires the pilbitmap booster patch)
230- image .load ()
231- kw ["data" ] = f"PIL:{ image .im .id } "
232- self .__im = image # must keep a reference
233- else :
234- # slow but safe way
235- kw ["data" ] = image .tobitmap ()
236- self .__photo = tkinter .BitmapImage (** kw )
219+ self .__photo = tkinter .BitmapImage (data = image .tobitmap (), ** kw )
237220
238221 def __del__ (self ) -> None :
239- name = self .__photo .name
222+ try :
223+ name = self .__photo .name
224+ except AttributeError :
225+ return
240226 self .__photo .name = None
241227 try :
242228 self .__photo .tk .call ("image" , "delete" , name )
@@ -273,9 +259,8 @@ def __str__(self) -> str:
273259def getimage (photo : PhotoImage ) -> Image .Image :
274260 """Copies the contents of a PhotoImage to a PIL image memory."""
275261 im = Image .new ("RGBA" , (photo .width (), photo .height ()))
276- block = im .im
277262
278- _pyimagingtkcall ("PyImagingPhotoGet" , photo , block . id )
263+ _pyimagingtkcall ("PyImagingPhotoGet" , photo , im . getim () )
279264
280265 return im
281266
0 commit comments