mirror of
https://github.com/nextcloud/android.git
synced 2024-11-21 12:45:32 +03:00
Merge pull request #9 from nextcloud/animatedGif
Support animated GiF-Images
This commit is contained in:
commit
704ffb4bac
2 changed files with 88 additions and 15 deletions
|
@ -4,13 +4,18 @@ import android.annotation.SuppressLint;
|
|||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Movie;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class ImageViewCustom extends ImageView {
|
||||
|
||||
private static final String TAG = ImageViewCustom.class.getSimpleName();
|
||||
|
@ -23,7 +28,12 @@ public class ImageViewCustom extends ImageView {
|
|||
private int mBitmapHeight;
|
||||
private int mBitmapWidth;
|
||||
|
||||
|
||||
private Movie mGifMovie;
|
||||
private int mMovieWidth, mMovieHeight;
|
||||
private long mMovieDuration;
|
||||
private long mMovieRunDuration;
|
||||
private long mLastTick;
|
||||
|
||||
public ImageViewCustom(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
@ -39,18 +49,60 @@ public class ImageViewCustom extends ImageView {
|
|||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
|
||||
if(IS_ICS_OR_HIGHER && checkIfMaximumBitmapExceed(canvas) || IS_VERSION_BUGGY_ON_RECYCLES ) {
|
||||
// Software type is set with two targets:
|
||||
// 1. prevent that bitmaps larger than maximum textures allowed are shown as black views in devices
|
||||
// with LAYER_TYPE_HARDWARE enabled by default;
|
||||
// 2. grant that bitmaps are correctly dellocated from memory in versions suffering the bug fixed in
|
||||
// 2. grant that bitmaps are correctly de-allocated from memory in versions suffering the bug fixed in
|
||||
// https://android.googlesource.com/platform/frameworks/base/+/034de6b1ec561797a2422314e6ef03e3cd3e08e0;
|
||||
//
|
||||
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||
}
|
||||
|
||||
super.onDraw(canvas);
|
||||
if(mGifMovie != null) {
|
||||
long nowTick = android.os.SystemClock.uptimeMillis();
|
||||
if (mLastTick == 0) {
|
||||
mMovieRunDuration = 0;
|
||||
} else {
|
||||
mMovieRunDuration += nowTick - mLastTick;
|
||||
if(mMovieRunDuration > mMovieDuration) {
|
||||
mMovieRunDuration = 0;
|
||||
}
|
||||
}
|
||||
|
||||
mGifMovie.setTime((int) mMovieRunDuration);
|
||||
|
||||
float scale = getScaleToViewFactor(mGifMovie, canvas);
|
||||
|
||||
canvas.scale(scale, scale);
|
||||
canvas.translate(((float) getWidth() / scale - (float) mGifMovie.width()) / 2f,
|
||||
((float) getHeight() / scale - (float) mGifMovie.height()) /2f);
|
||||
|
||||
mGifMovie.draw(canvas, 0, 0);
|
||||
|
||||
mLastTick = nowTick;
|
||||
invalidate();
|
||||
} else {
|
||||
super.onDraw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
private float getScaleToViewFactor(Movie movie, Canvas canvas) {
|
||||
if (movie.height() > getHeight() || movie.width() > getWidth()) {
|
||||
float offset = 0.25f;
|
||||
return (1f / Math.min(canvas.getHeight() / movie.height(), canvas.getWidth() / movie.width())) + offset;
|
||||
}
|
||||
|
||||
return Math.min(canvas.getHeight() / movie.height(), canvas.getWidth() / movie.width());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
if (mGifMovie == null) {
|
||||
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
|
||||
} else {
|
||||
setMeasuredDimension(mMovieWidth, mMovieHeight);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,24 +112,40 @@ public class ImageViewCustom extends ImageView {
|
|||
*/
|
||||
@SuppressLint("NewApi")
|
||||
private boolean checkIfMaximumBitmapExceed(Canvas canvas) {
|
||||
Log_OC.v(TAG, "Canvas maximum: " + canvas.getMaximumBitmapWidth() + " - " + canvas.getMaximumBitmapHeight());
|
||||
if (mBitmapWidth > canvas.getMaximumBitmapWidth()
|
||||
|| mBitmapHeight > canvas.getMaximumBitmapHeight()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return mBitmapWidth > canvas.getMaximumBitmapWidth()
|
||||
|| mBitmapHeight > canvas.getMaximumBitmapHeight();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Keeps the size of the bitmap cached in member variables for faster access in {@link #onDraw(Canvas)} ,
|
||||
* Keeps the size of the bitmap cached in member variables for faster access in {@link #onDraw(Canvas)},
|
||||
* but without keeping another reference to the {@link Bitmap}
|
||||
*/
|
||||
public void setImageBitmap (Bitmap bm) {
|
||||
public void setImageBitmap(Bitmap bm) {
|
||||
mBitmapWidth = bm.getWidth();
|
||||
mBitmapHeight = bm.getHeight();
|
||||
super.setImageBitmap(bm);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the GIF image of the given storage path.
|
||||
*
|
||||
* @param storagePath the storage path of the GIF image
|
||||
*/
|
||||
public void setGIFImageFromStoragePath(String storagePath) {
|
||||
try {
|
||||
InputStream gifInputStream = new FileInputStream(storagePath);
|
||||
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
|
||||
setFocusable(true);
|
||||
|
||||
mGifMovie = Movie.decodeStream(gifInputStream);
|
||||
mMovieWidth = mGifMovie.width();
|
||||
mMovieHeight = mGifMovie.height();
|
||||
mMovieDuration = mGifMovie.duration();
|
||||
} catch (Exception e) {
|
||||
Log_OC.e(TAG, "Failed to set GIF image");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -499,12 +499,17 @@ public class PreviewImageFragment extends FileFragment {
|
|||
Log_OC.d(TAG, "Showing image with resolution " + bitmap.getWidth() + "x" +
|
||||
bitmap.getHeight());
|
||||
|
||||
if (result.ocFile.getMimetype().equalsIgnoreCase("image/png")){
|
||||
if (result.ocFile.getMimetype().equalsIgnoreCase("image/png")) {
|
||||
Drawable backrepeat = getResources().getDrawable(R.drawable.backrepeat);
|
||||
imageView.setBackground(backrepeat);
|
||||
}
|
||||
|
||||
imageView.setImageBitmap(bitmap);
|
||||
if (result.ocFile.getMimetype().equalsIgnoreCase("image/gif")) {
|
||||
imageView.setGIFImageFromStoragePath(result.ocFile.getStoragePath());
|
||||
} else {
|
||||
imageView.setImageBitmap(bitmap);
|
||||
}
|
||||
|
||||
imageView.setVisibility(View.VISIBLE);
|
||||
mBitmap = bitmap; // needs to be kept for recycling when not useful
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue