I am 100% sure the problem here is with the actual image. However I hope that the solution is some attribute of the image that will help others in the future.
The image:
the photo in question http://soundwave.robotsidekick.com/mlsphotos.jpg
I have tried loading this image in several ways. I have downloaded it and tried loading it in an ImageView
:
final ImageView v = (ImageView) findViewById(R.id.image);
v.setImageResource(R.drawable.photo);
v.invalidate();
I have tried loading it from a url:
final String[] params = new String[] {
"",
};
(new AsyncTask<String, Bitmap, Bitmap>()
{
@Override
protected Bitmap doInBackground(final String... params)
{
Bitmap ret = null;
for (final String url : params)
{
try
{
Log.e(TAG, url);
ret = BitmapFactory.decodeStream((new URL(url)).openStream());
publishProgress(ret);
}
catch (final MalformedURLException e)
{
Log.e(TAG, "Malformed URL", e);
}
catch (final IOException e)
{
Log.e(TAG, "IO Exception", e);
}
}
return ret;
}
@Override
protected void onProgressUpdate(final Bitmap... values)
{
super.onProgressUpdate(values);
for (final Bitmap result : values)
{
if (result != null)
{
final ImageView v = (ImageView) MainActivity.this.findViewById(R.id.image);
v.setImageBitmap(result);
v.invalidate();
}
}
}
}).execute(params);
I have also tried loading the image in a WebView
like this:
final WebView webview = (WebView) findViewById(R.id.webview);
webview.loadData("<html><body><img src=\"" + url + "\"></body></html>", "text/html", "utf-8");
webview.invalidate();
I have also tried loading the image in Browser (the app) and that does not work.
None of those work, HOWEVER if I load the url into Chrome on Android it works great (not in Browser), if I load the image on my desktop browser (Chrome, Firefox, etc) it loads great. I have checked that the mime type matches the extension and I am just at a loss.
EDIT
There is a work around for images coming from an InputStream
where the bitmap processing runs out of data on the stream before the stream completes. The work around is documented in this question and this bug.
However this is a corrupt image whose data ends prematurely. I know that means I am already down a broken track, but I am hoping to have some better error handling than Android passing me back null
and I lose. iOS, Chrome (on device and computer) as well as most other places seem to have much better error handling. Is there something I can do on Android to handle corrupt jpgs?
EDIT 2
There has to be a solution here because Chrome on my device handles this situation elegantly. However the closest I can come to fixing this is the following code:
final InputStream is = (new URL(url)).openStream();
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
final int size = 1024;
int len = -1;
byte[] buf = new byte[size];
while ((len = is.read(buf, 0, size)) != -1)
{
bos.write(buf, 0, len);
}
buf = bos.toByteArray();
// buf is now filled with the corrupted bytes of the image
ret = BitmapFactory.decodeByteArray(buf, 0, buf.length);
// ret is null because it was a corrupt jpg
With that code I can check if there are bytes and the image wasn't decoded. Then at least I can tell I have a corrupt image (or not an image) and can report something slightly more useful to the user (like hey I have an image here with 16K but I sure don't know what to do with it).
Anyone know how Chrome manages to decode as much of the image as they can before they hit the corruption?