google/ExoPlayer · error · IllegalArgumentException
Failed to load bitmap.
Error message
Failed to load bitmap.
What it means
IllegalArgumentException thrown in TransformerActivity's input preview path when DataSourceBitmapLoader.loadBitmap(uri) completes exceptionally; future.get() wraps the failure in an ExecutionException (or the wait is interrupted). The demo only supports jpg inputs, so any decode/IO failure of the image surfaces as this error.
Source
Thrown at demos/transformer/src/main/java/com/google/android/exoplayer2/transformerdemo/TransformerActivity.java:716
outputPlayerView.setPlayer(outputPlayer);
outputPlayerView.setControllerAutoShow(false);
outputPlayer.setMediaItem(outputMediaItem);
outputPlayer.prepare();
this.outputPlayer = outputPlayer;
// Only support showing jpg images.
if (uri.toString().endsWith("jpg")) {
inputPlayerView.setVisibility(View.GONE);
inputImageView.setVisibility(View.VISIBLE);
inputTextView.setText(getString(R.string.input_image));
BitmapLoader bitmapLoader = new DataSourceBitmapLoader(getApplicationContext());
ListenableFuture<Bitmap> future = bitmapLoader.loadBitmap(uri);
try {
Bitmap bitmap = future.get();
inputImageView.setImageBitmap(bitmap);
} catch (ExecutionException | InterruptedException e) {
throw new IllegalArgumentException("Failed to load bitmap.", e);
}
} else {
inputPlayerView.setVisibility(View.VISIBLE);
inputImageView.setVisibility(View.GONE);
inputTextView.setText(getString(R.string.input_video_no_sound));
ExoPlayer inputPlayer = new ExoPlayer.Builder(/* context= */ this).build();
inputPlayerView.setPlayer(inputPlayer);
inputPlayerView.setControllerAutoShow(false);
inputPlayerView.setOnClickListener(this::onClickingPlayerView);
outputPlayerView.setOnClickListener(this::onClickingPlayerView);
inputPlayer.setMediaItem(inputMediaItem);
inputPlayer.prepare();
this.inputPlayer = inputPlayer;
inputPlayer.setVolume(0f);
inputPlayer.play();
}
outputPlayer.play();View on GitHub (pinned to dd430f7053)
Solutions
- Verify the URI is readable and the bytes are really JPEG before calling loadBitmap (check BitmapFactory.decodeBounds or the content resolver type)
- Catch ExecutionException separately and unwrap its cause for a specific message instead of a generic crash
- Restore the interrupted flag when catching InterruptedException so the thread state is preserved
- Support a broader set of image types or filter the picker to image/jpeg only
Example fix
// before
try {
Bitmap bitmap = future.get();
inputImageView.setImageBitmap(bitmap);
} catch (ExecutionException | InterruptedException e) {
throw new IllegalArgumentException("Failed to load bitmap.", e);
}
// after: degrade gracefully instead of crashing
try {
inputImageView.setImageBitmap(future.get());
} catch (ExecutionException e) {
Log.e(TAG, "Failed to load bitmap", e.getCause());
showToast(R.string.general_error); // keep the video preview path
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} Defensive patterns
Strategy: try-catch
Validate before calling
private boolean isDecodableJpg(Uri uri) {
try (InputStream in = getContentResolver().openInputStream(uri)) {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, opts);
return opts.outWidth > 0; // header parsed -> decodable
} catch (IOException | SecurityException e) {
return false;
}
} Try / catch
ListenableFuture<Bitmap> future = bitmapLoader.loadBitmap(uri);
try {
inputImageView.setImageBitmap(future.get());
} catch (ExecutionException e) {
Log.e(TAG, "bitmap decode failed", e.getCause()); // degrade, do not crash
inputImageView.setVisibility(View.GONE);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} Prevention
- Restrict the picker to image/jpeg so non-JPEG data cannot reach this path
- Treat future.get() as fallible: unwrap ExecutionException.getCause() for the real reason
- Restore the interrupt status whenever you catch InterruptedException
When it happens
Trigger: Input URI ends with 'jpg' but the bytes are not a decodable JPEG (corrupt file, renamed png, unsupported variant like CMYK jpeg); URI unreadable (content provider revoked, file moved); loadBitmap future fails with a BitmapDecoderException; thread interrupted while waiting.
Common situations: User picks a non-jpg image with a .jpg extension; SAF grant expired; large image OOM inside the decoder; HEIC disguised as jpg.
Related errors
- Could not delete the previous export output file
- Could not create the export output file
- Failed to load MediaPipeShaderProgram
- Unexpected color filter ${colorFilterSelection}
- Failed to load decoder native library.
AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14).
Data as JSON: /api/errors/1f8e861e0b701ce4.
Report an issue: GitHub.