beemdevelopment/Aegis · error · DecodeError
Unable to decode stream to bitmap
Error message
Unable to decode stream to bitmap
What it means
QrCodeHelper.decodeFromStream wraps BitmapFactory.decodeStream, which returns null when the InputStream does not contain a decodable bitmap (corrupt data, unsupported format, truncated stream). Aegis throws DecodeError immediately instead of passing the null Bitmap to ZXing. This is the app's way of signaling that the selected image is not a usable picture before QR decoding is even attempted.
Solutions
- Verify the picked file is a real, fully-downloaded image (open it in the gallery) before importing
- Re-export or re-save the QR code image, preferring PNG or JPEG
- Check available memory; very large images can fail to decode — resize before decoding
- If reading from a content URI, take a persistable, non-expired stream from the provider
Example fix
// before
InputStream in = context.getContentResolver().openInputStream(uri);
Result r = QrCodeHelper.decodeFromStream(in);
// after
try (InputStream in = context.getContentResolver().openInputStream(uri)) {
byte[] data = IOUtils.readAll(in);
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(data, 0, data.length, opts);
if (opts.outWidth <= 0) {
throw new DecodeError("Not a valid image");
}
Result r = QrCodeHelper.decodeFromStream(new ByteArrayInputStream(data));
} Defensive patterns
Strategy: validation
Validate before calling
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeStream(stream, null, opts);
if (opts.outWidth <= 0 || opts.outHeight <= 0) throw new DecodeError("Not a decodable image"); Try / catch
try {
Result r = QrCodeHelper.decodeFromStream(in);
} catch (DecodeError e) {
Toast.makeText(context, R.string.error_not_an_image, Toast.LENGTH_LONG).show();
} Prevention
- Pre-decode with inJustDecodeBounds to validate before real decode
- Ask users to re-export screenshots as PNG/JPEG
- Read the stream into memory once; avoid double-consuming closed streams
- Handle content-URIs that may return placeholder or zero-byte data
When it happens
Trigger: Calling QrCodeHelper.decodeFromStream with an InputStream whose bytes BitmapFactory cannot decode: a non-image file (e.g. a PDF or text file picked by the user), a truncated or partially downloaded image, an unsupported codec, or an already-closed stream.
Common situations: User picks a corrupt image from the gallery or a cloud-synced placeholder that hasn't downloaded; a file manager hands over a stream that Android's BitmapFactory can't handle (e.g. exotic HEIC/WebP variants on old devices); importing a QR screenshot that was saved as a zero-byte or damaged file.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unable to find pack.json in the root of the ZIP file
- Unable to create directories
- Unable to find relative to the root of the ZIP file
- Unable to delete directory
- Invalid number of iterations for PBKDF
AI-assisted analysis of beemdevelopment/Aegis@d6f4e5925a (2026-09-08).
Data as JSON: /api/errors/380ca354e396fbee.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/main/java/com/beemdevelopment/aegis/helpers/QrCodeHelper.java:46
private QrCodeHelper() {
}
public static Result decodeFromSource(LuminanceSource source) throws NotFoundException {
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.POSSIBLE_FORMATS, Collections.singletonList(BarcodeFormat.QR_CODE));
hints.put(DecodeHintType.ALSO_INVERTED, true);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
MultiFormatReader reader = new MultiFormatReader();
return reader.decode(bitmap, hints);
}
public static Result decodeFromStream(InputStream inStream) throws DecodeError {
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
Bitmap bitmap = BitmapFactory.decodeStream(inStream, null, bmOptions);
if (bitmap == null) {
throw new DecodeError("Unable to decode stream to bitmap");
}
// If ZXing is not able to decode the image on the first try, we try a couple of
// more times with smaller versions of the same image.
for (int i = 0; i <= 2; i++) {
if (i != 0) {
bitmap = BitmapHelper.resize(bitmap, bitmap.getWidth() / (i * 2), bitmap.getHeight() / (i * 2));
}
try {
int[] pixels = new int[bitmap.getWidth() * bitmap.getHeight()];
bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
LuminanceSource source = new RGBLuminanceSource(bitmap.getWidth(), bitmap.getHeight(), pixels);
return decodeFromSource(source);
} catch (NotFoundException ignored) {
}View on GitHub (pinned to d6f4e5925a)