एनिमेटेड GIF प्रदर्शित करें


261

मैं अपने एप्लायंस में एनिमेटेड GIF छवियों को प्रदर्शित करना चाहता हूं। जैसा कि मुझे पता चला कि एंड्रॉइड एनिमेटेड GIF का समर्थन नहीं करता है।

हालाँकि यह एनिमेशनप्रदर्शन का उपयोग कर एनिमेशन प्रदर्शित कर सकता है :

विकास> मार्गदर्शिकाएँ> छवियां और ग्राफिक्स> चित्र अवलोकन

उदाहरण अनुप्रयोग संसाधनों में फ़्रेम के रूप में सहेजे गए एनीमेशन का उपयोग करता है, लेकिन मुझे सीधे एनिमेटेड GIF प्रदर्शित करने की आवश्यकता है।

मेरी योजना एनिमेटेड जीआईएफ को फ्रेम में तोड़ने और प्रत्येक फ्रेम को एनिमेशनड्रायबल के रूप में जोड़ने की है।

क्या किसी को पता है कि एनिमेटेड GIF से फ़्रेम कैसे निकालें और उनमें से प्रत्येक को ड्रा करने योग्य में परिवर्तित करें ?


2
क्या आप Android के भीतर मतलब है, या एक बाहरी उपकरण के साथ एक GIF से फ्रेम निकालने?
ओसमंड

यह निश्चित रूप से, एक बग है देखना IssueTracker अधिक जानकारी के लिए।
fbtb

बस उन सभी के लिए जो एक ऐप की खोज करके यहां आए थे जो एनिमेटेड जीआईएफ प्रदर्शित कर सकते हैं: quickPic
rubo77


GIF github.com/facebook/fresco प्रदर्शित करने के लिए फ्रेस्को का उपयोग करें मुझे लगता है कि यह एक सरल समाधान है।
kaitian521 14:12

जवाबों:


191

Android वास्तव में Android.graphics.Movie वर्ग का उपयोग करते हुए, एनिमेटेड GIF को डीकोड और प्रदर्शित कर सकता है।

यह बहुत अधिक प्रलेखित नहीं है, लेकिन एसडीके संदर्भ में है । इसके अलावा, यह कुछ एनिमेटेड फ्लैग के साथ बिटमैपडबल उदाहरण में ApiDemos में नमूने में उपयोग किया जाता है ।


9
यह कितना स्थिर है? मैंने इसे अपने ऐप में लागू किया है, मेरे आइसक्रीम सैंडविच डिवाइस पर यह बिल्कुल भी काम नहीं कर रहा है, 2.3 एमुलेटर पर यह काम कर रहा है लेकिन कुछ जीआईएफ फ्रेम बग (गलत रंग) हैं। कंप्यूटर पर यह ठीक काम कर रहा है। क्या देता है?
बेनोइट डफेज

12
@Bicou पोस्ट-कोर्ट उपकरणों पर आपको setLayerType(LAYER_TYPE_SOFTWARE)अपने दृश्य पर होना चाहिए । लेकिन यह अभी भी केवल कुछ gif और कुछ उपकरणों के लिए काम करता है।
मिशाल के

9
@ माइकल धन्यवाद! Paint p = new Paint(); p.setAntiAlias(true); setLayerType(LAYER_TYPE_SOFTWARE, p);काम किया!
च्लोए

1
@lubosz: LAYER_TYPE_SOFTWARE सेट करने के लिए पर्याप्त होना चाहिए।
सूचक नल

2
मूवी क्लास उद्देश्य पर अनएन्जाइन्ड है - यह कमजोर और असमर्थित है। यदि आपको उचित Gif एनिमेशन की आवश्यकता है, तो आप इसे बेहतर तरीके से लागू करते हैं। मैंने इसे NDK का उपयोग करके अपने ऐप के लिए किया था।
सूचक नल

60

अपडेट करें:

ग्लाइड का उपयोग करें:

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

उपयोग:

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

डॉक्स देखें


1
अब मुझे ठीक लग रहा है, जाहिर है जवाब में पूरी लाइब्रेरी शामिल नहीं हो सकती है, इसलिए कॉल उदाहरण पर्याप्त लगता है।
गाबोरस

@ स्पष्ट रूप से कोडिंग के समय कोड शामिल नहीं था।
Jan

1
यदि आप पहले से ही NDK का उपयोग कर रहे हैं तो मैं इस पुस्तकालय का उपयोग करने की सलाह नहीं देता। इस देयता को जोड़ देने के बाद, एक एकता मॉड्यूल ने काम करना बंद कर दिया।
रोमिनाव जूल

यह सबसे अच्छी लाइब्रेरी है जिसे मैंने पाया है। एक चीज जो मैं अटका रहा हूं वह जीआईएफ छवि को ज़ूम करने के लिए चुटकी को लागू करना है। क्या कोई जानता है?
सांप

28

भी डाल (मुख्य / संपत्ति / htmls / name.gif) [इस HTML आकार के साथ समायोजित]

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

इस तरह से उदाहरण के लिए अपने Xml में घोषणा करें (मुख्य / रेस / लेआउट / name.xml): [आप आकार को परिभाषित करते हैं, उदाहरण के लिए]

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

अपनी गतिविधि में अगला कोड onCreate के अंदर रखें

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

यदि आप गतिशील रूप से लोड करना चाहते हैं, तो आपको वेबव्यू को डेटा के साथ लोड करना होगा:

// 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);

सुझाव: अधिक जानकारी के जांच करने के लिए स्थिर चित्र के साथ बेहतर लोड gif है https://developer.android.com/reference/android/graphics/drawable/AnimationDrawable.html

यही है, मुझे आशा है कि आप मदद करेंगे।


2
अगर मुझे sdcard से GIF लोड करना है?
जयदेव

अगर आप sdcard से लोड करना चाहते हैं: अपनी छवि के uri के लिए "file: ///android_asset/htmls/name.html" बदलें
एलेक्स जाराओस

इस पद्धति का उपयोग करके, मैं गतिशील रूप से gif फ़ाइल का नाम कैसे बदल सकता हूं? मैं हर ऐप के साथ जाने के लिए एक html फ़ाइल नहीं बनाना चाहता हूँ जिसे मुझे अपने ऐप में प्रदर्शित करने की आवश्यकता है
screne

GIF के लिए वेबव्यू? क्या आपने प्रदर्शन, मेमोरी खपत और बैटरी के बारे में सोचा?
दुनू

@ डुना जो 5 साल पहले था, वर्तमान में हम उदाहरण के लिए ग्लाइड का उपयोग कर सकते हैं
एलेक्स ज़ाराओस

22

मैंने फोन को सहेजने से पहले फ्रेम में जिफ एनिमेशन को विभाजित करके समस्या को हल किया , इसलिए मुझे एंड्रॉइड में इससे निपटना नहीं होगा।

तब मैं फोन पर हर फ्रेम डाउनलोड, इसे से Drawable बनाने और उसके बाद बनाने AnimationDrawable - बहुत मेरे सवाल से उदाहरण की तरह


2
जो एनिमेशन को संभालने का प्रलेखित तरीका है।
रिची एचएच

16

मुझे यहाँ एक अच्छा और सरल काम करने का एक बहुत ही आसान तरीका मिला

एनिमेटेड विजेट प्रदर्शित करें

यह काम करने से पहले कोड में करने के लिए कुछ चेज़ हैं

निम्नलिखित में

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

बस प्रतिस्थापित करें

setContentView(new MYGIFView());

में

setContentView(new MYGIFView(this));

और में

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

अपनी खुद की gif एनीमेशन फ़ाइल प्रदान करें

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

सबसे पहले लाइन में पढ़ें

public MYGIFView(Context context) {

वर्ग के नाम के अनुसार ...

इस छोटे से बदलाव के बाद यह मेरे लिए काम करना चाहिए ...

उममीद है कि इससे मदद मिलेगी


2
आपने किस Android संस्करण पर यह आज़माया? मैंने एंड्रॉइड के संस्करण 2.2 और 2.3 पर कोशिश की, लेकिन यह मूवी ऑब्जेक्ट अशक्त देता है। कोई भी विचार गलत हो सकता है क्या?
अश्विनी शाहपुरकर

16
कृपया इस उत्तर को साफ करें, इसके, यादृच्छिक।
करदेता

2
उत्तर में क्या समस्या है? मैंने सिर्फ एक लिंक प्रदान किया है और इसे काम करने के लिए कुछ आवश्यक फिक्स दिए हैं
अपीयर करें

10

Android पर एनिमेटेड GIF दिखाने के तरीके:

  • मूवी की क्लास। जैसा कि ऊपर उल्लेख किया गया है, यह काफी छोटी है।
  • WebView। यह उपयोग करने के लिए बहुत सरल है और आमतौर पर काम करता है। लेकिन कभी-कभी यह दुर्व्यवहार करना शुरू कर देता है, और यह हमेशा कुछ अस्पष्ट उपकरणों पर होता है जो आपके पास नहीं हैं। साथ ही, आप किसी भी प्रकार के सूची दृश्यों में कई उदाहरणों का उपयोग नहीं कर सकते, क्योंकि यह आपकी स्मृति के लिए चीजें करता है। फिर भी, आप इसे प्राथमिक दृष्टिकोण मान सकते हैं।
  • कस्टम कोड gifs को बिटमैप्स में डिकोड करने के लिए और उन्हें ड्रा करने योग्य या छवि दृश्य के रूप में दिखाएं। मैं दो पुस्तकालयों का उल्लेख करूंगा:

https://github.com/koral--/android-gif-drawable - डिकोडर सी में लागू किया गया है, इसलिए यह बहुत कुशल है।

https://code.google.com/p/giffiledecoder - डिकोडर जावा में लागू किया गया है, इसलिए इसके साथ काम करना आसान है। फिर भी यथोचित रूप से कुशल, बड़ी फ़ाइलों के साथ भी।

आपको GifDecoder क्लास के आधार पर कई लाइब्रेरी भी मिलेंगी। यह भी एक जावा-आधारित डिकोडर है, लेकिन यह पूरी फाइल को मेमोरी में लोड करके काम करता है, इसलिए यह केवल छोटी फाइलों पर लागू होता है।


10

एंड्रॉइड में काम करने वाले एनिमेटेड जिफ के लिए मेरे पास वास्तव में कठिन समय था। मैं केवल दो काम कर रहा था:

  1. WebView
  2. आयन

WebView ठीक काम करता है और वास्तव में आसान है, लेकिन समस्या यह है कि यह दृश्य को धीमा बनाता है और एप्लिकेशन एक या दूसरे सेकंड के लिए अनुत्तरदायी होगा। मुझे वह पसंद नहीं था। इसलिए मैंने विभिन्न तरीकों की कोशिश की है (काम नहीं किया):

  1. ImageViewEx पदावनत है!
  2. picasso ने एनिमेटेड GIF को लोड नहीं किया
  3. android-gif-drawable बहुत अच्छा लगता है, लेकिन इसने मेरे प्रोजेक्ट में कुछ वायर्ड NDK मुद्दों को जन्म दिया। इसने मेरे स्थानीय NDK पुस्तकालय को काम करना बंद कर दिया, और मैं इसे ठीक करने में सक्षम नहीं था

मेरे साथ कुछ आगे और पीछे था Ion; अंत में, मेरे पास यह काम कर रहा है, और यह वास्तव में तेज़ है :-)

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

मेरे पास Android-gif-drawable के साथ समान NDK संबंधित मुद्दे थे।
रोमिनाव

नमस्कार @RominaV, क्या आपने लोड gif लोड होने पर आयन में प्रगति पट्टी का उपयोग किया है, क्योंकि मुझे लोड gif के दौरान प्रगति दिखाने की आवश्यकता है।
patel135

9

ग्लाइड 4.6

1. जिफ़ लोड करने के लिए

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

2. फ़ाइल ऑब्जेक्ट प्राप्त करने के लिए

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);
                    }
                });

8

Glide

Android के लिए छवि लोडर लाइब्रेरी, Google द्वारा अनुशंसित।

  • ग्लाइड पिकासो से काफी मिलता-जुलता है लेकिन पिकासो की तुलना में यह बहुत तेज है।
  • ग्लाइड पिकासो की तुलना में कम मेमोरी का उपभोग करता है।

उस ग्लाइड में क्या है लेकिन पिकासो नहीं है

GIF एनीमेशन को एक साधारण ImageView में लोड करने की क्षमता ग्लाइड की सबसे दिलचस्प विशेषता हो सकती है। और हाँ, आप पिकासो के साथ ऐसा नहीं कर सकते। कुछ महत्वपूर्ण लिंक-यहां छवि विवरण दर्ज करें

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

Google ग्लिड की सलाह कहाँ देता है?
डेरज़ू

1
इसे देखें, जहाँ डेवलपर Android टीम ने अपने नमूना ऐप में Glide का उपयोग किया है। डेवलपर
शोएब सिद्दीकी

1
'ग्लाइड पिकासो से काफी मिलता-जुलता है लेकिन पिकासो की तुलना में यह बहुत तेज है' और 'ग्लाइड पिकासो की याददाश्त कम करता है।' क्षमा करें, मैं इन विचारों से संतुष्ट नहीं हूँ, कृपया इस लिंक को पसंद करें: medium.com/@multidots/glide-vs-picasso-930eed42b81d । Btw, मैं ग्लाइड 4.0 का परीक्षण नहीं कर सकता क्योंकि 3.0.1 (स्लो इंटरनेट कनेक्शन) पर बिल्ड अपग्रेड नहीं कर पा रहा हूं; लेकिन मैंने gif दिखाने पर ग्लाइड 3.5.2 का परीक्षण किया, यह काम करता है लेकिन पूरी तरह से नहीं जैसा कि मैंने बड़े img (यह टिमटिमा रहा है) पर उम्मीद की थी, और यह एक सामान्य मुद्दा भी है। कृपया CMIW करें।
गुयेन तन डाट

7

ImageViewEx का उपयोग करें , एक पुस्तकालय जो gif का उपयोग करना आसान बनाता है ImageView


इसे हटा दिया गया है
मार्टिन मार्कोसिनी

मैंने इस लाइब्रेरी कोड के माध्यम से देखा है, यह 2 या अधिक वर्षों के लिए अच्छा होना चाहिए।
नाइटस्कीकोड

1
हां, मुझे लगता है कि यह अपेक्षाकृत ठीक है, बस यह इंगित करते हुए कि लेखक ने इसे रद्द करने का फैसला किया है। (और इसलिए इसे बनाए रखने के लिए नहीं), यह इंगित करते हुए कि हमें पिकासो की तरह कुछ का उपयोग करना चाहिए, जो अजीब है, क्योंकि पिकासो एक छवि डाउनलोडर है और यह आपकी मदद नहीं करेगा जब यह किसी भी कई डाउनलोड / कैश की तुलना में एक एनिमेटेड जिफ प्रदर्शित करने के लिए आता है। उपकरण वहाँ से बाहर।
मार्टिन मारकोसिनी

6

इसे आज़माएं, प्रगति कोड में bellow कोड प्रदर्शन gif फ़ाइल

loading_activity.xml (लेआउट फ़ोल्डर में)

<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 (ड्रा करने योग्य फ़ोल्डर में)

यहाँ मैंने black_gif.gif (drawable folder में) डाला, आप यहाँ अपना gif डाल सकते हैं

<?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 (रिस फ़ोल्डर में)

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);

    }

}

मैं तुम्हें जिफ घुमाते हुए देखता हूं। क्यों?
बजे AlikElzin-kilaka

आप कैसे आकर्षित करने योग्य फ़ोल्डर में जिफ डाल सकते हैं?
अपूर्वा

6

किसी ने आयन या ग्लाइड लाइब्रेरी का उल्लेख नहीं किया है । वे बहुत अच्छा काम करते हैं।

WebView की तुलना में इसे संभालना आसान है।


5

मुझे इस लेख के भीतर प्रस्तावित समाधान के साथ सफलता मिली है , एक वर्ग जिसे कहा जाता है GifMovieView, जो Viewतब प्रदर्शित किया जा सकता है या एक विशिष्ट में जोड़ा जा सकता है ViewGroup। निर्दिष्ट लेख के भाग 2 और 3 में प्रस्तुत अन्य विधियों को देखें।

इस पद्धति का एकमात्र दोष यह है कि फिल्म पर एंटीएलियासिंग अच्छा नहीं है ("छायादार" एंड्रॉइड Movieक्लास का उपयोग करने का एक साइड-इफेक्ट होना चाहिए )। फिर आप अपने एनिमेटेड GIF के भीतर पृष्ठभूमि को एक ठोस रंग में सेट करना बेहतर समझते हैं।


4

बिटमैपडबल उदाहरण पर कुछ विचार ... मूल रूप से यह android.graphics से प्राचीन, बल्कि फीचरहीन मूवी क्लास का उपयोग करता है। हाल के एपीआई संस्करणों पर आपको हार्डवेयर त्वरण को बंद करने की आवश्यकता है, जैसा कि यहां वर्णित है । यह अन्यथा मेरे लिए segfaulting था।

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

यहाँ बिटमैपडबल उदाहरण को केवल GIF भाग के साथ छोटा किया गया है। आपको अपना स्वयं का विजेट (दृश्य) बनाना होगा और इसे अपने आप से बनाना होगा। एक 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 अन्य विधियाँ, वेबव्यू के साथ ImageView के साथ एक और इस ठीक ट्यूटोरियल में पाया जा सकता है । ImageView विधि Google कोड से Apache लाइसेंस प्राप्त Android-gifview का उपयोग करती है ।


1
@luboz क्या आप मुझे बता सकते हैं कि Android प्रदर्शन के लिए कौन सा तरीका अच्छा है ... मैं छप स्क्रीन लोडिंग बार के लिए एनिमेटेड जिफ़ का उपयोग करना चाहता हूं। तो क्या आप कृपया सुझाव दे सकते हैं कि कौन सी विधि बेहतर है। मैं यह भी जानना चाहता हूं कि छवि दृश्य विधि का उपयोग करके क्या स्केल प्रकार की संपत्ति का उपयोग करना संभव है?
स्वप-आईओएस-एंड्रॉइड

4

@PointerNull ने अच्छा समाधान दिया, लेकिन यह सही नहीं है। यह बड़ी फ़ाइलों के साथ कुछ उपकरणों पर काम नहीं करता है और प्री आईसीएस संस्करण में डेल्टा फ्रेम के साथ छोटी गाड़ी जिफ एनीमेशन दिखाता है। मुझे इस बग के बिना हल मिल गया। यह देशी डिकोडिंग के साथ ड्रॉबल के लिए लाइब्रेरी है: कोरल का एंड्रॉइड-जिफ-ड्रॉएबल


2

इसे WebView में डालें, इसे सही तरीके से प्रदर्शित करने में सक्षम होना चाहिए, क्योंकि डिफ़ॉल्ट ब्राउज़र gif फ़ाइलों का समर्थन करता है। (फ्रोयो +, अगर मैं गलत नहीं हूँ)


यह सच नहीं है। सभी ब्राउज़र GIF का समर्थन नहीं करते हैं।
रिची एचएच

4
उम्मीद है कि हमें सभी ब्राउज़रों की आवश्यकता नहीं है ... स्टॉक ब्राउज़र एंड्रॉइड 2.2 के बाद से इसका समर्थन करता है, इसलिए मुझे डाउनवोट न करें, कृपया। एक WebView निश्चित रूप से GIF प्रदर्शित करेगा!
कीबी

2

हमारे एंड्रॉइड ऐप में एनिमेटेड जिफ़ लोड करने के लिए दो विकल्प हैं

1) जिफ़ को एक में लोड करने के लिए ग्लाइड का उपयोग करना ImageView

    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) gif को a में लोड करने के लिए html का उपयोग करना WebView

एड्रेस को .gif फाइल के साथ html बनाएं:

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

इस फ़ाइल को संपत्ति निर्देशिका में संग्रहीत करें:

यहां छवि विवरण दर्ज करें

इस html को अपने एप्लिकेशन के वेब दृश्य में लोड करें:

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

विधर्म इस दो विकल्पों का एक पूर्ण उदाहरण है

यहां छवि विवरण दर्ज करें


2

केवल Android API (Android Pie) के लिए 28 और +

के रूप में AnimatedImageDrawable का उपयोग करें

// 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 कोड, एक ImageView जोड़ें

<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 एक बच्चे के द्वारा बनाई गई है जो Drawable है ImageDecoder.decodeDrawable

ImageDecoder.decodeDrawableजिसके द्वारा आगे के उदाहरण की आवश्यकता ImageDecoder.Sourceहै ImageDecoder.createSource

ImageDecoder.createSourceस्रोत नाम बनाने के लिए केवल एक नाम, बाइटबफ़र, फ़ाइल, रिसोर्सआईड, यूआरआई, कंटेंट.ओवर के रूप में ले सकते हैं और इसे पॉलिमॉर्फिक कॉल के AnimatedImageDrawableरूप में बनाने के लिए उपयोग करते हैं।Drawable

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)

नोट: आप ImageDecoder # decodeBitmapBitmap का उपयोग करके भी बना सकते हैं ।

आउटपुट:

AnimatedDrawable आकार बदलने, फ्रेम और रंग हेरफेर का भी समर्थन करता है


1

मुझे लगता है कि gif फ़ाइलों को संभालने के लिए बेहतर पुस्तकालय यह एक है: कोरल द्वारा

इसका इस्तेमाल किया और मैं सफल रहा और यह लाइब्रेरी GIF'S को समर्पित है; लेकिन जैसा कि जहां पिकासो और ग्लाइड हैं सामान्य प्रयोजन छवि ढांचे; इसलिए मुझे लगता है कि इस लाइब्रेरी के डेवलपर्स जीआईएफ फाइलों पर पूरी तरह से केंद्रित हैं



1

बस यह जोड़ना चाहता था कि मूवी वर्ग अब पदावनत हो गया है।

इस कक्षा को एपीआई स्तर पी में पदावनत किया गया था।

इसका उपयोग करने की सिफारिश की जाती है

AnimatedImageDrawable

एनिमेटेड चित्र (जैसे जीआईएफ) खींचने के लिए आकर्षित करने योग्य।


1

Src फ़ोल्डर के अंतर्गत "Utils" नाम का एक पैकेज बनाएँ और "GifImageView" नाम का एक वर्ग बनाएँ।

public class GifImageView extends View {
    private InputStream mInputStream;
    private Movie mMovie;
    private int mWidth, mHeight;
    private long mStart;
    private Context mContext;
    public GifImageView(Context context) {
        super(context);
        this.mContext = context;
    }
    public GifImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public GifImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        if (attrs.getAttributeName(1).equals("background")) {
            int id = Integer.parseInt(attrs.getAttributeValue(1).substring(1));
            setGifImageResource(id);
        }
    }
    private void init() {
        setFocusable(true);
        mMovie = Movie.decodeStream(mInputStream);
        mWidth = mMovie.width();
        mHeight = mMovie.height();
        requestLayout();
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(mWidth, mHeight);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        long now = SystemClock.uptimeMillis();
        if (mStart == 0) {
            mStart = now;
        }
        if (mMovie != null) {
            int duration = mMovie.duration();
            if (duration == 0) {
                duration = 1000;
            }
            int relTime = (int) ((now - mStart) % duration);
            mMovie.setTime(relTime);
            mMovie.draw(canvas, 0, 0);
            invalidate();
        }
    }
    public void setGifImageResource(int id) {
        mInputStream = mContext.getResources().openRawResource(id);
        init();
    }
    public void setGifImageUri(Uri uri) {
        try {
            mInputStream = mContext.getContentResolver().openInputStream(uri);
            init();
        } catch (FileNotFoundException e) {
            Log.e("GIfImageView", "File not found");
        }
    }
}

अब GifImageView को MainActivity File में परिभाषित करें: src / activity / MainActivity.class

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        GifImageView gifImageView = (GifImageView) findViewById(R.id.GifImageView);
        gifImageView.setGifImageResource(R.drawable.smartphone_drib);
    }
}

अब UI भाग फ़ाइल: res / layout / activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:gravity="center"
    android:background="#111E39"
    tools:context=".Activity.MainActivity">
    <com.android.animatedgif.Utils.GifImageView
        android:id="@+id/GifImageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

</RelativeLayout>

Resourece कोड: Android उदाहरण


छवि का आकार बदलने के लिए कैसे, pls
मृत आदमी

0

सबसे पहले एंड्रॉइड ब्राउज़र को एनिमेटेड GIF का समर्थन करना चाहिए। अगर यह नहीं है तो यह एक बग है! इस मुद्दे पर नज़र रखें।

यदि आप इन एनिमेटेड GIF को ब्राउज़र के बाहर प्रदर्शित कर रहे हैं तो यह एक अलग कहानी हो सकती है। जो आप पूछ रहे हैं उसे करने के लिए बाहरी लाइब्रेरी की आवश्यकता होगी जो एनिमेटेड GIF के डिकोडिंग का समर्थन करती है।

कॉल का पहला पोर्ट जावा 2 डी या जेएआई (जावा एडवांस्ड इमेजिंग) एपीआई को देखना होगा, हालाँकि मुझे बहुत आश्चर्य होगा अगर एंड्रॉइड डालविक आपके ऐप में उन पुस्तकालयों का समर्थन करेगा।


कुछ डिवाइस एक वेब ब्राउज़र पर भी एनिमेटेड जिफ़ नहीं दिखाते हैं। एक उदाहरण के रूप में, मुझे पता है कि एंड्रॉइड 2.3.6 के साथ आकाशगंगा मिनी उन्हें नहीं दिखाता है।
Android डेवलपर

0

@ लोंटी ने जो कहा, उसके समान, लेकिन थोड़ी और गहराई के साथ:

मैंने एक ही समस्या को हल करने के लिए GIMP को खोल दिया था, एक को छोड़कर सभी परतों को छिपाएं, इसे अपनी छवि के रूप में निर्यात करें, और फिर उस परत को छिपाएं और अगले एक को अनहाइड करें, आदि, जब तक कि मेरे पास प्रत्येक के लिए व्यक्तिगत संसाधन फ़ाइलें न हों। । तब मैं उन्हें एनिमेशनड्राइवेबल एक्सएमएल फ़ाइल में फ्रेम के रूप में उपयोग कर सकता था।


1
यदि आपके पास इतना समय नहीं है तो आप फ्रेम को निकालने के लिए जिफिसल का उपयोग कर सकते हैं । साथ ही xml फाइलें बनाते समय अजगर या बैश बहुत काम आते हैं।
लूबोज़


0

कुछ मैंने ऐप में gif दिखाने के लिए किया। मैंने ImageView को विस्तारित किया ताकि लोग इसकी विशेषताओं का स्वतंत्र रूप से उपयोग कर सकें। यह यूआरएल से या संपत्ति निर्देशिका से gifs दिखा सकता है। पुस्तकालय भी इसे से विरासत में लेने के लिए कक्षाओं का विस्तार करना आसान बनाता है और जीआईएफ को आरंभीकृत करने के लिए विभिन्न तरीकों का समर्थन करने के लिए इसका विस्तार करता है।

https://github.com/Gavras/GIFView

गिथब पृष्ठ पर थोड़ा गाइड है।

यह एंड्रॉइड आर्सेनल पर भी प्रकाशित किया गया था:

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

उदाहरण का उपयोग करें:

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" />

गतिविधि में:

    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) {

        }
});

प्रोग्राम को व्यवस्थित रूप से सेट करना:

mGifView.setGifResource("asset:gif1");

0

सबसे आसान तरीका - नीचे दिए गए कोड पर विचार किया जा सकता है

हम Imageview setImageResource का लाभ उठा सकते हैं, उसी के लिए नीचे दिए गए कोड का संदर्भ लें।

नीचे दिए गए कोड का उपयोग gif incase जैसी छवि दिखाने के लिए किया जा सकता है यदि आपके पास gif की एकाधिक विभाजित छवि है। बस gif को एक ऑनलाइन टूल से अलग-अलग png में विभाजित करें और नीचे दिए गए क्रम की तरह ड्रॉबल में छवि डालें

image_1.png, image_2.png, आदि।

छवि को गतिशील रूप से बदलने के लिए हैंडलर रखें।

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

URL से सीधे अपने ऐप लेआउट में एनिमेटेड GIF प्रदर्शित करने का आसान तरीका WebView वर्ग का उपयोग करना है।

चरण 1: अपने लेआउट एक्सएमएल में

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

चरण 2: अपनी गतिविधि में

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

चरण 3: अपने घोषणापत्र में ।XML इंटरनेट की अनुमति दें

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

चरण 4: यदि आप अपनी GIF पृष्ठभूमि को पारदर्शी बनाना चाहते हैं और GIF को अपने लेआउट में फिट करना चाहते हैं

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


वर्कअराउंड के लिए धन्यवाद, लेकिन काफी डेवलपर एक स्मृति प्रभाव, सीपीयू उपयोग और बैटरी जीवनकाल के रूप में कुछ निहितार्थों के कारण गैर-देशी रेंडर नहीं करना चाहते हैं
ruX

-1

आप इस लिंक में पाए जाने वाले GifAnimationDrawable लाइब्रेरी का उपयोग कर सकते हैं - https://github.com/Hipmob/gifanimateddrawable , और जो किसी भी जिफ़ को एनिमेशनड्राइव में बदल सकते हैं। का आनंद लें :)


-8
public class Test extends GraphicsActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new SampleView(this));
  }

  private static class SampleView extends View {
    private Bitmap mBitmap;
    private Bitmap mBitmap2;
    private Bitmap mBitmap3;
    private Bitmap mBitmap4;
    private Drawable mDrawable;

    private Movie mMovie;
    private long mMovieStart;

    // Set to false to use decodeByteArray
    private static final boolean DECODE_STREAM = true;

    private static byte[] streamToBytes(InputStream is) {
      ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
      byte[] buffer = new byte[1024];
      int len;
      try {
        while ((len = is.read(buffer)) >= 0) {
          os.write(buffer, 0, len);
        }
      } catch (java.io.IOException e) {
      }
      return os.toByteArray();
    }

    public SampleView(Context context) {
      super(context);
      setFocusable(true);

      java.io.InputStream is;
      is = context.getResources().openRawResource(R.drawable.icon);

      BitmapFactory.Options opts = new BitmapFactory.Options();
      Bitmap bm;

      opts.inJustDecodeBounds = true;
      bm = BitmapFactory.decodeStream(is, null, opts);

      // now opts.outWidth and opts.outHeight are the dimension of the
      // bitmap, even though bm is null

      opts.inJustDecodeBounds = false; // this will request the bm
      opts.inSampleSize = 4; // scaled down by 4
      bm = BitmapFactory.decodeStream(is, null, opts);

      mBitmap = bm;

      // decode an image with transparency
      is = context.getResources().openRawResource(R.drawable.icon);
      mBitmap2 = BitmapFactory.decodeStream(is);

      // create a deep copy of it using getPixels() into different configs
      int w = mBitmap2.getWidth();
      int h = mBitmap2.getHeight();
      int[] pixels = new int[w * h];
      mBitmap2.getPixels(pixels, 0, w, 0, 0, w, h);
      mBitmap3 = Bitmap.createBitmap(pixels, 0, w, w, h,
          Bitmap.Config.ARGB_8888);
      mBitmap4 = Bitmap.createBitmap(pixels, 0, w, w, h,
          Bitmap.Config.ARGB_4444);

      mDrawable = context.getResources().getDrawable(R.drawable.icon);
      mDrawable.setBounds(150, 20, 300, 100);

      is = context.getResources().openRawResource(R.drawable.animated_gif);

      if (DECODE_STREAM) {
        mMovie = Movie.decodeStream(is);
      } else {
        byte[] array = streamToBytes(is);
        mMovie = Movie.decodeByteArray(array, 0, array.length);
      }
    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawColor(0xFFCCCCCC);

      Paint p = new Paint();
      p.setAntiAlias(true);

      canvas.drawBitmap(mBitmap, 10, 10, null);
      canvas.drawBitmap(mBitmap2, 10, 170, null);
      canvas.drawBitmap(mBitmap3, 110, 170, null);
      canvas.drawBitmap(mBitmap4, 210, 170, null);

      mDrawable.draw(canvas);

      long now = android.os.SystemClock.uptimeMillis();
      if (mMovieStart == 0) { // first time
        mMovieStart = now;
      }
      if (mMovie != null) {
        int dur = mMovie.duration();
        if (dur == 0) {
          dur = 1000;
        }
        int relTime = (int) ((now - mMovieStart) % dur);
        mMovie.setTime(relTime);
        mMovie.draw(canvas, getWidth() - mMovie.width(), getHeight()
            - mMovie.height());
        invalidate();
      }
    }
  }
}

class GraphicsActivity extends Activity {
  // set to true to test Picture
  private static final boolean TEST_PICTURE = false;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  }

  @Override
  public void setContentView(View view) {
    if (TEST_PICTURE) {
      ViewGroup vg = new PictureLayout(this);
      vg.addView(view);
      view = vg;
    }

    super.setContentView(view);
  }
}

class PictureLayout extends ViewGroup {
  private final Picture mPicture = new Picture();

  public PictureLayout(Context context) {
    super(context);
  }

  public PictureLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  @Override
  public void addView(View child) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child);
  }

  @Override
  public void addView(View child, int index) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index);
  }

  @Override
  public void addView(View child, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, params);
  }

  @Override
  public void addView(View child, int index, LayoutParams params) {
    if (getChildCount() > 1) {
      throw new IllegalStateException(
          "PictureLayout can host only one direct child");
    }

    super.addView(child, index, params);
  }

  @Override
  protected LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.MATCH_PARENT);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    final int count = getChildCount();

    int maxHeight = 0;
    int maxWidth = 0;

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        measureChild(child, widthMeasureSpec, heightMeasureSpec);
      }
    }

    maxWidth += getPaddingLeft() + getPaddingRight();
    maxHeight += getPaddingTop() + getPaddingBottom();

    Drawable drawable = getBackground();
    if (drawable != null) {
      maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
      maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
    }

    setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
        resolveSize(maxHeight, heightMeasureSpec));
  }

  private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx,
      float sy) {
    canvas.save();
    canvas.translate(x, y);
    canvas.clipRect(0, 0, w, h);
    canvas.scale(0.5f, 0.5f);
    canvas.scale(sx, sy, w, h);
    canvas.drawPicture(mPicture);
    canvas.restore();
  }

  @Override
  protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
    mPicture.endRecording();

    int x = getWidth() / 2;
    int y = getHeight() / 2;

    if (false) {
      canvas.drawPicture(mPicture);
    } else {
      drawPict(canvas, 0, 0, x, y, 1, 1);
      drawPict(canvas, x, 0, x, y, -1, 1);
      drawPict(canvas, 0, y, x, y, 1, -1);
      drawPict(canvas, x, y, x, y, -1, -1);
    }
  }

  @Override
  public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
    location[0] = getLeft();
    location[1] = getTop();
    dirty.set(0, 0, getWidth(), getHeight());
    return getParent();
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    final int count = super.getChildCount();

    for (int i = 0; i < count; i++) {
      final View child = getChildAt(i);
      if (child.getVisibility() != GONE) {
        final int childLeft = getPaddingLeft();
        final int childTop = getPaddingTop();
        child.layout(childLeft, childTop,
            childLeft + child.getMeasuredWidth(),
            childTop + child.getMeasuredHeight());

      }
    }
  }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.