Android : URL이 주어진 큰 애니메이션 GIF는 어떻게 표시됩니까?

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

  •  03-07-2019
  •  | 
  •  

문제

큰 애니메이션 GIF의 URL을 가지고 있다고 가정하고 스트리밍 방식으로 애니메이션을 표시하는 YouTube와 같은 활동을 만들고 싶었습니다. 내가 어떻게 할

  1. 이미지에서 스트리밍?
  2. 실제 애니메이션으로 표시 되나요?

알아요 ImageView 첫 번째 프레임만을 보여주기 때문에 대답이 아닙니다.

보너스는 버퍼링 상태에 액세스 할 수 있으므로 스트리밍 사운드도 동기화 할 수 있습니다. ytmnd 뷰어 응용 프로그램. 공개 GIF 파일을 더 좋은 형식으로 트랜스 코딩하는 서비스를 만들 수는 있지만 추가 종속성없이 앱이 작동하도록합니다.

도움이 되었습니까?

해결책

솔루션의 일반적인 스케치는 고용 사용자 정의를 사용하는 것입니다. View 묻는 것은 a 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

아마도 애니메이션 촬영 가능 당신을 위해 일할 수 있습니까? 편집 :이 게시물과 같이 URL에서로드하려는 경우가 아닙니다. 죄송합니다

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

GIF IE의 복잡성에 따라 간단한 로딩/진행 지표 인 경우 GIF를 분리하고 각 이미지를 별도로 저장 한 다음 Android 프레임 워크의 애니메이션 흡기 가능을 사용할 수 있습니다.

간단한 진행률 막대의 경우 오류가 적고 성능이 훨씬 높을 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top