放大镜就是直接调用相机,使用放大缩小的功能实现,调用相机有两种方式,一种是直接调用系统的;另一种是自定义相机,需要自定义一个预览界面,下面简单介绍自定义相机方式:

参考:http://developer.android.com/guide/topics/media/camera.html

首先我们需要申请权限:

1、获取需要的权限,检测手机是否有相机。

//manifest里添加使用相机的权限

//使用相机属性

//相机自动对焦

1

2

3

4

5

6

71

2

3

4

5

6

7

然后再判断是否有相机存在:

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

101

2

3

4

5

6

7

8

9

10

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

}1

2

3

4

5

6

7

8

9

10

111

2

3

4

5

6

7

8

9

10

11

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

851

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

}1

2

3

4

5

6

7

8

9

10

11

12

131

2

3

4

5

6

7

8

9

10

11

12

13

下面是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

1881

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

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐