无法在Android Canvas中缩放gif移动框架

时间:2012-07-28 16:34:30

标签: android scale android-canvas gif

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

4 个答案:

答案 0 :(得分:3)

如果您尝试在另一个布局中制作可缩放且可重复使用的专用视图,则还应使用View的getWidth()和getHeight()方法。

我在更改View的专用大小时遇到​​了这个问题: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太大了,通过这些更改,我能够测试并看到它在我的View为1280 X 900并且图像放大以及我的视图为1000 X 160并且缩小的两种情况下都有效。

祝你好运,玩得开心:D

-Chris

答案 1 :(得分:1)

这应该有效。

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

}

答案 2 :(得分:0)

这是我的解决方案:

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

答案 3 :(得分:0)

此示例使我们可以调整 GIF 的大小,并相应地适合屏幕以适应图像的原始大小。

enter image description here

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" />