@@ -278,8 +278,13 @@ def worst_tile_contrast(
278278 tile_size : int ,
279279) -> TiledContrastMeasurement | None :
280280 """Measure the lowest text-pixel contrast across tiled samples."""
281+ if tile_size <= 0 :
282+ raise ValueError ("tile_size must be positive" )
283+
281284 foreground_alpha = foreground_image .getchannel ("A" ).point (lambda value : 255 if value else 0 )
282- tile_count = _tile_count (region , tile_size )
285+ tile_count = ((region .width + tile_size - 1 ) // tile_size ) * (
286+ (region .height + tile_size - 1 ) // tile_size
287+ )
283288
284289 worst : TiledContrastMeasurement | None = None
285290 for tile in _tiled_regions (region , tile_size ):
@@ -288,7 +293,9 @@ def worst_tile_contrast(
288293 continue
289294
290295 background = average_visible_background (background_image , tile , mask = foreground_alpha )
291- foreground = _average_visible_foreground (foreground_image , tile , foreground_alpha )
296+ foreground_crop = foreground_image .crop ((tile .x , tile .y , tile .right , tile .bottom ))
297+ foreground_mask = foreground_alpha .crop ((tile .x , tile .y , tile .right , tile .bottom ))
298+ foreground = tuple (ImageStat .Stat (foreground_crop , mask = foreground_mask ).mean [:3 ])
292299 contrast = contrast_ratio (foreground , background )
293300 if worst is None or contrast < worst .contrast :
294301 worst = TiledContrastMeasurement (
@@ -301,27 +308,7 @@ def worst_tile_contrast(
301308 return worst
302309
303310
304- def _average_visible_foreground (
305- image : Image .Image , region : BBox , mask : Image .Image
306- ) -> tuple [float , float , float ]:
307- crop = image .crop ((region .x , region .y , region .right , region .bottom ))
308- mask_crop = mask .crop ((region .x , region .y , region .right , region .bottom ))
309- mean_r , mean_g , mean_b , * _ = ImageStat .Stat (crop , mask = mask_crop ).mean
310- return mean_r , mean_g , mean_b
311-
312-
313- def _tile_count (region : BBox , tile_size : int ) -> int :
314- if tile_size <= 0 :
315- raise ValueError ("tile_size must be positive" )
316- cols = (region .width + tile_size - 1 ) // tile_size
317- rows = (region .height + tile_size - 1 ) // tile_size
318- return cols * rows
319-
320-
321311def _tiled_regions (region : BBox , tile_size : int ) -> Iterable [BBox ]:
322- if tile_size <= 0 :
323- raise ValueError ("tile_size must be positive" )
324-
325312 for y in range (region .y , region .bottom , tile_size ):
326313 for x in range (region .x , region .right , tile_size ):
327314 yield BBox .from_points (
0 commit comments