我在缩放 GIF 电影帧时遇到问题。我在绘制框架之前使用 Canvas.scale(float sx, float sy) 。但它不绘制缩放框架,它什么也不画。有什么想法吗?
问问题
2284 次
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 回答