bitmapfactory.decodeStream يعيد دائمًا Null و Decider Decoder عروض Decode عاد كاذبة
سؤال
اختبار الصورة هنا:http://images.plurk.com/tn_4134189_bf54fe8e270ce41240d534b513384ee.gif
لقد جربت العديد من الحلول الموجودة على الإنترنت ولكن لا يوجد حل عمل.
أنا أستخدم رمز المقتطف التالي:
Url imageUrl = new Url("http://images.plurk.com/tn_4134189_bf54fe8e270ce41240d534b5133884ee.gif");
Bitmap image = BitmapFactory.decodeStream(imageUrl.openStream());
دائما الحصول على هذا السجل:
DEBUG/skia(1441): --- decoder->decode returned false
أي مساعدة؟ شكرًا.
تعديل:
لا يمكن أيضًا عرض تلك الصور التي فشلت في فك تشفيرها WebView
. ولكن يمكن أن ترى ما إذا كانت مفتوحة في متصفح.
المحلول
جرب هذا بمثابة حل مؤقت:
أضف أولاً الفصل التالي:
public static class PlurkInputStream extends FilterInputStream {
protected PlurkInputStream(InputStream in) {
super(in);
}
@Override
public int read(byte[] buffer, int offset, int count)
throws IOException {
int ret = super.read(buffer, offset, count);
for ( int i = 2; i < buffer.length; i++ ) {
if ( buffer[i - 2] == 0x2c && buffer[i - 1] == 0x05
&& buffer[i] == 0 ) {
buffer[i - 1] = 0;
}
}
return ret;
}
}
ثم لف الدفق الأصلي الخاص بك مع plurkinputstream:
Bitmap bitmap = BitmapFactory.decodeStream(new PlurkInputStream(originalInputStream));
اسمحوا لي أن أعرف إذا كان هذا يساعدك.
تعديل:
آسف الرجاء تجربة الإصدار التالي بدلاً من ذلك:
for ( int i = 6; i < buffer.length - 4; i++ ) {
if ( buffer[i] == 0x2c ) {
if ( buffer[i + 2] == 0 && buffer[i + 1] > 0
&& buffer[i + 1] <= 48 ) {
buffer[i + 1] = 0;
}
if ( buffer[i + 4] == 0 && buffer[i + 3] > 0
&& buffer[i + 3] <= 48 ) {
buffer[i + 3] = 0;
}
}
}
لاحظ أن هذا ليس رمزًا فعالًا ولا هذا الحل الكامل/الصحيح. سوف يعمل في معظم الحالات ، ولكن ليس كل شيء.
نصائح أخرى
واجهت نفس المشكلة ، تم إصلاحه جزئيًا من خلال هذا الفصل:
static class FlushedInputStream extends FilterInputStream {
public FlushedInputStream(InputStream inputStream) {
super(inputStream);
}
@Override
public long skip(long n) throws IOException {
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L) {
int byte = read();
if (byte < 0) {
break; // we reached EOF
} else {
bytesSkipped = 1; // we read one byte
}
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
و:
InputStream in = null;
try {
in = new java.net.URL(imageUrl).openStream();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Bitmap image = BitmapFactory.decodeStream(new FlushedInputStream(in));
لقد ساعد ذلك في معظم الحالات ، لكن هذا ليس حلًا عالميًا. لمزيد من الرجوع إلى هذا تقرير الشوائب.
حظا سعيدا!
جربت كل الحلول لكنني لم أحل مشكلتي. بعد بعض الاختبارات ، حدثت مشكلة فشل فك ترميز Skia كثيرًا عندما لا يكون اتصال الإنترنت مستقرًا. بالنسبة لي ، إجبار على إعادة تنزيل الصورة حل المشكلة.
قدمت المشكلة أيضًا أكثر عندما تكون الصورة ذات حجم كبير.
سيطلب مني استخدام حلقة إعادة تجهيزات 2 على الأكثر وسيتم تنزيل الصورة بشكل صحيح.
Bitmap bmp = null;
int retries = 0;
while(bmp == null){
if (retries == 2){
break;
}
bmp = GetBmpFromURL(String imageURL);
Log.d(TAG,"Retry...");
retries++;
}
هذا يجب أن يعمل:
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
connection.disconnect();
input.close();
يحتوي MyBitMap على صورتك.
ويرجع ذلك إلى وجود خطأ في فئة InputStream في Android. يمكنك العثور على حل صالح ووصف للخطأ هنا http://code.google.com/p/android/issues/detail؟id=6066
لأسباب الذاكرة ، يجب أن تكون تتنفيذ خيارات نقطية مثل هذا:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4; // might try 8 also
وظيفة التنزيل الرئيسية في صورة نقطية ربما مثل هذا:
Bitmap downloadBitmap(String url) {
final HttpClient client = AndroidHttpClient.newInstance("Android");
final HttpGet getRequest = new HttpGet(url);
try {
HttpResponse response = client.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
if(DEBUG)Log.w("ImageDownloader", "Error " + statusCode +
" while retrieving bitmap from " + url);
return null;
}
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
inputStream = entity.getContent();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4; // might try 8 also
return BitmapFactory.decodeStream(new FlushedInputStream(inputStream),null,options);
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
} catch (IOException e) {
getRequest.abort();
if(DEBUG)Log.w(TAG, "I/O error while retrieving bitmap from " + url, e);
} catch (IllegalStateException e) {
getRequest.abort();
if(DEBUG)Log.w(TAG, "Incorrect URL: " + url);
} catch (Exception e) {
getRequest.abort();
if(DEBUG)Log.w(TAG, "Error while retrieving bitmap from " + url, e);
} finally {
if ((client instanceof AndroidHttpClient)) {
((AndroidHttpClient) client).close();
}
}
return null;
}
وربما يجب أن تكون تنفذ شجاعة مثل هذا:http://android-developers.blogspot.com/2010/07/multithReading-for-performance.html
بالنسبة لي المشكلة هي نوع لون الصورة: صورتك على اللون = cymk ليس في RGB
ربما لم تكن هذه هي حالتك ولكن قد تكون إذا كنت تحاول فك تشفير الصور باستخدام CMYK Colorspace ، بدلاً من RGB Colorspace. صور CMYK ، مثل هذا, ، غير مدعوم من قبل Android ، ولن يتم عرضه حتى في متصفح الويب Android. اقرأ المزيد عن هذا هنا:
غير قادر على تحميل JPEG-ISMAGE مع bitmapfactory.decodefile. يعود فارغة
جرب هذا:
HttpGet httpRequest = new HttpGet(url);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = (HttpResponse) httpclient.execute(httpRequest);
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufferedHttpEntity = new BufferedHttpEntity(entity);
InputStream is = bufferedHttpEntity.getContent();
Drawable d = Drawable.createFromStream(is, "");
//or bitmap
//Bitmap b = BitmapFactory.decodeStream(is);