wake-up-neo.com

Animiertes GIF anzeigen

Ich möchte animierte GIF-Bilder in meiner Anwendung anzeigen. __ Wie ich herausfand, wie schwierig es ist, dass Android animierte GIF-Dateien nicht nativ unterstützt.

Es können jedoch Animationen mit AnimationDrawable angezeigt werden:

Entwickeln> Hilfslinien> Bilder & Grafiken> Drawables-Übersicht

In diesem Beispiel werden Animationen verwendet, die als Frames in Anwendungsressourcen gespeichert sind, aber ich muss animierte GIFs direkt anzeigen.

Mein Plan ist es, animierte GIFs in Frames aufzuteilen und jeden Frame so zu zeichnen, dass er in AnimationDrawable gezeichnet werden kann.

Weiß jemand, wie Frames aus animierten GIF-Dateien extrahiert und in Drawable konvertiert werden?

234
Leonti

Android kann mit der Klasse Android.graphics.Movie animierte GIFs dekodieren und anzeigen.

Dies ist nicht zu viel dokumentiert, befindet sich jedoch in SDK-Referenz . Außerdem wird es in Samples in ApiDemos im Beispiel BitmapDecode mit einem animierten Flag verwendet.

183
Pointer Null

UPDATE:

Verwenden Sie Gleiten:

dependencies {
  implementation 'com.github.bumptech.glide:glide:4.0.0'
}

verwendungszweck:

Glide.with(context).load(GIF_URI).into(new GlideDrawableImageViewTarget(IMAGE_VIEW));

siehe docs

43
itzhar

auch put (main/assets/htmls/name.gif) [mit diesem html an die größe anpassen]

<html style="margin: 0;">
<body style="margin: 0;">
<img src="name.gif" style="width: 100%; height: 100%" />
</body>
</html>

deklarieren Sie in Ihrer XML-Datei zum Beispiel wie folgt (main/res/layout/name.xml): [Sie definieren zum Beispiel die Größe]

<WebView
Android:layout_width="70dp"
Android:layout_height="70dp"
Android:id="@+id/webView"
Android:layout_gravity="center_horizontal" />

geben Sie in Ihrer Aktivität den nächsten Code in onCreate ein

web = (WebView) findViewById(R.id.webView); 
web.setBackgroundColor(Color.TRANSPARENT); //for gif without background
web.loadUrl("file:///Android_asset/htmls/name.html");

wenn Sie dynamisch laden möchten, müssen Sie die Webansicht mit Daten laden:

// or "[path]/name.gif" (e.g: file:///Android_asset/name.gif for resources in asset folder), and in loadDataWithBaseURL(), you don't need to set base URL, on the other hand, it's similar to loadData() method.
String gifName = "name.gif";
String yourData = "<html style=\"margin: 0;\">\n" +
        "    <body style=\"margin: 0;\">\n" +
        "    <img src=" + gifName + " style=\"width: 100%; height: 100%\" />\n" +
        "    </body>\n" +
        "    </html>";
// Important to add this attribute to webView to get resource from outside.
webView.getSettings().setAllowFileAccess(true);

// Notice: should use loadDataWithBaseURL. BaseUrl could be the base url such as the path to asset folder, or SDCard or any other path, where your images or the other media resides related to your html
webView.loadDataWithBaseURL("file:///Android_asset/", yourData, "text/html", "utf-8", null);
// Or if you want to load image from SD card or where else, here is the idea.
String base = Environment.getExternalStorageDirectory().getAbsolutePath().toString();
webView.loadDataWithBaseURL(base + '/', yourData, "text/html", "utf-8", null);

vorschlag: Es ist besser, GIF mit statischen Bildern zu laden, um weitere Informationen zu erhalten. https://developer.Android.com/reference/Android/graphics/drawable/AnimationDrawable.html

Das war's, ich hoffe du hilfst.

28
Alex Zaraos

Ich löste das Problem, indem ich gif -Animationen in Frames aufteilte, bevor ich es auf dem Telefon speichere, sodass ich mich in Android nicht damit befassen müsste.

Dann lade ich jeden Frame auf das Handy herunter, erstelle daraus Drawable und erstelle dann AnimationDrawable - sehr ähnlich dem Beispiel aus meiner Frage

21
Leonti

ich fand einen sehr einfachen Weg mit einem Nizza und einfachen Arbeitsbeispiel hier

animiertes Widget anzeigen

Bevor es funktioniert, gibt es einige Möglichkeiten, die im Code zu tun sind

IM FOLGENDEN

    @Override
    public void onCreate(Bundle savedInstanceState){    
        super.onCreate(savedInstanceStated);   
        setContentView(new MYGIFView());
    }    
}

einfach austauschen 

setContentView(new MYGIFView());

im

setContentView(new MYGIFView(this));

UND IN

public GIFView(Context context) {
    super(context);

Stellen Sie Ihre eigene GIF-Animationsdatei bereit

    is = context.getResources().openRawResource(R.drawable.earth);
    movie = Movie.decodeStream(is);
}

ERSTE DIE ERSTE LINIE EIN

public MYGIFView(Context context) {

entsprechend dem Namen der Klasse ...

nach diesen kleinen Änderungen sollte es wie bei mir funktionieren ...

ich hoffe das hilft

16
Apperside

Möglichkeiten, animiertes GIF auf Android anzuzeigen:

  • Filmklasse. Wie oben erwähnt, ist es ziemlich fehlerhaft.
  • WebView. Es ist sehr einfach zu bedienen und normalerweise funktioniert. Aber manchmal fängt es an, sich schlecht zu benehmen, und es ist immer auf einigen obskuren Geräten, die Sie nicht haben. Außerdem können Sie nicht mehrere Instanzen in jeder Art von Listenansicht verwenden, da dies zu Ihrem Speicher führt. Sie könnten es jedoch als einen primären Ansatz betrachten. 
  • Benutzerdefinierter Code, um Gifs in Bitmaps zu decodieren und als Drawable oder ImageView anzuzeigen. Ich werde zwei Bibliotheken erwähnen:

https://github.com/koral--/Android-gif-drawable - Der Decoder ist in C implementiert. 

https://code.google.com/p/giffiledecoder - Der Decoder ist in Java implementiert und kann daher einfacher verwendet werden. Auch bei großen Dateien noch einigermaßen effizient.

Sie finden auch viele Bibliotheken, die auf der GifDecoder-Klasse basieren. Dies ist auch ein Java-basierter Decoder, aber es funktioniert, indem die gesamte Datei in den Arbeitsspeicher geladen wird, also nur für kleine Dateien.

9
Nick Frolov

Es fiel mir wirklich schwer, animierte GIFs in Android zu erstellen. Ich hatte nur folgende zwei Arbeiten:

  1. WebView
  2. Ion

WebView funktioniert gut und sehr einfach, aber das Problem ist, dass die Ansicht langsamer geladen wird und die App etwa eine Sekunde lang nicht reagiert. Ich mochte das nicht. Also habe ich verschiedene Ansätze ausprobiert (NICHT gearbeitet):

  1. ImageViewEx ist veraltet!
  2. picasso Animiertes GIF wurde nicht geladen
  3. Android-Gif-drawable sieht gut aus, aber es hat einige verkabelte NDK-Probleme in meinem Projekt verursacht. Es hat dazu geführt, dass meine lokale NDK-Bibliothek nicht mehr funktioniert und ich es nicht beheben konnte

Ich hatte einiges hin und her mit Ion; Endlich habe ich es funktioniert und es geht wirklich schnell :-)

Ion.with(imgView)
  .error(R.drawable.default_image)
  .animateGif(AnimateGifMode.ANIMATE)
  .load("file:///Android_asset/animated.gif");
8

Verwenden Sie ImageViewEx , eine Bibliothek, die die Verwendung einer GIF so einfach wie die Verwendung einer ImageView macht. 

7
NightSkyCode

Glide

Image Loader Library für Android, empfohlen von Google.

  • Glide ist Picasso ziemlich ähnlich, aber es ist viel schneller als Picasso.
  • Glide verbraucht weniger Speicher als Picasso.

Was dieser Glide hat, aber Picasso nicht

Die Möglichkeit, GIF-Animationen in eine einfache ImageView zu laden, ist möglicherweise die interessanteste Funktion von Glide. Und ja, mit Picasso ist das nicht möglich . enter image description here Einige wichtige Links-

  1. https://github.com/bumptech/glide
  2. http://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/de
7
Shoeb Siddique

Niemand hat die Bibliothek Ion oder Glide erwähnt. Sie arbeiten sehr gut.

Im Vergleich zu einem WebView ist die Handhabung einfacher.

6
bapho

Versuchen Sie es mit dieser untenstehenden Code-Anzeige-GIF-Datei

loading_activity.xml (im Layoutordner)

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:id="@+id/container"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:background="#ffffff" >

    <ProgressBar
        Android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleLarge"
        Android:layout_width="70dp"
        Android:layout_height="70dp"
        Android:layout_centerHorizontal="true"
        Android:layout_centerVertical="true"
        Android:indeterminate="true"
        Android:indeterminateDrawable="@drawable/custom_loading"
        Android:visibility="gone" />

</RelativeLayout>

custom_loading.xml (im Zeichnungsordner)

hier lege ich black_gif.gif (in einem Ordner mit Zeichnungsfunktion) an. Sie können hier Ihr eigenes Gif einfügen

<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:drawable="@drawable/black_gif"
    Android:pivotX="50%"
    Android:pivotY="50%" />

LoadingActivity.Java (im Ordner res)

public class LoadingActivity extends Activity {

    ProgressBar bar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_loading);
        bar = (ProgressBar) findViewById(R.id.progressBar);
        bar.setVisibility(View.VISIBLE);

    }

}
5
nirav kalola

Ich hatte Erfolg mit der vorgeschlagenen Lösung in diesem Artikel , einer Klasse namens GifMovieView, die eine View rendert, die dann angezeigt oder einer bestimmten ViewGroup hinzugefügt werden kann. Überprüfen Sie die anderen in den Abschnitten 2 und 3 des angegebenen Artikels beschriebenen Methoden. 

Der einzige Nachteil dieser Methode ist, dass das Antialiasing des Films nicht so gut ist (muss ein Nebeneffekt der Verwendung der "zwielichtigen" Android-Klasse "Movie" sein). Sie sollten den Hintergrund dann besser in Ihrer animierten GIF auf eine einfarbige Farbe einstellen.

5
Dr1Ku

@PointerNull gab eine gute Lösung, ist aber nicht perfekt. Auf einigen Geräten mit großen Dateien funktioniert es nicht und es wird eine fehlerhafte Gif-Animation mit Delta-Frames in der Version ICS angezeigt. Es ist eine Bibliothek mit nativer Decodierung zum Zeichnen: korals Android-Gif-Drawable .

4

Glide 4.6

1. gif laden

GlideApp.with(context)
            .load(R.raw.gif) // or url
            .into(imageview);

2. So erhalten Sie das Dateiobjekt

GlideApp.with(context)
                .asGif()
                .load(R.raw.gif) //or url
                .into(new SimpleTarget<GifDrawable>() {
                    @Override
                    public void onResourceReady(@NonNull GifDrawable resource, @Nullable Transition<? super GifDrawable> transition) {

                        resource.start();
                      //resource.setLoopCount(1);
                        imageView.setImageDrawable(resource);
                    }
                });
4
Gowsik K C

Einige Überlegungen zum BitmapDecode-Beispiel ... Im Grunde verwendet es die uralte, aber eher unkomplizierte Movie -Klasse von Android.graphics .. Bei den letzten API-Versionen müssen Sie die Hardwarebeschleunigung ausschalten, wie hier beschrieben . Ansonsten war es für mich segfault.

<activity
            Android:hardwareAccelerated="false"
            Android:name="foo.GifActivity"
            Android:label="The state of computer animation 2014">
</activity>

Hier ist das BitmapDecode-Beispiel nur mit dem GIF-Teil verkürzt. Sie müssen Ihr eigenes Widget (View) erstellen und es selbst zeichnen. Nicht ganz so mächtig wie eine ImageView.

import Android.app.Activity;
import Android.content.Context;
import Android.graphics.*;
import Android.os.*;
import Android.view.View;

public class GifActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new GifView(this));
    }

    static class GifView extends View {
        Movie movie;

        GifView(Context context) {
            super(context);
            movie = Movie.decodeStream(
                    context.getResources().openRawResource(
                            R.drawable.some_gif));
        }
        @Override
        protected void onDraw(Canvas canvas) {   
            if (movie != null) {
                movie.setTime(
                    (int) SystemClock.uptimeMillis() % movie.duration());
                movie.draw(canvas, 0, 0);
                invalidate();
            }
        }
    }
}

2 andere Methoden, eine mit ImageView, eine andere mit WebView, finden Sie in diesem feinen Tutorial . Die ImageView-Methode verwendet den von Apache lizenzierten Android-gifview von Google Code.

4
lubosz

Legen Sie es in einem WebView ab. Es muss in der Lage sein, es korrekt anzuzeigen, da der Standardbrowser GIF-Dateien unterstützt. (Froyo +, wenn ich mich nicht irre)

2
keybee

Nur für Android API (Android Pie) 28 und +

Verwenden Sie AnimatedImageDrawable as

// ImageView from layout
val ima : ImageView = findViewById(R.id.img_gif)
// create AnimatedDrawable 
val decodedAnimation = ImageDecoder.decodeDrawable(
        // create ImageDecoder.Source object
        ImageDecoder.createSource(resources, R.drawable.tenor))
// set the drawble as image source of ImageView
ima.setImageDrawable(decodedAnimation)
// play the animation
(decodedAnimation as? AnimatedImageDrawable)?.start()

XML-Code, fügen Sie eine ImageView hinzu

<ImageView
    Android:id="@+id/img_gif"
    Android:background="@drawable/ic_launcher_background" <!--Default background-->
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    Android:layout_width="200dp"
    Android:layout_height="200dp" />

AnimatedImageDrawable ist ein untergeordnetes Element von Drawable und wurde von ImageDecoder.decodeDrawable erstellt.

ImageDecoder.decodeDrawable, der außerdem die von ImageDecoder.Source erstellte Instanz von ImageDecoder.createSource erforderte.

ImageDecoder.createSource kann Quelle nur als Name, ByteBuffer, File, resourceId, URI, ContentResolver zum Erstellen des Quellobjekts verwenden und verwendet es, um AnimatedImageDrawable als Drawable (polymorpher Aufruf) zu erstellen

static ImageDecoder.Source  createSource(AssetManager assets, String fileName)
static ImageDecoder.Source  createSource(ByteBuffer buffer)
static ImageDecoder.Source  createSource(File file)
static ImageDecoder.Source  createSource(Resources res, int resId)
static ImageDecoder.Source  createSource(ContentResolver cr, Uri uri)

Hinweis: Sie können Bitmap auch mit ImageDecoder # decodeBitmap erstellen.

Ausgabe:

AnimatedDrawable unterstützt auch die Größenanpassung, Rahmen- und Farbmanipulation

2
Pavneet_Singh

Verwenden Sie ein Fresko. So geht's:

http://frescolib.org/docs/animations.html

Hier ist das Repo mit der Probe:

https://github.com/facebook/fresco/tree/master/samples/animation

Vorsicht, Fresco unterstützt keine Wrap-Inhalte!

1

Ich denke, die bessere Bibliothek für GIF-Dateien ist diese: von koral

Ich habe es benutzt und bin erfolgreich. Diese Bibliothek ist GIF'S gewidmet. aber wo als picasso und gleiten sind allgemeine Bildrahmen; Ich denke, die Entwickler dieser Bibliothek haben sich ganz auf GIF-Dateien konzentriert

1
DJphy

Es gibt zwei Möglichkeiten, animierte Gifs in unsere Android-Apps zu laden

1) Verwenden von Glide , um das Gif in eine ImageView zu laden.

    String urlGif = "https://cdn.dribbble.com/users/263558/screenshots/1337078/dvsd.gif";
    //add Glide implementation into the build.gradle file.
    ImageView imageView = (ImageView)findViewById(R.id.imageView);
    Uri uri = Uri.parse(urlGif);
    Glide.with(getApplicationContext()).load(uri).into(imageView);

2) Verwenden eines HTML-Codes zum Laden des Gifs in eine WebView

Erstellen Sie die HTML-Datei mit der Adresse in der GIF-Datei:

<html style="margin: 0;">
<body style="margin: 0;">
<img src="https://..../myimage.gif" style="width: 100%; height: 100%" />
</body>
</html>

speichern Sie diese Datei im Assets-Verzeichnis:

 enter image description here

Laden Sie diese HTML in das WebView Ihrer Anwendung:

    WebView webView =  (WebView)findViewById(R.id.webView);
    webView = (WebView) findViewById(R.id.webView);
    webView.loadUrl("file:///Android_asset/html/webpage_gif.html");

Heres ist ein komplettes Beispiel für diese beiden Optionen .

 enter image description here

1
Elenasys

Ich wollte nur hinzufügen, dass die Movie Klasse jetzt veraltet ist. 

Diese Klasse wurde auf API-Ebene P nicht mehr unterstützt. 

Es wird empfohlen, dies zu verwenden 

AnimatedImageDrawable

Zeichnet zum Zeichnen von animierten Bildern (wie GIF).

0
Sushobh Nadiger

Etwas, was ich für das Anzeigen von GIFs in Apps getan habe. Ich habe ImageView erweitert, damit die Benutzer seine Attribute frei verwenden können. Es kann Gifs aus der URL oder aus dem Assets-Verzeichnis anzeigen .. Die Bibliothek macht es auch einfach, Klassen zu erweitern, um davon zu erben, und es so erweitern, dass verschiedene Methoden zur Initialisierung des GIF unterstützt werden.

https://github.com/Gavras/GIFView

Es gibt eine kleine Anleitung auf der Github-Seite.

Es wurde auch auf Android Arsenal veröffentlicht:

https://Android-arsenal.com/details/1/4947

Beispiel verwenden:

Aus XML:

<com.whygraphics.gifview.gif.GIFView xmlns:gif_view="http://schemas.Android.com/apk/res-auto"
        Android:id="@+id/main_activity_gif_vie"
        Android:layout_width="200dp"
        Android:layout_height="200dp"
        Android:scaleType="center"
        gif_view:gif_src="url:http://pop.h-cdn.co/assets/16/33/480x264/gallery-1471381857-gif-season-2.gif" />

In der Tätigkeit:

    GIFView mGifView = (GIFView) findViewById(R.id.main_activity_gif_vie);

    mGifView.setOnSettingGifListener(new GIFView.OnSettingGifListener() {
                @Override
                public void onSuccess(GIFView view, Exception e) {
                    Toast.makeText(MainActivity.this, "onSuccess()", Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onFailure(GIFView view, Exception e) {

        }
});

Das programmgesteuerte Festlegen des GIF:

mGifView.setGifResource("asset:gif1");
0
Tzlil Gavra

Einfachste Möglichkeit - Der untenstehende Code kann berücksichtigt werden

Wir können Imageview setImageResource nutzen, siehe den gleichen Code.

Der folgende Code kann verwendet werden, um das Bild wie bei GIF anzuzeigen, wenn Sie ein mehrteiliges Bild von GIF haben. Teilen Sie einfach das GIF in ein einzelnes PNG aus einem Online-Tool auf und setzen Sie das Bild in die Zeichenfolge wie in der folgenden Reihenfolge

image_1.png, image_2.png usw.

Bitten Sie den Handler, das Bild dynamisch zu ändern.

int imagePosition = 1;
    Handler handler = new Handler();
        Runnable runnable = new Runnable() {
            public void run() {
                updateImage();
            }
        };




    public void updateImage() {

                appInstance.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        int resId = getResources().getIdentifier("image_" + imagePosition, "drawable", appInstance.getPackageName());
                        gifImageViewDummy.setImageResource(resId);
                        imagePosition++;
    //Consider you have 30 image for the anim
                        if (imagePosition == 30) {
//this make animation play only once
                            handler.removeCallbacks(runnable);

                        } else {
    //You can define your own time based on the animation
                            handler.postDelayed(runnable, 50);
                        }

//to make animation to continue use below code and remove above if else
// if (imagePosition == 30)
//imagePosition = 1;
// handler.postDelayed(runnable, 50);
// 
                    }
                });
              }
0
Lakshmanan

Zunächst sollte der Android-Browser Animated GIFs unterstützen. Wenn nicht, ist es ein Fehler! Schauen Sie sich die Issue-Tracker an.

Wenn Sie diese animierten GIFs außerhalb eines Browsers anzeigen, kann dies eine andere Geschichte sein. Um das zu tun, was Sie fragen, ist eine externe Bibliothek erforderlich, die die Decodierung von animierten GIFs unterstützt.

Der erste Anlaufpunkt wäre ein Blick auf die Java2D- oder JAI-API (Java Advanced Imaging), obwohl ich sehr überrascht wäre, wenn Android Dalvik diese Bibliotheken in Ihrer App unterstützt.

0
Eurig Jones

Ich löste dies, indem ich GIF in Frames aufteilte und Standard-Android-Animationen verwendete

0
Raluca Lucaci

Ähnlich wie bei @Leonti, aber mit etwas mehr Tiefe: 

Was ich tat, um das gleiche Problem zu lösen, war das Öffnen von GIMP, das Ausblenden aller Ebenen mit Ausnahme einer Ebene, das Exportieren als eigenes Bild, das Ausblenden der Ebene und das Ausblenden der nächsten Ebene usw., bis ich für jedes einzelne Ressource-Dateien hatte . Dann könnte ich sie als Rahmen in der AnimationDrawable-XML-Datei verwenden.

0
Jon O

Die einfachste Möglichkeit, animierte GIF-Dateien direkt von der URL zu Ihrem App-Layout anzuzeigen, ist die Verwendung der WebView-Klasse. 

Schritt 1: In Ihrem Layout XML

<WebView
Android:id="@+id/webView"
Android:layout_width="50dp"
Android:layout_height="50dp"
/>

Schritt 2: In Ihrer Aktivität

WebView wb;
wb = (WebView) findViewById(R.id.webView);
wb.loadUrl("https://.......);

Schritt 3: Machen Sie in Ihrem Manifest.XML die Internet-Berechtigung

<uses-permission Android:name="Android.permission.INTERNET" />

Schritt 4: Wenn Sie Ihren GIF-Hintergrund transparent machen und GIF an Ihr Layout anpassen möchten

wb.setBackgroundColor(Color.TRANSPARENT);
wb.getSettings().setLoadWithOverviewMode(true);
wb.getSettings().setUseWideViewPort(true);

0
Ovais Chaudhry