Android : URL이 주어진 큰 애니메이션 GIF는 어떻게 표시됩니까?
-
03-07-2019 - |
문제
큰 애니메이션 GIF의 URL을 가지고 있다고 가정하고 스트리밍 방식으로 애니메이션을 표시하는 YouTube와 같은 활동을 만들고 싶었습니다. 내가 어떻게 할
- 이미지에서 스트리밍?
- 실제 애니메이션으로 표시 되나요?
알아요 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);
결과는 여기에 있습니다 :-
여기에서 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 프레임 워크의 애니메이션 흡기 가능을 사용할 수 있습니다.
간단한 진행률 막대의 경우 오류가 적고 성능이 훨씬 높을 수 있습니다.