以编程方式确定android中的相机质量
我想用摄像头(前置摄像头)录制视频,但在不同的设备中,前置摄像头的录制质量是不同的,当我们想用摄像头录制一些视频时,我们必须为我们的MediaRecorder设置CamrecorderProfile,问题是,当我将CamcorderProfile.QUALITY_720P用作CamrecorderProfile时,有些设备的前置摄像头不支持720P分辨率。 如果我们使用QUALITY_LOW,我们可以在所有设备中录制,但在某些设备中,输出视频将如下所示:以编程方式确定android中的相机质量,android,camera,record,Android,Camera,Record,我想用摄像头(前置摄像头)录制视频,但在不同的设备中,前置摄像头的录制质量是不同的,当我们想用摄像头录制一些视频时,我们必须为我们的MediaRecorder设置CamrecorderProfile,问题是,当我将CamcorderProfile.QUALITY_720P用作CamrecorderProfile时,有些设备的前置摄像头不支持720P分辨率。 如果我们使用QUALITY_LOW,我们可以在所有设备中录制,但在某些设备中,输出视频将如下所示: 那么有没有办法找出摄像机的质量,因此,
那么有没有办法找出摄像机的质量,因此,我们可以使用适当的质量在每台设备中进行录制您可以使用
摄像头检查支持的分辨率。参数
api好的,我将为您提供一个快速启动代码。通过此代码,我可以获得安装了我的应用程序的任何手机的最佳参数,这样它在运行时不会拉伸或显示不平滑捕获。您最需要的代码是SurfaceChanged
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, acquire the camera and tell it where to draw.
try {
mCamera = Camera.open(); // WARNING: without permission in Manifest.xml, crashes
}
catch (RuntimeException exception) {
//Log.i(TAG, "Exception on Camera.open(): " + exception.toString());
Toast.makeText(getContext(), "Camera broken, quitting :(",Toast.LENGTH_LONG).show();
// TODO: exit program
}
try {
mCamera.setPreviewDisplay(holder);
updateBufferSize();
mCamera.addCallbackBuffer(mBuffer); // where we'll store the image data
mCamera.setPreviewCallbackWithBuffer(new PreviewCallback() {
public synchronized void onPreviewFrame(byte[] data, Camera c) {
if (mCamera != null) { // there was a race condition when onStop() was called..
mCamera.addCallbackBuffer(mBuffer); // it was consumed by the call, add it back
}
}
});
} catch (Exception exception) {
//Log.e(TAG, "Exception trying to set preview");
if (mCamera != null){
mCamera.release();
mCamera = null;
}
// TODO: add more exception handling logic here
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when we return, so stop the preview.
// Because the CameraDevice object is not a shared resource, it's very
// important to release it when the activity is paused.
//Log.i(TAG,"SurfaceDestroyed being called");
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
// FYI: not called for each frame of the camera preview
// gets called on my phone when keyboard is slid out
// requesting landscape orientation prevents this from being called as camera tilts
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
//Log.i(TAG, "Preview: surfaceChanged() - size now " + w + "x" + h);
// Now that the size is known, set up the camera parameters and begin
// the preview.
try {
mParameters = mCamera.getParameters();
int picH = mParameters.getPictureSize().height;
int picW = mParameters.getPictureSize().width;
int preH = mParameters.getPreviewSize().height;
int preW = mParameters.getPreviewSize().width;
float scale = ((float)(picH*preW)) / ((float)(picW*preH));
float bff = 0;
try {
List<Camera.Size> supportedSizes = null;
//maximize supported resizes, TODO remove as hardcode
w*=1.5;
h*=1.5;
// On older devices (<1.6) the following will fail
// the camera will work nevertheless
supportedSizes = mCamera.getParameters().getSupportedPreviewSizes();
// preview form factor
float ff = (float) w / h;
System.out.println("TAG" + "Screen res: w:" + w + " h:" + h + " aspect ratio:" + ff);
// holder for the best form factor and size
int bestw = 0;
int besth = 0;
Iterator<Camera.Size> itr = supportedSizes.iterator();
// we look for the best preview size, it has to be the closest
// to the
// screen form factor
while (itr.hasNext()) {
Camera.Size element = itr.next();
// current form factor
float cff = (float) element.width / element.height;
// check if the current element is a candidate to replace
// the best match so far
// current form factor should be closer to the bff
// preview width should be less than screen width
// preview width should be more than current bestw
// this combination will ensure that the highest resolution
// will win
Log.d("TAG", "Candidate camera element: w:"
+ element.width + " h:" + element.height
+ " aspect ratio:" + cff);
if ((ff - cff <= ff - bff) && (element.width <= w)
&& (element.width >= bestw)) {
bff = cff;
bestw = element.width;
besth = element.height;
}
}
System.out.println("TAG" + "Chosen camera element: w:" + bestw + " h:" + besth + " aspect ratio:" + bff);
// Some Samsung phones will end up with bestw and besth = 0
// because their minimum preview size is bigger then the screen
// size.
// In this case, we use the default values: 480x320
if ((bestw == 0) || (besth == 0)) {
Log.d("Mixare", "Using default camera parameters!");
bestw = 480;
besth = 320;
}
mParameters.setPreviewSize(bestw,besth);
} catch (Exception ex) {
mParameters.setPreviewSize(480,320);
bff=1.5f;
}
makeResizeForCameraAspect(bff);
for (Integer i : mParameters.getSupportedPreviewFormats()) {
//Log.i(TAG, "supported preview format: " + i);
}
List<Size> sizes = mParameters.getSupportedPreviewSizes();
for (Size size : sizes) {
Log.i(VIEW_LOG_TAG, "supported preview size: " + size.width + "x" + size.height);
}
mCamera.setParameters(mParameters); // apply the changes
} catch (Exception e) {
// older phone - doesn't support these calls
}
updateBufferSize(); // then use them to calculate
Size p = mCamera.getParameters().getPreviewSize();
//Log.i(TAG, "Preview: checking it was set: " + p.width + "x" + p.height); // DEBUG
mCamera.startPreview();
}
private void makeResizeForCameraAspect(float cameraAspectRatio) {
ViewGroup.LayoutParams layoutParams=this.getLayoutParams();
int matchParentWidth=this.getWidth();
int newHeight=(int)(matchParentWidth/cameraAspectRatio);
if(newHeight!=layoutParams.height){
layoutParams.height=newHeight;
layoutParams.width=matchParentWidth;
this.setLayoutParams(layoutParams);
this.invalidate();
}
}
public Parameters getCameraParameters(){
return mCamera.getParameters();
}
public void setCameraFocus(AutoFocusCallback autoFocus){
mCamera.getParameters();
mCamera.getParameters();
if (mCamera.getParameters().getFocusMode().equals(Parameters.FOCUS_MODE_AUTO) ||
mCamera.getParameters().getFocusMode().equals(Parameters.FOCUS_MODE_MACRO)){
mCamera.autoFocus(autoFocus);
}
}
public void surfaceCreated(SurfaceHolder持有者){
//曲面已创建,获取摄影机并告诉其绘制位置。
试一试{
mCamera=Camera.open();//警告:如果没有Manifest.xml中的权限,将崩溃
}
捕获(运行时异常){
//Log.i(标记“Camera.open()上的异常:”+Exception.toString());
Toast.makeText(getContext(),“相机坏了,退出:(”,Toast.LENGTH_LONG).show();
//TODO:退出程序
}
试一试{
mCamera.setPreviewDisplay(支架);
updateBufferSize();
mCamera.addCallbackBuffer(mBuffer);//我们将在哪里存储图像数据
setPreviewCallbackWithBuffer(新的PreviewCallback(){
公共同步void onPreviewFrame(字节[]数据,摄像头c){
如果(mCamera!=null){//调用onStop()时存在争用条件。。
mCamera.addCallbackBuffer(mBuffer);//它已被调用占用,请将其添加回
}
}
});
}捕获(异常){
//Log.e(标记“尝试设置预览的异常”);
if(mCamera!=null){
mCamera.release();
mCamera=null;
}
//TODO:在此处添加更多异常处理逻辑
}
}
公共空间表面覆盖(表面覆盖物持有人){
//当我们返回时,曲面将被破坏,因此请停止预览。
//因为CameraDevice对象不是共享资源,所以它非常有用
//当活动暂停时释放它很重要。
//Log.i(标记“被调用的表面置换”);
mCamera.stopPreview();
mCamera.release();
mCamera=null;
}
//仅供参考:不为相机预览的每一帧调用
//当键盘滑出时在我的手机上被呼叫
//请求横向定向可防止将其称为摄影机倾斜
公共无效表面更改(表面持有人,整数格式,整数w,整数h){
//Log.i(标记,“预览:surfaceChanged()-size now”+w+“x”+h);
//现在已经知道大小,请设置相机参数并开始
//预览。
试一试{
mParameters=mCamera.getParameters();
int picH=mpareters.getPictureSize().height;
int picW=mpareters.getPictureSize().width;
int preH=mpareters.getPreviewSize().height;
int preW=mpareters.getPreviewSize().width;
浮动刻度=((浮动)(picH*preW))/((浮动)(picW*preH));
浮动bff=0;
试一试{
列表支持的大小=空;
//最大化支持的大小调整,TODO作为硬代码删除
w*=1.5;
h*=1.5;
//在旧设备上(