前些天朋友用surfaceView组件显示图片时遇到只能显示半张图片问题。一开始我以为图片过大,于是换了张小图片试试,结果小图片只显示在surfaceView的一角,其他部分为surfaceView的黑色部分。
http://download.csdn.net/detail/renzaijianghu12354/8038399
经过我的分析研究对图片进行了缩放达到了图片完整显示的目的,废话少说,下面介绍一下我的方法。
public class MainActivity extends Activity {
private SurfaceView sf;
private SurfaceHolder holder;
float h;
float w;
// int opts;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sf = (SurfaceView)findViewById(R.id.surfaceView1);
// 得到屏幕管理器
WindowManager wm = (WindowManager)getSystemService(WINDOW_SERVICE);
// 屏幕高、宽
h = wm.getDefaultDisplay().getHeight();
w = wm.getDefaultDisplay().getWidth();
holder = sf.getHolder();
// 设置回调函数
holder.addCallback(new Callback() {
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
BitmapFactory.Options opts = new Options();
Bitmap bitm = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.java, opts);
// 解析图片的头文件
opts.inJustDecodeBounds = true;
// 得到图片高、宽
float imageH = opts.outHeight;
float imageW = opts.outWidth;
System.out.println("图片的高"+imageH);
System.out.println("屏幕的高"+h);
/*// int scaleX = imageW/w+1;
// int scaleY = imageH/h+1;
int scale = 2;
if(scaleX > scaleY & scaleY >= 1){
scale = scaleX;
}
if(scaleY > scaleX & scaleX >= 1){
scale = scaleY;
}
opts.inJustDecodeBounds = false;
opts.inSampleSize = scale;
System.out.println(scale);*/
Canvas canvas = holder.lockCanvas();
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.java);
// canvas.drawBitmap(bitmap, 0, 0, null);
//
// 设置缩放比
Matrix matrix = new Matrix();
matrix.setScale(w/imageW, h/imageH);
canvas.drawBitmap(bitmap, matrix, null);
// 解锁
holder.unlockCanvasAndPost(canvas);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
}
}
思路也很简单,就是首先得到图片的宽高,然后得到屏幕的宽高,用屏幕的宽高/图片的宽高就可以得到图片的缩放比。再在surfaceView中显示缩放之后的图片即可。
得到屏幕的宽高比较常见,用WindowManager即可。
得到图片的宽高用到了BitmapFactory.Options opts = newOptions();
BitmapFactory.Options这个类,有一个字段叫做 inJustDecodeBounds 。SDK中对这个成员的说明是这样的:
If set to true, the decoder will return null (nobitmap), but the out…
也就是说,如果我们把它设为true,那么BitmapFactory.decodeFile(String path, Options opt)并不会真的返回一个Bitmap给你,它仅仅会把它的宽,高取回来给你,这样就不会占用太多的内存,也就不会那么频繁的发生OOM了。
float imageH = opts.outHeight;
float imageW =opts.outWidth;
这就是图片的高和宽
接下来得到图片的缩放比
// 设置缩放比
Matrix matrix = new Matrix();
matrix.setScale(w/imageW, h/imageH);
然后在SurfaceView中设置
<span style="white-space:pre"> </span>canvas.drawBitmap(bitmap, matrix, null);
这样图片就能在SurfaceView完整的显示了!
代码下载地址
// 设置缩放比
Matrix matrix = new Matrix();
matrix.setScale(w/imageW, h/imageH);
http://download.csdn.net/detail/renzaijianghu12354/8038399
// 设置缩放比
Matrix matrix = new Matrix();
matrix.setScale(w/imageW, h/imageH);