koral--/android-gif-drawable · error · IllegalArgumentException

x must be < width

Error message

x must be < width

What it means

getPixel returns the ARGB color of a single pixel of the current frame. Because the internal buffer bitmap may be larger than the GIF (a reused bitmap), the library explicitly checks x and y against the GIF's intrinsic width/height and throws IllegalArgumentException if they exceed bounds.

Solutions

  1. Clamp coordinates: x = Math.min(x, gifDrawable.getWidth() - 1), same for height
  2. Scale touch/view coordinates to drawable bitmap coordinates before sampling
  3. Catch IllegalArgumentException around getPixel and return a transparent/sentinel color

Example fix

// before
int color = gifDrawable.getPixel(touchX, touchY);
// after
int x = Math.min(touchX, gifDrawable.getIntrinsicWidth() - 1);
int y = Math.min(touchY, gifDrawable.getIntrinsicHeight() - 1);
int color = gifDrawable.getPixel(x, y);
Defensive patterns

Strategy: validation

Validate before calling

if (x >= gifDrawable.getIntrinsicWidth() || y >= gifDrawable.getIntrinsicHeight()) { return Color.TRANSPARENT; }

Type guard

boolean inBounds(GifDrawable g, int x, int y) { return x >= 0 && y >= 0 && x < g.getIntrinsicWidth() && y < g.getIntrinsicHeight(); }

Try / catch

try { color = gifDrawable.getPixel(x, y); } catch (IllegalArgumentException e) { color = Color.TRANSPARENT; }

Prevention

When it happens

Trigger: Calling getPixel(x, y) with x >= gif width or y >= gif height, e.g. sampling coordinates from a touch event scaled to a larger view, or iterating a parent bitmap's dimensions.

Common situations: Touch-to-color pickers mapping view coordinates directly to bitmap coordinates without scaling/offset; iterating rows/cols using the container bitmap size instead of getWidth()/getHeight(); density scaling mismatches.

Related errors


AI-assisted analysis of koral--/android-gif-drawable@26ff795f78 (2026-09-10). Data as JSON: /api/errors/a445ef243bc7b03f. Report an issue: GitHub.

Appendix: source

Thrown at android-gif-drawable/src/main/java/pl/droidsonroids/gif/GifDrawable.java:756

	 */
	public void getPixels(@NonNull int[] pixels) {
		mBuffer.getPixels(pixels, 0, mNativeInfoHandle.getWidth(), 0, 0, mNativeInfoHandle.getWidth(), mNativeInfoHandle.getHeight());
	}

	/**
	 * Returns the {@link Color} at the specified location. Throws an exception
	 * if x or y are out of bounds (negative or &gt;= to the width or height
	 * respectively). The returned color is a non-premultiplied ARGB value.
	 *
	 * @param x The x coordinate (0...width-1) of the pixel to return
	 * @param y The y coordinate (0...height-1) of the pixel to return
	 * @return The argb {@link Color} at the specified coordinate
	 * @throws IllegalArgumentException if x, y exceed the drawable's bounds
	 * @throws IllegalStateException    if drawable is recycled
	 */
	public int getPixel(@IntRange(from = 0) int x, @IntRange(from = 0) int y) {
		if (x >= mNativeInfoHandle.getWidth()) { //need to check explicitly because reused bitmap may be larger
			throw new IllegalArgumentException("x must be < width");
		}
		if (y >= mNativeInfoHandle.getHeight()) {
			throw new IllegalArgumentException("y must be < height");
		}
		return mBuffer.getPixel(x, y);
	}

	@Override
	protected void onBoundsChange(@NonNull Rect bounds) {
		mDstRect.set(bounds);
		if (mTransform != null) {
			mTransform.onBoundsChange(bounds);
		}
	}

	/**
	 * Reads and renders new frame if needed then draws last rendered frame.
	 *

View on GitHub (pinned to 26ff795f78)