放大镜就是直接调用相机,使用放大缩小的功能实现,调用相机有两种方式,一种是直接调用系统的;另一种是自定义相机,需要自定义一个预览界面,下面简单介绍自定义相机方式:
参考:http://developer./guide/topics/media/camera.html
首先我们需要申请权限:
1、获取需要的权限,检测手机是否有相机。
//manifest里添加使用相机的权限
<uses-permission android:name="android.permission.CAMERA" />
//使用相机属性
<uses-feature android:name="android.hardware.camera" />
//相机自动对焦
<uses-feature android:name="android.hardware.camera.autofocus" />
然后再判断是否有相机存在:
/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
2.打开相机,官网实现的安全方式打开相机
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
3、创建预览窗口,这是最主要的部分
SurfaceView:该类是一个视图组件,实现了照片的预览功能。
SurfaceHolder:一个抽象接口,是SurfaceView的支持类,一般通过SurfaceView的getHolder()方法获得。允许你控制界面的尺寸和格式、编辑界面的像素,以及监控界面尺寸的改变。
SurfaceHolder.Callback:SurfaceHolder 的一个内部接口,可以实现该接口获取界面改变的信息。该接口中有三个方法,surfaceCreated()方法在界面创建时被调用,一般在该方法中打开 照相机并设置预览。surfaceChanged()方法在界面尺寸改变时 被调用,一般在该方法中设置相机的参数(大小、格式等)。 surfaceDestroyed()方法在界面被销毁时调用,在该方法中清除相机实例,释放资源。
Camera:相机类,实现拍照功能。
Camera.PictureCallback:Camera的一个内部接口,处理照片准备好后的回调。
接着我们定义预览窗口的自定义View
/** A basic Camera preview class */
public class MyPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public MyPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
//获取相机属性
Camera.Parameters parameters = mCamera.getParameters();
//自动对焦
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
//由于相机默认是横屏的,创建时旋转一下调正位置
if(this.getResources().getConfiguration().orientation!= Configuration.ORIENTATION_LANDSCAPE){
parameters.set("orientation", "portrait");
mCamera.setDisplayOrientation(90);
parameters.setRotation(90);
}else{
parameters.set("orientation", "landscape");
mCamera.setDisplayOrientation(0);
parameters.setRotation(0);
}
mCamera.setParameters(parameters);
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// make any resize, rotate or reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
e.printStackTrace();
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// return super.onTouchEvent(event);
//按下时自动对焦
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mCamera.autoFocus(null);
}
return true;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
4、添加seekbar调节预览区域的缩放。
由于在Nexus5上获取到的maxZoom是99,如果你的设备取不到这么大,那么需要将progress的刻度乘一个比例,以免报错。
/**
* maxZoom = parameters.getMaxZoom(); 最大缩放
* ratio = 100 / maxZoom;获取比例
*/
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
Camera c = mCamera;
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(progress / ratio < maxZoom)
parameters.setZoom(progress / ratio);
c.setParameters(parameters);
c.autoFocus(null);
}
下面是Demo的核心部分代码:
public class MainActivity extends Activity {
private Camera mCamera;
private CameraPreview mPreview;
private boolean isClicked = false;
private Camera.AutoFocusCallback mAutoFocusCallback;
private SeekBar seekBar;
private int maxZoom;
private int ratio = 1;
Camera.Parameters parameters;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
seekBar = (SeekBar)findViewById(R.id.seekBar);
mCamera = safeCameraOpen();
mAutoFocusCallback = new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
Camera c=mCamera;
// TODO Auto-generated method stub
if(success){
//自动对焦成功
c.setOneShotPreviewCallback(null);
}
};
if(mCamera != null) {
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.framelayout);
preview.addView(mPreview);
parameters = mCamera.getParameters();
maxZoom = parameters.getMaxZoom();
if(maxZoom > 0)
ratio = 100 / maxZoom;
// parameters.setZoom(99);
// mCamera.setParameters(parameters);
}
/**
* maxZoom = parameters.getMaxZoom(); 最大缩放
* ratio = 100 / maxZoom;获取比例
*/
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
Camera c = mCamera;
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(progress / ratio < maxZoom)
parameters.setZoom(progress / ratio);
c.setParameters(parameters);
c.autoFocus(null);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
@Override
protected void onPause() {
super.onPause();
if(mCamera != null){
mCamera.release();
}
}
@Override
protected void onResume(){
super.onResume();
mCamera = safeCameraOpen();
}
//camera
private Camera safeCameraOpen() {
Camera c = null;
try {
c = Camera.open();
} catch (Exception e) {
Log.e(getString(R.string.app_name), "failed to open Camera");
e.printStackTrace();
}
return c;
}
//自定义相机展览区
public class MyPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public MyPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
//获取相机属性
Camera.Parameters parameters = mCamera.getParameters();
//自动对焦
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
//由于相机默认是横屏的,创建时旋转一下调正位置
if(this.getResources().getConfiguration().orientation!= Configuration.ORIENTATION_LANDSCAPE){
parameters.set("orientation", "portrait");
mCamera.setDisplayOrientation(90);
parameters.setRotation(90);
}else{
parameters.set("orientation", "landscape");
mCamera.setDisplayOrientation(0);
parameters.setRotation(0);
}
mCamera.setParameters(parameters);
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// make any resize, rotate or reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
e.printStackTrace();
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// return super.onTouchEvent(event);
//按下时自动对焦
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mCamera.autoFocus(null);
}
return true;
}
}
/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
|