Android: كيف يتم عرض GIF متحرك كبير إعطاء عنوان URL؟

StackOverflow https://stackoverflow.com/questions/809878

  •  03-07-2019
  •  | 
  •  

سؤال

لنفترض أن لدي عنوان URL لـ GIF المتحركة الكبيرة وأردت أن أصنع نشاطًا يشبه YouTube الذي يعرض الرسوم المتحركة بطريقة تدفق. كيف أفعل

  1. دفق في الصورة؟
  2. احصل عليها مع الرسوم المتحركة الفعلية؟

أنا أعرف ImageView ليس الجواب لأنه يظهر فقط الإطار الأول.

ستكون المكافأة هي الوصول إلى حالة التخزين المؤقت حتى أتمكن من مزامنة صوت البث أيضًا - هذا جزء من أ ytmnd تطبيق المشاهد. على الرغم من أنه يمكنني إنشاء خدمة تقوم بتنقل ملفات GIF العامة إلى تنسيق أجمل ، إلا أنني أود أن يعمل التطبيق دون تبعيات إضافية.

هل كانت مفيدة؟

المحلول

الرسم العام للحل هو استخدام العرف View الذي يسأل يسأل أ Movie لرسم نفسها إلى Canvas دوريا.

الخطوة الأولى هي بناء Movie نموذج. هناك مصنع يسمى decodeStream يمكن أن يصنع فيلمًا يعطى InputStream لكن لا يكفي استخدام الدفق من أ UrlConnection. إذا جربت هذا ، فستحصل على IOException عندما يحاول تحميل الفيلم الاتصال reset على الدفق. الاختراق ، المؤسف كما هو ، هو استخدام منفصل BufferedInputStream مع مجموعة يدوي mark لإخبارها بحفظ بيانات كافية reset لن تفشل. لحسن الحظ ، و URLConnection يمكن أن تخبرنا مقدار البيانات التي يمكن توقعها. أقول إن هذا الاختراق أمر مؤسف لأنه يتطلب بشكل فعال أن يتم تخزين الصورة بأكملها في الذاكرة (وهو لا توجد مشكلة في تطبيقات سطح المكتب ، لكنها مشكلة خطيرة على جهاز محمول مقيد بالذاكرة).

هنا قصاصة من Movie رمز الإعداد:

URL url = new URL(gifSource);
URLConnection conn = url.openConnection();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bis.mark(conn.getContentLength());
Movie movie = Movie.decodeStream(bis);
bis.close();

بعد ذلك ، تحتاج إلى إنشاء عرض يعرض هذا Movie. فئة فرعية من View مع العرف onDraw سيقوم بالخدعة (على افتراض أن لديها إمكانية الوصول إلى Movie قمت بإنشاء مع الكود السابق).

@Override protected void onDraw(Canvas canvas) {
    if(movie != null) {
        long now = android.os.SystemClock.uptimeMillis();
        int dur = Math.max(movie.duration(), 1); // is it really animated?
        int pos = (int)(now % dur);
        movie.setTime(pos);
        movie.draw(canvas, x, y);
    }
}

لن تؤدي المنظر إلى إعادة رسم نفسه دون مساعدة ، والاتصال العميق invalidate() في نهاية onDraw هو مجرد نفايات الطاقة. في مؤشر ترابط آخر (ربما الذي استخدمته لتنزيل بيانات الصورة) ، يمكنك نشر الرسائل إلى مؤشر الترابط الرئيسي ، وطلب إبطال العرض بوتيرة ثابتة (ولكن ليس مجنون).

Handler handler = new Handler();
new Thread() {
    @Override public void run() {
        // ... setup the movie (using the code from above)
        // ... create and display the custom view, passing the movie

        while(!Thread.currentThread().isInterrupted()) {
            handler.post(new Runnable() {
                public void run(){
                    view.invalidate();
                }
            });
            try {
                Thread.sleep(50); // yields 20 fps
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}.start();

الحل الجميل حقًا سيحتوي على كل أنواع أشرطة التقدم الحلو والتحقق من الأخطاء ، ولكن النواة موجودة هنا.

نصائح أخرى

هل جربت BitmapDecode?

هناك مثال في عروض API هنا.

انسل من أثبت أكثر طريقة سهلة وفعالة لتحقيق ذلك مع سطر واحد فقط من التعليمات البرمجية:-

Glide.with(getApplicationContext())
            .load(Uri.parse("https://media1.giphy.com/media/5ziaphcUWGKPu/200.gif"))
            .asGif().placeholder(R.drawable.ic_launcher).crossFade()
            .into(imageView);

النتيجة هنا:-

enter image description here

GIF مأخوذة من هنا http://giphy.com/search/big-gif/3

أضف جرة من هنا:- https://github.com/bumptech/glide/releases

يمكن AnimationDrawable هل يمكن أن تعمل من أجلك؟ تحرير: ليس إذا كنت تريد التحميل من عنوان URL مثل هذا المنشور. آسف

http://developer.android.com/reference/android/graphics/drawable/animationDrawable.html

اعتمادًا على تعقيد GIF IE إذا كان مؤشرًا بسيطًا للتحميل/التقدم ، يمكنك تفكيك GIF عن بعضها البعض ، وإنقاذ كل صورة بشكل منفصل واستخدام Android Framework.

بالنسبة لأشرطة التقدم البسيطة ، قد يكون هذا أقل عرضة للخطأ ، وربما أكثر أداء.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top