3b1b/manim · error · Exception
Cannot sample color from outside an image
Error message
Cannot sample color from outside an image
What it means
Raised by AbstractImageMobject.point_to_rgb (image_mobject.py:71) when the sampled point maps to an x-coordinate outside the image while the y-coordinate is inside. Note the guard reads `if not (0 <= x_alpha <= 1) and (0 <= y_alpha <= 1)` — due to precedence this only fires for out-of-range x with in-range y; a point outside in y (or both) silently clamps and returns an edge pixel instead of raising.
Source
Thrown at manimlib/mobject/types/image_mobject.py:71
def set_opacity(self, opacity: float, recurse: bool = True):
with self.data.being_written() as data:
data["opacity"][:, 0] = resize_with_interpolation(
np.array(listify(opacity)),
self.get_num_points()
)
return self
def set_color(self, color, opacity=None, recurse=None):
return self
def point_to_rgb(self, point: Vect3) -> Vect3:
x0, y0 = self.get_corner(UL)[:2]
x1, y1 = self.get_corner(DR)[:2]
x_alpha = inverse_interpolate(x0, x1, point[0])
y_alpha = inverse_interpolate(y0, y1, point[1])
if not (0 <= x_alpha <= 1) and (0 <= y_alpha <= 1):
# TODO, raise smarter exception
raise Exception("Cannot sample color from outside an image")
pw, ph = self.image.size
rgb = self.image.getpixel((
int((pw - 1) * x_alpha),
int((ph - 1) * y_alpha),
))[:3]
return np.array(rgb) / 255
View on GitHub (pinned to dee01804d4)
Solutions
- Before sampling, verify the point is inside the image rectangle: compare against mob.get_corner(UL) and mob.get_corner(DR)
- Clamp the point onto the image before calling point_to_rgb if edge-pixel behavior is acceptable
- If you maintain a fork/patch, fix the condition to `if not (0 <= x_alpha <= 1 and 0 <= y_alpha <= 1)` so all out-of-bounds points raise
Example fix
# before
rgb = img.point_to_rgb(np.array([5.0, 0.5, 0.0])) # x off-image -> raises
# after
ul, dr = img.get_corner(UL)[:2], img.get_corner(DR)[:2]
if ul[0] <= p[0] <= dr[0] and dr[1] <= p[1] <= ul[1]:
rgb = img.point_to_rgb(p) Defensive patterns
Strategy: validation
Validate before calling
def point_on_image(img, p) -> bool:
ul, dr = img.get_corner(UL)[:2], img.get_corner(DR)[:2]
return ul[0] <= p[0] <= dr[0] and dr[1] <= p[1] <= ul[1]
rgb = img.point_to_rgb(p) if point_on_image(img, p) else DEFAULT_COLOR Try / catch
try:
rgb = img.point_to_rgb(p)
except Exception:
rgb = np.array([0.5, 0.5, 0.5]) # fallback for off-image samples Prevention
- Clamp or reject points outside get_corner(UL)/get_corner(DR) before sampling
- Do not assume the built-in check covers vertical overflow — guard both axes yourself
- For interactive sampling, first hit-test the point against the image's bounding box
When it happens
Trigger: Calling image_mobject.point_to_rgb(point) where point[0] lies left/right of the image's corners but point[1] is vertically within the image; typically when probing with a point produced by an intersection or a cursor position that is off the image.
Common situations: Interactive/color-picker scenes sampling colors at arbitrary screen points; using point_to_rgb on points from line_intersections or mouse events without checking they are on the image; relying on the check to catch all out-of-image points and hitting the precedence quirk in manim versions with this source.
Related errors
- Need at least one color
- Invalid color type
- Unsupported: {path_verb}
- At least 2 mobjects needed for Union.
- At least 2 mobjects needed for Intersection.
AI-assisted analysis of 3b1b/manim@dee01804d4 (2026-08-14).
Data as JSON: /api/errors/3554cb060f4e0c66.
Report an issue: GitHub.