版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】怎么在Android中通过自定义Camera实现拍照功能
这篇文章给大家介绍怎么在Android中通过自定义Camera实现拍照功能,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Camera类在5.0以后不推荐使用了,取而代之的是android.hardware.camera2包下的类,本文使用Camera。
我们首先自定义一个View去继承SurfaceView:public
class
CameraSurfaceView
extends
SurfaceView
implements
SurfaceHolder.Callback,
Camera.AutoFocusCallback
{
private
SurfaceHolder
mHolder;
private
Camera
mCamera;
private
static
final
int
ORIENTATION
=
90;
private
int
mScreenWidth;
private
int
mScreenHeight;
private
boolean
isOpen;
public
CameraSurfaceView(Context
context,
AttributeSet
attrs)
{
super(context,
attrs);
getScreenMatrix(context);
mHolder
=
getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
private
void
getScreenMatrix(Context
context)
{
WindowManager
WM
=
(WindowManager)
context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics
outMetrics
=
new
DisplayMetrics();
WM.getDefaultDisplay().getMetrics(outMetrics);
mScreenWidth
=
outMetrics.widthPixels;
mScreenHeight
=
outMetrics.heightPixels;
}
public
void
takePicture(Camera.ShutterCallback
mShutterCallback,
Camera.PictureCallback
rawPictureCallback,
Camera.PictureCallback
jpegPictureCallback)
{
if
(mCamera
!=
null)
mCamera.takePicture(mShutterCallback,
rawPictureCallback,
jpegPictureCallback);
}
public
void
startPreview()
{
mCamera.startPreview();
}
@Override
public
void
surfaceCreated(SurfaceHolder
holder)
{
if
(!checkCameraHardware(getContext()))
return;
if
(mCamera
==
null)
{
isOpen
=
safeCameraOpen(Camera.CameraInfo.CAMERA_FACING_BACK);
}
if
(!isOpen)
{
return;
}
mCamera.setDisplayOrientation(ORIENTATION);
try
{
mCamera.setPreviewDisplay(holder);
}
catch
(IOException
e)
{
e.printStackTrace();
}
}
@Override
public
void
surfaceChanged(SurfaceHolder
holder,
int
format,
int
width,
int
height)
{
if
(mCamera
!=
null)
{
setCameraParams(mScreenWidth,
mScreenHeight);
mCamera.startPreview();
}
}
@Override
public
void
surfaceDestroyed(SurfaceHolder
holder)
{
releaseCameraAndPreview();
}
private
boolean
safeCameraOpen(int
id)
{
boolean
qOpened
=
false;
try
{
releaseCameraAndPreview();
mCamera
=
Camera.open(id);
qOpened
=
(mCamera
!=
null);
}
catch
(Exception
e)
{
e.printStackTrace();
}
return
qOpened;
}
private
void
releaseCameraAndPreview()
{
if
(mCamera
!=
null)
{
mCamera.stopPreview();
mCamera.release();
mCamera
=
null;
}
}
private
boolean
checkCameraHardware(Context
context)
{
if
(context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA))
{
return
true;
}
else
{
return
false;
}
}
@Override
public
void
onAutoFocus(boolean
success,
Camera
camera)
{
}
private
void
setCameraParams(int
width,
int
height)
{
Camera.Parameters
parameters
=
mCamera.getParameters();
//
获取摄像头支持的PictureSize列表
List<Camera.Size>
pictureSizeList
=
parameters.getSupportedPictureSizes();
/**从列表中选取合适的分辨率*/
Camera.Size
picSize
=
getProperSize(pictureSizeList,
((float)
height
/
width));
if
(null
==
picSize)
{
picSize
=
parameters.getPictureSize();
}
//
根据选出的PictureSize重新设置SurfaceView大小
float
w
=
picSize.width;
float
h
=
picSize.height;
parameters.setPictureSize(picSize.width,
picSize.height);
this.setLayoutParams(new
RelativeLayout.LayoutParams((int)
(height
*
(h
/
w)),
height));
//
获取摄像头支持的PreviewSize列表
List<Camera.Size>
previewSizeList
=
parameters.getSupportedPreviewSizes();
Camera.Size
preSize
=
getProperSize(previewSizeList,
((float)
height)
/
width);
if
(null
!=
preSize)
{
parameters.setPreviewSize(preSize.width,
preSize.height);
}
parameters.setJpegQuality(100);
//
设置照片质量
if
(parameters.getSupportedFocusModes().contains(android.hardware.Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
{
parameters.setFocusMode(android.hardware.Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);//
连续对焦模式
}
mCamera.setDisplayOrientation(90);//
设置PreviewDisplay的方向,效果就是将捕获的画面旋转多少度显示
mCamera.setParameters(parameters);
}
/**
*
选取合适的分辨率
*/
private
Camera.Size
getProperSize(List<Camera.Size>
pictureSizeList,
float
screenRatio)
{
Camera.Size
result
=
null;
for
(Camera.Size
size
:
pictureSizeList)
{
float
currentRatio
=
((float)
size.width)
/
size.height;
if
(currentRatio
-
screenRatio
==
0)
{
result
=
size;
break;
}
}
if
(null
==
result)
{
for
(Camera.Size
size
:
pictureSizeList)
{
float
curRatio
=
((float)
size.width)
/
size.height;
if
(curRatio
==
4f
/
3)
{//
默认w:h
=
4:3
result
=
size;
break;
}
}
}
return
result;
}
}代码没什么难度,在View创建的时候完成Camera的初始化,然后对Camera进行参数的设置(图片尺寸,质量之类的),最后别忘了在View销毁的时候对资源进行释放。控件定义完了之后我们就要去使用它,在布局文件中添加就OK:<?xml
version="1.0"
encoding="utf-8"?>
<RelativeLayout
xmlns:android="/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.padoon.cameratest.CameraSurfaceView
android:id="@+id/sv_camera"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="4"/>
<ImageView
android:id="@+id/img_take_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_gravity="bottom"
android:layout_marginBottom="10dp"
android:layout_marginRight="10dp"
android:src="@mipmap/icon_camera"/>
</RelativeLayout>然后在Activity中去完成拍照功能:public
class
CameraActivity
extends
AppCompatActivity
{
private
boolean
isClick
=
true;
private
static
final
String
PATH_IMAGES
=
Environment.getExternalStorageDirectory().getAbsolutePath()
+
File.separator
+
"easy_check";
private
CameraSurfaceView
mCameraSurfaceView;
//拍照快门的回调
private
Camera.ShutterCallback
mShutterCallback
=
new
Camera.ShutterCallback()
{
@Override
public
void
onShutter()
{
}
};
//拍照完成之后返回原始数据的回调
private
Camera.PictureCallback
rawPictureCallback
=
new
Camera.PictureCallback()
{
@Override
public
void
onPictureTaken(byte[]
data,
Camera
camera)
{
}
};
//拍照完成之后返回压缩数据的回调
private
Camera.PictureCallback
jpegPictureCallback
=
new
Camera.PictureCallback()
{
@Override
public
void
onPictureTaken(byte[]
data,
Camera
camera)
{
mCameraSurfaceView.startPreview();
saveFile(data);
Toast.makeText(CameraActivity.this,
"拍照成功",
Toast.LENGTH_SHORT).show();
isClick
=
true;
}
};
@Override
protected
void
onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView
img_take_photo
=
(ImageView)
findViewById(R.id.img_take_photo);
mCameraSurfaceView
=
(CameraSurfaceView)
findViewById(R.id.sv_camera);
img_take_photo.setOnClickListener(new
View.OnClickListener()
{
@Override
public
void
onClick(View
v)
{
takePhoto();
}
});
}
public
void
takePhoto()
{
if
(isClick)
{
isClick
=
false;
mCameraSurfaceView.takePicture(mShutterCallback,
rawPictureCallback,
jpegPictureCallback);
}
}
//保存图片到硬盘
public
void
saveFile(byte[]
data)
{
String
fileName
=
UUID.randomUUID().toString()
+
".jpg";
FileOutputStream
outputStream
=
null;
tr
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- GB 44019-2024化学品船清洗舱安全作业要求
- 【模板】材料采购合同模板七篇
- 海南文化概论(海南联盟)-知到答案、智慧树答案
- 2023年自动输送设备资金筹措计划书
- 2023年气雾剂机械资金申请报告
- 2023年一级造价师考试《技术与计量(安装)》真题及答案
- 公司员工薪酬福利发放制度总结
- 消防工作防范总结
- 企业战略规划总结
- 医院工作总结:温和而专业的患者交流
- 医疗质量奖惩条例
- 《组织行为学》美斯蒂芬·P·罗宾斯著版课件
- Unit5重点单词讲解课件-高中英语人教版(2019)选择性必修第三册
- 食品添加剂E编码中英文对照表
- 四年级上册美术教案-18给小伙伴拍张照 |人美版
- 湖 泊 【思维导图+重难点突破】 高考地理 考点全覆盖式精讲 高效复习备考课件
- 编辑查询房产信息授权委托书(500字)
- 软件开发项目维保及售后服务方案
- 国家开放大学《金融风险概论》练习题参考答案
- 医院岗位风险分级、监管制度
- 神经内科年度发展重点规划
评论
0/150
提交评论