programing

애니메이션 GIF 표시

goodcopy 2022. 8. 10. 21:21
반응형

애니메이션 GIF 표시

애니메이션 GIF 이미지를 A에 표시하고 싶다.Android는 애니메이션 GIF를 지원하지 않는 것을 어렵게 알게 되었습니다.

그러나 AnimationDrawable을 사용하여 애니메이션을 표시할 수 있습니다.

[개발] > [가이드]> [이미지&그래픽]> [그림]의 개요

이 예에서는 어플리케이션리소스에 프레임으로 저장된 애니메이션을 사용하고 있습니다만, 필요한 것은 애니메이션 GIF를 직접 표시하는 것입니다.

애니메이션 GIF를 프레임에 분할하여 각각의 프레임을 애니메이션 드로잉 가능으로 추가할 예정입니다.

애니메이션 GIF에서 프레임을 추출하여 각각 드로잉 가능한 것으로 변환하는 방법을 아는 사람이 있습니까?

Android는 실제로 Android.graphics를 사용하여 애니메이션 GIF를 디코딩하고 표시할 수 있습니다.영화 수업.

이는 문서화되어 있지 않지만 SDK 참조에 기재되어 있습니다.또한 비트맵 디코드 예제의 ApiDemos 샘플에서 일부 애니메이션 플래그를 사용하여 사용됩니다.

갱신:

활공 사용:

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

사용방법:

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

문서를 참조하다

또한 (main/htmls/name.gif) [이 html을 사용하여 크기에 맞게 조정]

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

예를 들어 다음과 같이 XML로 선언합니다(main/res/layout/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);

제안: 자세한 내용은 https://developer.android.com/reference/android/graphics/drawable/AnimationDrawable.html에서 정적 이미지를 사용하여 gif를 로드하는 것이 좋습니다.

이상입니다. 잘 부탁드립니다.

현재 Glide https://github.com/bumptech/glide을 사용할 수 있습니다.

gif 애니메이션을 프레임으로 분할하여 폰에 저장하기 때문에 Android에서는 대응하지 않아도 됩니다.

그런 다음 모든 프레임을 전화기에 다운로드하고 Drawable을 만든 다음 Animation Drawable을 만듭니다.이것은 질문의 예와 매우 유사합니다.

나는 아주 쉬운 방법을 찾았다. 여기 좋고 간단한 작업 예제를 가지고 있다.

애니메이션 위젯 표시

동작시키기 전에 코드로 해야 할 일이 몇 가지 있습니다.

이하에 기재

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

학급의 이름에 의하면...

이 작은 변화들을 한 후에 그것은 나에게 효과가 있을 것이다...

이것이 도움이 되기를 바란다

활공 4.6

1. gif를 로드하려면

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

Android에서 애니메이션 GIF를 표시하는 방법:

  • 영화 수업.위에서 말한 것처럼 꽤 버그가 심합니다.
  • Web View.그것은 매우 사용하기 쉽고 보통 작동한다.하지만 때로는 잘못된 행동을 하기 시작하기도 하고, 항상 가지고 있지 않은 불분명한 기기에 있습니다.또한 모든 종류의 목록 보기에서 여러 인스턴스를 사용할 수 없습니다. 여러 인스턴스가 메모리에 영향을 미치기 때문입니다.그래도 주요 접근법으로 간주할 수 있습니다.
  • GIF를 비트맵으로 디코딩하여 Drawable 또는 ImageView로 표시하는 커스텀 코드.다음 두 가지 라이브러리에 대해 설명하겠습니다.

https://github.com/koral--/android-gif-drawable - 디코더는 C로 구현되어 있기 때문에 매우 효율적입니다.

https://code.google.com/p/giffiledecoder - 디코더는 Java로 구현되어 있어 조작이 용이합니다.대용량 파일에서도 여전히 상당히 효율적입니다.

또한 GifDecoder 클래스를 기반으로 하는 많은 라이브러리를 찾을 수 있습니다.Java 기반의 디코더이기도 하지만 전체 파일을 메모리에 로드하는 방식으로 작동하기 때문에 작은 파일에만 적용됩니다.

Android에서 동작하는 gif 애니메이션을 만드는 것이 너무 힘들었어요.다음 두 가지 작업만 수행했습니다.

  1. 웹 뷰
  2. 이온

WebView는 정상적으로 동작하며 매우 간단하지만 문제는 뷰 로딩 속도가 느려지고 앱이 1초 정도 응답하지 않는다는 것입니다.나는 그것을 좋아하지 않았다.그래서 여러 가지 방법을 시도해 보았습니다(실효하지 않았습니다).

  1. 이미지 표시Ex는 더 이상 사용되지 않습니다!
  2. 피카소는 애니메이션 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");

Glide

Android용 Image Loader Library(Google 권장).

  • 글라이드는 피카소와 꽤 비슷하지만 피카소보다 훨씬 빠르다.
  • 글라이드는 피카소보다 기억력이 적다.

글라이드는 가지고 있지만 피카소는 가지고 있지 않은 것

GIF 애니메이션을 심플한 ImageView에 로드하는 기능은 Glide의 가장 흥미로운 기능입니다.그래, 피카소로는 그럴 수 없어여기에 이미지 설명 입력 몇 가지 중요한 링크-

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

ImageViewEx를 사용하면 GIF를 쉽게 사용할 수 있습니다.ImageView

실행해 보십시오. 진행 표시줄에서 벨로 코드 표시 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(그리기 가능한 폴더에)를 넣을 수 있으며, 여기에 당신의 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%" />

Loading Activity.java(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);

    }

}

아무도 이온이나 글라이드 도서관을 언급하지 않았다.그들은 매우 잘 작동한다.

WebView에 비해 조작이 용이합니다.

는 이 기사에서 제안한 해결책으로 성공을 거두었다.GifMovieViewView그런 다음 특정에 표시 또는 추가할 수 있습니다.ViewGroup 의 파트 2 및 3에 된 다른 하십시오. 지정된 문서의 파트 2 및 파트 3에 제시된 다른 방법을 확인하십시오.

좋지 입니다(' 안드로이드를 ).MovieGIF 에서 배경을 단색으로 설정하는 .그런 다음 애니메이션 GIF 내에서 배경을 단색으로 설정하는 것이 좋습니다.

비트맵 디코드 예에 대한 몇 가지 생각...기본적으로는 Android.graphics의 오래된 무비 클래스를 사용합니다.최신 API 버전에서는 여기에 설명된 바와 같이 하드웨어 가속을 해제해야 합니다.그렇지 않으면 세그먼트 폴트였어요.

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

다음은 GIF 부분만 줄인 BitmapDecode 예제입니다.위젯(보기)을 직접 만들어 직접 그려야 합니다.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를 사용하는 방법, WebView를 사용하는 방법을 훌륭한 튜토리얼에서 확인할 수 있습니다.ImageView메서드는 Google Code에서 Apache 라이선스가 부여된 Android-gifview를 사용합니다.

@PointerNull은 좋은 해결책을 제시했지만 완벽하지는 않다.대용량 파일이 있는 일부 장치에서는 작동하지 않으며 ICS 이전 버전에서 델타 프레임이 있는 버그 Gif 애니메이션을 표시합니다.이 버그가 없는 해결책을 찾았습니다.이것은 Koral의 Android-gif-drawable이라는 네이티브 디코딩 기능을 갖춘 라이브러리입니다.

Android API(Android Pie)28 및 + 전용

use 애니메이션 이미지 그리기 가능 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 코드, 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.createSourcesource를 이름으로만 사용할 수 있습니다.ByteBuffer 、 File 、 resourceId 、 URI 、 ContentResolver can can object and and오브젝트 작성에 사용할 수 있습니다.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)

주의: 다음 항목을 만들 수도 있습니다.BitmapImageDecoder#decodeBitmap을 사용합니다.

출력:

Animated Drawable은 크기 조정, 프레임 및 색상 조작도 지원합니다.

WebView에 넣으면 기본 브라우저가 gif 파일을 지원하므로 올바르게 표시할 수 있어야 합니다.(Froyo+, 틀리지 않았다면)

Android 앱에 애니메이션 GIF를 로드하려면 두 가지 옵션이 있습니다.

1) GIF를 Glide로 로드하여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) html을 사용하여 gif를 로딩합니다.WebView

.gif 파일의 주소를 사용하여 html을 만듭니다.

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

이 파일을 자산 디렉토리에 저장합니다.

여기에 이미지 설명 입력

응용 프로그램의 WebView에 다음 html을 로드합니다.

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

다음은 이 두 가지 옵션의 완전한 예입니다.

여기에 이미지 설명 입력

gif 파일을 처리하는 데 더 좋은 라이브러리는 이것이라고 생각합니다: by koral

그것을 사용했고, 나는 성공했고, 이 라이브러리는 GIF 전용이다; 하지만 피카소와 글라이드는 범용 이미지 프레임워크이다; 그래서 나는 이 라이브러리의 개발자들이 전적으로 GIF 파일에 집중했다고 생각한다.

프레스코를 사용하세요.방법은 다음과 같습니다.

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

샘플에 대한 레포는 다음과 같습니다.

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

프레스코는 랩 콘텐츠를 지원하지 않습니다!

Movie 클래스는 이제 더 이상 사용되지 않습니다.

이 클래스는 API 수준 P에서 더 이상 사용되지 않습니다.

이것을 사용하는 것을 추천합니다.

애니메이션 이미지 그리기 가능

애니메이션 이미지(GIF 등)를 그리기 위해 그릴 수 있습니다.

@Leonti가 말한 것과 비슷하지만 좀 더 자세히 설명하겠습니다.

같은 문제를 해결하기 위해 GIMP를 열고 한 레이어를 제외한 모든 레이어를 숨긴 후 자체 이미지로 내보낸 다음 레이어를 숨기고 다음 레이어 숨김을 해제하는 등 각 레이어에 대한 개별 리소스 파일이 있을 때까지 작업을 수행했습니다.그런 다음 AnimationDrawable XML 파일의 프레임으로 사용할 수 있습니다.

앱으로 gif를 보여주면서 했던 거.Image View의 속성을 자유롭게 사용할 수 있도록 확장했습니다.URL 또는 자산 디렉토리에서 gif를 표시할 수 있습니다.또한 라이브러리를 사용하면 클래스를 쉽게 확장하고 클래스를 확장하여 gif를 초기화하는 다양한 방법을 지원할 수 있습니다.

https://github.com/Gavras/GIFView

기트허브 페이지에 작은 가이드가 있어요.

Android Arsenal에도 게재되었습니다.

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

        }
});

프로그래밍 방식으로 gif 설정:

mGifView.setGifResource("asset:gif1");

가장 쉬운 방법 - 아래 코드를 고려할 수 있습니다.

Imageview setImageResource 를 이용할 수 있습니다.아래의 코드도 같은 것을 참조해 주세요.

아래 코드는 gif의 다중 분할 이미지가 있는 경우 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);
// 
                    }
                });
              }

URL에서 앱 레이아웃으로 바로 애니메이션 GIF를 표시하는 쉬운 방법은 WebView 클래스를 사용하는 것입니다.

순서 1: 레이아웃 XML에서

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

gif 로딩에 Glide를 사용하려는 경우:

Glide.with(this)
        .asGif()
        .load(R.raw.onboarding_layers) //Your gif resource
        .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.NONE))
        .listener(new RequestListener<GifDrawable>() {
            @Override
            public boolean onLoadFailed(@Nullable @org.jetbrains.annotations.Nullable GlideException e, Object model, Target<GifDrawable> target, boolean isFirstResource) {
                return false;
            }

            @Override
            public boolean onResourceReady(GifDrawable resource, Object model, Target<GifDrawable> target, DataSource dataSource, boolean isFirstResource) {
                resource.setLoopCount(1);
                return false;
            }
        })
        .into((ImageView) view.findViewById(R.id.layer_icons));

자원을 절약하기 위해 글라이드 라이브러리가 있습니다.이미지만 표시하기 위해 특별한 웹뷰를 사용해야 하는 이유를 알 수 없습니다.Glide는 gif에서 그릴 수 있는 애니메이션을 준비하여 이미지 뷰에 직접 넣는 완벽하고 쉬운 라이브러리입니다.gifdrawable 핸들 애니메이션 자체의 논리.Gif에는 애니메이션의 원시 RGB 데이터가 압축되어 있습니다.웹뷰 사용이 복잡할 필요는 없으며 앱에 gif 파일만 표시되도록 더 많은 파일을 관리할 수 있습니다.

우선 Android 브라우저는 애니메이션 GIF를 지원해야 합니다.그렇지 않다면 그것은 벌레입니다!문제 추적기를 살펴보십시오.

이러한 애니메이션 GIF를 브라우저 외부에 표시하는 경우 이야기가 달라질 수 있습니다.원하는 작업을 수행하려면 애니메이션 GIF 디코딩을 지원하는 외부 라이브러리가 필요합니다.

첫 번째 방문지는 Java2D 또는 JAI(Java Advanced Imaging) API를 살펴보는 것이지만, Android Dalvik이 당신의 앱에서 이러한 라이브러리를 지원한다면 매우 놀랄 것입니다.

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

      }
    }
  }
}

언급URL : https://stackoverflow.com/questions/3660209/display-animated-gif

반응형