2

我在缩放 GIF 电影帧时遇到问题。我在绘制框架之前使用 Canvas.scale(float sx, float sy) 。但它不绘制缩放框架,它什么也不画。有什么想法吗?

4

4 回答 4

3

如果您尝试在另一个布局中创建一个可缩放且可重用的专用视图,您也应该使用视图的 getWidth() 和 getHeight() 方法。

我在更改视图的专用尺寸时遇到了这个问题:canvas.getWidth() 是整个屏幕的宽度,而不是视图的宽度,所以我修改了 onDraw 方法如下。

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawColor(Color.TRANSPARENT);
    super.onDraw(canvas);

    long now = android.os.SystemClock.uptimeMillis();  

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

    if (cur == 0) cur = now;  

    if(movie != null)
    {
        float scale = 1f;
        if(movie.height() > getHeight() || movie.width() > getWidth())
            scale = ( 1f / Math.min(canvas.getHeight() / movie.height(), canvas.getWidth() / movie.width()) ) + 0.25f;
        else    
            scale = Math.min(canvas.getHeight() / movie.height(), canvas.getWidth() / movie.width());

        canvas.scale(scale, scale);
        canvas.translate(((float)getWidth() / scale - (float)movie.width())/2f,
                ((float)getHeight() / scale - (float)movie.height())/2f);

        int relTime = (int)((now - cur) % movie.duration());
        movie.setTime(relTime);
        movie.draw(canvas, 0, 0);


        invalidate();
    }
}

注意 getWidth(), getHeight() if 语句检查电影是否大于视图,在我的情况下,我的视图高度是 160,但我的 GIF 是 260,但是使用其他方法总是会将 GIF 画得太大,通过这些更改,我能够测试并看到它在我的视图为 1280 X 900 并且图像按比例放大的情况下以及我的视图为 1000 X 160 并且它按比例缩小的情况下工作。

祝你好运,玩得开心:D

-克里斯

于 2014-05-03T09:44:35.527 回答
2

这应该有效。

protected void onDraw(Canvas canvas)
{
    canvas.drawColor(Color.TRANSPARENT);

    canvas.scale(0.5f, 0.5f); // scale gif to its half size

    super.onDraw(canvas);

    /* movie.setTime . . . */

    movie.draw(canvas, ...);

    this.invalidate();

}
于 2012-12-15T19:09:20.273 回答
1

这是我的解决方案:

public class GifImageView extends View {
    private InputStream mInputStream;
    private Movie mMovie;
    public 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;
            }

            float scale = Math.min((float) canvas.getHeight() / (float) mMovie.height(), (float) canvas.getWidth() / (float) mMovie.width());

            canvas.scale(scale, scale);
            canvas.translate(((float) mWidth / scale - (float) mMovie.width()) / 2f,
                ((float) mHeight / scale - (float) mMovie.height()) / 2f);

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

    public void setSize(int dimension) {
        mWidth = dimension;
        mHeight = dimension;
    }
}

将其添加到您的布局文件中:

<GifImageView
        android:id="@+id/gifView"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerHorizontal="true"
        android:background="@drawable/image" />

那么您可以简单地在 Java 代码中设置维度:

gifView.setSize(dimension);
于 2018-08-24T07:34:17.670 回答
0

此示例允许我们根据图像的原始大小调整GIF的大小并适合屏幕。

在此处输入图像描述

PlayGifView.class

public class PlayGifView extends View{

    private static final int DEFAULT_MOVIEW_DURATION = 1000;

    private int mMovieResourceId;
    private Movie mMovie;

    private long mMovieStart = 0;
    private int mCurrentAnimationTime = 0;
public Context context;
    @SuppressLint("NewApi")
    public PlayGifView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
       /**
        * Starting from HONEYCOMB have to turn off HardWare acceleration to draw
        * Movie on Canvas.
        */
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
           setLayerType(View.LAYER_TYPE_SOFTWARE, null);
       }

   }

    public void setImageResource(int mvId){
        this.mMovieResourceId = mvId;
       mMovie = Movie.decodeStream(getResources().openRawResource(mMovieResourceId));
       requestLayout();
    }

    public void setMovieData(Movie movieImg){
        mMovie = movieImg;
        requestLayout();
    }

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
   if(mMovie != null){

       //Find higest
       int exceptedSize = 200;
       int highest = 0;
       int quality = 0;
       if(mMovie.height()>mMovie.width()){
           highest=mMovie.height();
       }else{
           highest=mMovie.width();
       }

       //Get Display Size
       Display display = ((Activity) getContext()).getWindowManager().getDefaultDisplay();
       Point size = new Point();
       display.getSize(size);

       setMeasuredDimension((int)(((float)mMovie.width()/(float)highest)*((float) size.x))
               , (int)(((float)mMovie.height()/(float)highest)*((float)size.x)));
   }else{
       setMeasuredDimension(getSuggestedMinimumWidth(), getSuggestedMinimumHeight());
   }
}

@Override
protected void onDraw(Canvas canvas) {
   if (mMovie != null){
       updateAnimtionTime();

       //Get Display Size
       Display display = ((Activity) getContext()).getWindowManager().getDefaultDisplay();
       Point size = new Point();
       display.getSize(size);

       float scale = Math.max((float) canvas.getHeight() / (float) mMovie.height(), (float) canvas.getWidth() / (float) mMovie.width());

       canvas.scale(scale, scale);
       canvas.translate(((float) size.x / scale - (float) mMovie.width()) / 2f,
               0);

       drawGif(canvas);
       invalidate();
   }else{
//       drawGif(canvas);
   }
}

private void updateAnimtionTime() {
   long now = android.os.SystemClock.uptimeMillis();

   if (mMovieStart == 0) {
       mMovieStart = now;
   }
   int dur = mMovie.duration();
   if (dur == 0) {
       dur = DEFAULT_MOVIEW_DURATION;
   }
   mCurrentAnimationTime = (int) ((now - mMovieStart) % dur);
}

private void drawGif(Canvas canvas) {
   mMovie.setTime(mCurrentAnimationTime);
   mMovie.draw(canvas, 0, 0);
   canvas.restore();
}

}

主要活动.class

PlayGifView pGif = findViewById(R.id.viewGif);
pGif.setImageResource(R.drawable.ads1);

activity_main.xml

<com.---- Yours-----.PlayGifView
    android:id="@+id/viewGif"
    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
于 2019-11-18T17:40:09.267 回答