上次已经写过SurfaceView显示Camera摄像了,代码可以运行,但是里面有问题,这次纠正过来,顺便实现变焦:
代码:
public class CameravedioActivity extends Activity{
private static final String TAG = "CameravedioActivity";
private Camera camera;
private boolean preview = false ;
private SeekBar mSeekBar;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*
*设置窗口属性:一定要在 setContentView(R.layout.main) 之前
*/
// 窗口标题,其实可以在manifes文件里面注册
// requestWindowFeature(Window.FEATURE_NO_TITLE);
// 全屏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceView.getHolder().setFixedSize(200, 200);
surfaceView.getHolder().addCallback(new SurfaceViewCallback());
/**
* seekbar 用来实现变焦逻辑
*/
mSeekBar = (SeekBar)findViewById(R.id.seekbar);
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
Log.d(TAG, "progress:"+progress);
// sdk 文档描述 set zoom 之前先check
if(camera.getParameters().isZoomSupported()){
Parameters params = camera.getParameters();
params.setZoom(progress);
camera.setParameters(params);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
Log.d(TAG, "onStartTrackingTouch");
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
Log.d(TAG, "onStartTrackingTouch");
}
});
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
}
public static void setCameraDisplayOrientation(Activity activity,
int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay()
.getRotation();
int degrees = 0;
Log.d(TAG, "rotation:"+rotation);
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
private final class SurfaceViewCallback implements Callback {
/**
* surfaceView 被创建成功后调用此方法
*/
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG,"surfaceCreated");
/*
* 在SurfaceView创建好之后 打开摄像头
* 注意是 android.hardware.Camera
*/
// 2.2获取摄像头number physical cameras
// api 9: Camera.getNumberOfCameras()
Log.d(TAG, "numbers:"+Camera.getNumberOfCameras());
if(Camera.getNumberOfCameras() ==2){
// 前置摄像头
// api 9 :Camera.CameraInfo
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
camera.setDisplayOrientation(90);
}else{
camera = Camera.open();
}
// camera = Camera.open();
// setCameraDisplayOrientation(CameravedioActivity.this,Camera.CameraInfo.CAMERA_FACING_FRONT,camera);
Log.d(TAG, "smoothZoom:"+camera.getParameters().isSmoothZoomSupported());
Log.d(TAG, "supportzoom:"+camera.getParameters().isZoomSupported());
Log.d(TAG, "max zoom:"+camera.getParameters().getMaxZoom());
/*
* This method must be called before startPreview(). otherwise surfaceview没有图像
*/
try {
camera.setPreviewDisplay(surfaceHolder);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Camera.Parameters parameters = camera.getParameters();
/* 每秒从摄像头捕获5帧画面, */
parameters.setPreviewFrameRate(5);
/* 设置照片的输出格式:jpg */
parameters.setPictureFormat(PixelFormat.JPEG);
/* 照片质量 */
parameters.set("jpeg-quality", 85);
mSeekBar.setMax(parameters.getMaxZoom());
// valid parameters:
// 取得相机所支持多少图片大小的个数
List<Size> pszize = parameters.getSupportedPreviewSizes();
// List<Size> pszize = parameters.getSupportedPictureSizes();
if (null != pszize && 0 < pszize.size()) {
int height[] = new int[pszize.size()];// 声明一个数组
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < pszize.size(); i++) {
Size size = (Size) pszize.get(i);
int sizeheight = size.height;
int sizewidth = size.width;
height[i] = sizeheight;
map.put(sizeheight, sizewidth);
Log.d(TAG, "size.width:"+sizewidth+"\tsize.height:"+sizeheight);
}
Arrays.sort(height);
// 设置
// parameters.setPictureSize(map.get(height[0]),height[0]);
parameters.setPreviewSize(map.get(height[0]),height[0]);
}
/* 将参数对象赋予到 camera 对象上 */
camera.setParameters(parameters);
camera.startPreview();
/**
* Installs a callback to be invoked for every preview frame in addition to displaying them on the screen.
* The callback will be repeatedly called for as long as preview is active. This method can be called at
* any time, even while preview is live. Any other preview callbacks are overridden.
* a callback object that receives a copy of each preview frame, or null to stop receiving
*/
camera.setPreviewCallback(new Camera.PreviewCallback(){
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
// TODO Auto-generated method stub
//在视频聊天中,这里传送本地frame数据给remote端
// Log.d(TAG, "camera:"+camera);
// Log.d(TAG, "byte:"+data);
}
});
preview = true;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.d(TAG,"surfaceChanged");
}
/**
* SurfaceView 被销毁时释放掉 摄像头
*/
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if(camera != null) {
/* 若摄像头正在工作,先停止它 */
if(preview) {
camera.stopPreview();
preview = false;
}
//如果注册了此回调,在release之前调用,否则release之后还回调,crash
camera.setPreviewCallback(null);
camera.release();
}
}
}
}
注册文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.edu.wtu"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<!-- android:screenOrientation="landscape" 表示横向界面 -->
<activity android:name=".CameravedioActivity" android:label="@string/app_name" android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="7" />
<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 申请使用摄像头的权限 -->
<uses-permission android:name="android.permission.CAMERA"/>
</manifest>
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="200dip"
android:layout_height="150dip"
android:layout_gravity="center"
android:visibility="visible"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<SeekBar
android:id="@+id/seekbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="40dip"
android:layout_marginRight="40dip"
android:layout_gravity="center"
android:progressDrawable="@android:color/transparent"
android:background="@drawable/progressbar_box"
/>
</LinearLayout>
</LinearLayout>
</FrameLayout>
seekbar用来实现调焦的