Skip to content

Commit 8498a3e

Browse files
committed
Fix index bounds calculation for image slicing compatibility
1 parent 52ab482 commit 8498a3e

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@
6363

6464
🛠️ Bug fixes:
6565

66+
* Fixed index bounds calculation for image slicing compatibility:
67+
* Corrected the calculation of maximum indices in `get_plot_coordinates` to ensure proper bounds when using NumPy array slicing
68+
* Previously, the maximum indices were off by one, which could cause issues when extracting image data using the returned coordinates
69+
* Now returns indices that correctly align with Python/NumPy slicing conventions (e.g., `[i1:i2+1, j1:j2+1]`)
70+
* This fixes an historic bug that could lead to off-by-one errors when users extracted image data using the coordinates provided by this function
6671
* Fixed plot update after inserting a point using the `EditPointTool` on non-Windows platforms
6772
* [Issue #46](https://github.com/PlotPyStack/PlotPy/issues/46) - Contrast adjustment with 'Eliminate outliers' failed for float images with high dynamic range
6873
* [Issue #29](https://github.com/PlotPyStack/PlotPy/issues/29) - SelectTool: Selecting Another Shape Without Unselection

plotpy/items/image/base.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -230,23 +230,30 @@ def get_closest_index_rect(
230230
Defaults to True.
231231
232232
Returns:
233-
Closest image rectangular pixel area index bounds
233+
Closest image rectangular pixel area index bounds compatible with
234+
direct array slicing (e.g., data[iy0:iy1, ix0:ix1])
234235
235236
.. note::
236237
237238
Avoid returning empty rectangular area (return 1x1 pixel area instead).
238239
Handle reversed/not-reversed Y-axis orientation.
240+
Indices are compatible with direct array slicing and match get_data
241+
behavior.
239242
"""
240243
ix0, iy0 = self.get_closest_indexes(x0, y0, corner="TL")
241-
ix1, iy1 = self.get_closest_indexes(x1, y1, corner="BR")
244+
# Use TL to avoid double +1 addition
245+
ix1, iy1 = self.get_closest_indexes(x1, y1, corner="TL")
242246
if ix0 > ix1:
243247
ix1, ix0 = ix0, ix1
244248
if iy0 > iy1:
245249
iy1, iy0 = iy0, iy1
250+
# Add +1 to bottom-right indices for slice compatibility (matches get_data)
251+
ix1 = min(ix1 + 1, self.data.shape[1])
252+
iy1 = min(iy1 + 1, self.data.shape[0])
246253
if ix0 == ix1 and avoid_empty:
247-
ix1 += 1
254+
ix1 = min(ix1 + 1, self.data.shape[1])
248255
if iy0 == iy1 and avoid_empty:
249-
iy1 += 1
256+
iy1 = min(iy1 + 1, self.data.shape[0])
250257
return ix0, iy0, ix1, iy1
251258

252259
def align_rectangular_shape(self, shape: RectangleShape) -> None:

0 commit comments

Comments
 (0)