安卓相机preVIEW并不好看 [英] Android: Camera preview doesn't look nice
本文介绍了安卓相机preVIEW并不好看的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我已经写了相机应用(活动),需要一个图片,而是preVIEW显示摄像机的实时画面看起来并不好看,这是一个有点高,像这样:
下面是code为我的相机preVIEW:
公共类相机preVIEW延伸SurfaceView实现SurfaceHolder.Callback
{
私人SurfaceHolder mHolder;
私人相机mCamera;
公共摄像头preVIEW(上下文的背景下,相机摄像头)
{
超级(上下文);
mCamera =摄像头; mHolder = getHolder();
mHolder.addCallback(本);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
公共无效surfaceCreated(SurfaceHolder持有人)
{
尝试
{
mCamera.set previewDisplay(支架);
mCamera.start preVIEW();
}
赶上(IOException异常E)
{
Log.d(TAG相机preVIEW失败!:+ e.getMessage());
}
}
公共无效surfaceChanged(SurfaceHolder架,INT男,INT N,INT W)
{
}
公共无效surfaceDestroyed(SurfaceHolder持有人)
{
}
}< XML版本=1.0编码=UTF-8&GT?;
< LinearLayout中的xmlns:机器人=http://schemas.android.com/apk/res/android
机器人:layout_width =FILL_PARENT
机器人:layout_height =FILL_PARENT
机器人:方向=垂直> <的FrameLayout
机器人:ID =@ + ID / camera_ preVIEW
机器人:layout_width =WRAP_CONTENT
机器人:layout_height =0dip
机器人:layout_weight =0.86/> <按钮
机器人:ID =@ + ID / button_capture
机器人:layout_width =WRAP_CONTENT
机器人:layout_height =WRAP_CONTENT
机器人:layout_marginBottom =16DP
机器人:比重=中心
安卓的onClick =捕获
机器人:文字=拍照/> <按钮
机器人:ID =@ + ID / button_accept
机器人:layout_width =115dp
机器人:layout_height =WRAP_CONTENT
机器人:文字=接受
机器人:知名度=水涨船高
安卓的onClick =接受/> <按钮
机器人:ID =@ + ID / button_retake
机器人:layout_width =107dp
机器人:layout_height =WRAP_CONTENT
机器人:文字=重考
机器人:知名度=水涨船高
安卓的onClick =夺回/>< / LinearLayout中>
解决方案
公共类IQCameraView扩展的ViewGroup实现SurfaceHolder.Callback {公共静态最终诠释CAMERA_ERROR = 0;
公共静态最终诠释CAMERA_RESULT = 1;私人最终字符串标记=preVIEW
私人SurfaceView mSurfaceView;
私人SurfaceHolder mHolder;
私人尺寸M previewSize;
私人列表<尺寸和GT; mSupported previewSizes;
私人相机mCamera;私人布尔mCameraActive;私人IQCameraCallback mCallback;/ **
* @参数mCallback
类型IQCameraCallback的*
*为mCallback型空setter函数的@return
* @since 2012年10月10日
* /
公共无效setmCallback(IQCameraCallback mCallback){
this.mCallback = mCallback;
}/ **
* @参数方面
类型上下文的*
*类型布尔函数的@return将检查系统有一个摄像头
* 或不
* @since 2012年10月10日
* /
公共静态布尔checkCameraHardware(上下文的背景下){
如果(context.getPackageManager()。hasSystemFeature(
PackageManager.FEATURE_CAMERA)){
返回true;
}其他{
返回false;
}
}/ **
* @参数方面
*构造函数
* @since 2012年10月16日
* /
公共IQCameraView(上下文的背景下){
超级(上下文); mSurfaceView =新SurfaceView(背景);
addView(mSurfaceView);
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(本);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}/ **
* @参数摄像头
类型的相机*
*为mCamera型空setter函数的@return
* @since 2012年10月16日
* /
公共无效setCamera(相机摄像机){
mCamera =摄像头;
如果(mCamera!= NULL){
mSupported previewSizes = mCamera.getParameters()
.getSupported previewSizes();
requestLayout();
}
}/ **
* @参数
*类型为null
*型空函数@返回其将从得到当前帧
*摄像头
* @since 2012年10月16日
* /
公共无效takePicture(){
如果(空= mCamera和放大器;!&安培; mCameraActive){
mCamera.takePicture(NULL,NULL,新IQPhotoHandler(的getContext()
本));
}
}/ **
* @参数结果
String类型*
*型空函数@返回时,将图像保存为将被称为
*完整
* @since 2012年10月16日
* /
公共无效onImageCapture(最后弦乐结果){
如果(NULL!= mCallback){
mCallback.onCameraCallback(CAMERA_RESULT,结果);
}
mCamera.start preVIEW();
}/ *
*(非Javadoc中)
*
* @see android.view.View#onMeasure(INT,INT)
*
* @since 2012年10月16日
* /
@覆盖
保护无效onMeasure(INT widthMeasureSpec,诠释heightMeasureSpec){
//我们故意忽略孩子的测量,因为充当
//包装到中心相机preVIEW而不是SurfaceView
//拉伸。
最终诠释宽度= resolveSize(getSuggestedMinimumWidth()
widthMeasureSpec);
最终诠释身高= resolveSize(getSuggestedMinimumHeight()
heightMeasureSpec);
setMeasuredDimension(宽度,高度); 如果(mSupported previewSizes!= NULL){
米previewSize = GET previewSize(mSupported previewSizes,宽,高);
}
}/ *
*(非Javadoc中)
*
* @see android.view.ViewGroup#onLayout(布尔,INT,INT,INT,INT)
*
* @since 2012年10月16日
* /
@覆盖
保护无效onLayout(布尔变化,诠释L,INT T,INT R,INT B){
如果(变更&放大器;&放大器; getChildCount()大于0){
最后查看孩子= getChildAt(0); 最终诠释宽度= R - 1;
最终诠释身高= B - 吨; INT previewWidth =宽度;
INT previewHeight =高度; //中心父项子SurfaceView。
如果(宽* previewHeight>高* previewWidth){
最终诠释scaledChildWidth = previewWidth *高
/ previewHeight;
child.layout((宽 - scaledChildWidth)/ 2,0,
(宽+ scaledChildWidth)/ 2,高度);
}其他{
最终诠释scaledChildHeight = previewHeight *宽
/ previewWidth;
child.layout(0,(高度 - scaledChildHeight)/ 2,宽度,
(高度+ scaledChildHeight)/ 2);
}
}
}/ **
* @参数
*类型为null
*类型为null功能@return这将释放德相机
* @since 2012年10月16日
* /
公共无效releaseCamera(){
如果(空= mCamera和放大器;!&安培; mCameraActive){
mCamera.stop preVIEW();
mCamera.release();
mCamera = NULL;
}
mCameraActive = FALSE;
}/ *
*(非Javadoc中)
*
* @see
* android.view.SurfaceHolder.Callback#surfaceCreated(android.view.SurfaceHolder
*)
*
* @since 2012年10月16日
* /
公共无效surfaceCreated(SurfaceHolder持有人){
尝试{
如果(mCamera!= NULL){
mCamera.set previewDisplay(支架);
}
}赶上(IOException异常五){
Log.e(TAG,IOException异常造成集previewDisplay(),E);
}
}/ *
*(非Javadoc中)
*
* @see android.view.SurfaceHolder.Callback#surfaceDestroyed(android.view。
* SurfaceHolder)
*
* @since 2012年10月16日
* /
公共无效surfaceDestroyed(SurfaceHolder持有人){
releaseCamera();
}/ *
*(非Javadoc中)
*
* @see
* android.view.SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder
*,INT,INT,INT)
*
* @since 2012年10月16日
* /
公共无效surfaceChanged(SurfaceHolder架,INT格式,诠释W,INT高){
Camera.Parameters参数= mCamera.getParameters();
parameters.set previewSize(M previewSize.width,男previewSize.height);
parameters.setPictureSize(M previewSize.width,男previewSize.height);
parameters.setPictureFormat(PixelFormat.JPEG);
mCamera.setDisplayOrientation(90);
requestLayout();
尝试{
mCamera.setParameters(参数);
}赶上(例外五){
System.out.print(HIH);
}
mCamera.start preVIEW();
mCameraActive =真;
}/ **
* @参数规格
类型列表*
* @参数W¯¯
类型为int *
* @参数^ h
类型为int *
* @返回类型大小功能optionalSize将找到确切大小
*需要德摄像机视图
* @since 2012年10月16日
* /
私人尺寸的get previewSize(列表<尺寸和GT;的大小,INT W,INT高){
最终双ASPECT_TOLERANCE = 0.1;
双targetRatio =(双)W / H;
如果(大小== NULL)
返回null;
大小optimalSize = NULL;
双minDiff = Double.MAX_VALUE;
INT targetHeight = H;
对于(尺寸大小:大小){
双率=(双)size.width / size.height;
如果(Math.abs(比 - targetRatio)GT; ASPECT_TOLERANCE)
继续;
如果(Math.abs(size.height - targetHeight)LT; minDiff){
optimalSize =大小;
minDiff = Math.abs(size.height - targetHeight);
}
} //找不到一个长宽比匹配,忽略此要求
如果(optimalSize == NULL){
minDiff = Double.MAX_VALUE;
对于(尺寸大小:大小){
如果(Math.abs(size.height - targetHeight)LT; minDiff){
optimalSize =大小;
minDiff = Math.abs(size.height - targetHeight);
}
}
} 返回optimalSize;
}/ **
* @author rajeshcp
* @since 2012年10月16日
* /
公共静态界面IQCameraCallback {
公共无效onCameraCallback(最终int型的,最终目标参数);
}
}
试试这个code已用于项目,希望这将有助于
I've written a camera app (activity) that takes a picture, but the preview that shows the live picture of camera doesn't look nice, it's a bit tall, like this :
Here is the code for my camera preview :
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback
{
private SurfaceHolder mHolder ;
private Camera mCamera;
public CameraPreview(Context context , Camera camera)
{
super(context) ;
mCamera = camera ;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder)
{
try
{
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
catch(IOException e)
{
Log.d(TAG,"Camera Preview Failed!: "+e.getMessage());
}
}
public void surfaceChanged(SurfaceHolder holder , int m , int n , int w)
{
}
public void surfaceDestroyed(SurfaceHolder holder)
{
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<FrameLayout
android:id="@+id/camera_preview"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="0.86" />
<Button
android:id="@+id/button_capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:gravity="center"
android:onClick="capture"
android:text="Capture" />
<Button
android:id="@+id/button_accept"
android:layout_width="115dp"
android:layout_height="wrap_content"
android:text="Accept"
android:visibility="gone"
android:onClick = "accept" />
<Button
android:id="@+id/button_retake"
android:layout_width="107dp"
android:layout_height="wrap_content"
android:text="Retake"
android:visibility="gone"
android:onClick = "retake"/>
</LinearLayout>
解决方案
public class IQCameraView extends ViewGroup implements SurfaceHolder.Callback {
public static final int CAMERA_ERROR = 0;
public static final int CAMERA_RESULT = 1;
private final String TAG = "Preview";
private SurfaceView mSurfaceView;
private SurfaceHolder mHolder;
private Size mPreviewSize;
private List<Size> mSupportedPreviewSizes;
private Camera mCamera;
private boolean mCameraActive;
private IQCameraCallback mCallback;
/**
* @param mCallback
* of type IQCameraCallback
* @return of type null setter function for mCallback
* @since 10 Oct 2012
*/
public void setmCallback(IQCameraCallback mCallback) {
this.mCallback = mCallback;
}
/**
* @param context
* of type Context
* @return of type boolean function which will check the system has a camera
* or not
* @since 10 Oct 2012
*/
public static boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
return true;
} else {
return false;
}
}
/**
* @param context
* Constructor function
* @since 16 Oct 2012
*/
public IQCameraView(Context context) {
super(context);
mSurfaceView = new SurfaceView(context);
addView(mSurfaceView);
mHolder = mSurfaceView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
/**
* @param camera
* of type Camera
* @return of type null setter function for mCamera
* @since 16 Oct 2012
*/
public void setCamera(Camera camera) {
mCamera = camera;
if (mCamera != null) {
mSupportedPreviewSizes = mCamera.getParameters()
.getSupportedPreviewSizes();
requestLayout();
}
}
/**
* @param of
* type null
* @return of type null function which will get the current frame from the
* camera
* @since 16 Oct 2012
*/
public void takePicture() {
if (null != mCamera && mCameraActive) {
mCamera.takePicture(null, null, new IQPhotoHandler(getContext(),
this));
}
}
/**
* @param result
* of type String
* @return of type null function which will be called when the image save is
* complete
* @since 16 Oct 2012
*/
public void onImageCapture(final String result) {
if (null != mCallback) {
mCallback.onCameraCallback(CAMERA_RESULT, result);
}
mCamera.startPreview();
}
/*
* (non-Javadoc)
*
* @see android.view.View#onMeasure(int, int)
*
* @since 16 Oct 2012
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// We purposely disregard child measurements because act as a
// Wrapper to a SurfaceView that centers the camera preview instead of
// stretching it.
final int width = resolveSize(getSuggestedMinimumWidth(),
widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(),
heightMeasureSpec);
setMeasuredDimension(width, height);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getPreviewSize(mSupportedPreviewSizes, width, height);
}
}
/*
* (non-Javadoc)
*
* @see android.view.ViewGroup#onLayout(boolean, int, int, int, int)
*
* @since 16 Oct 2012
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed && getChildCount() > 0) {
final View child = getChildAt(0);
final int width = r - l;
final int height = b - t;
int previewWidth = width;
int previewHeight = height;
// Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth) {
final int scaledChildWidth = previewWidth * height
/ previewHeight;
child.layout((width - scaledChildWidth) / 2, 0,
(width + scaledChildWidth) / 2, height);
} else {
final int scaledChildHeight = previewHeight * width
/ previewWidth;
child.layout(0, (height - scaledChildHeight) / 2, width,
(height + scaledChildHeight) / 2);
}
}
}
/**
* @param of
* type null
* @return of type null function which will release teh camera
* @since 16 Oct 2012
*/
public void releaseCamera() {
if (null != mCamera && mCameraActive) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
mCameraActive = false;
}
/*
* (non-Javadoc)
*
* @see
* android.view.SurfaceHolder.Callback#surfaceCreated(android.view.SurfaceHolder
* )
*
* @since 16 Oct 2012
*/
public void surfaceCreated(SurfaceHolder holder) {
try {
if (mCamera != null) {
mCamera.setPreviewDisplay(holder);
}
} catch (IOException e) {
Log.e(TAG, "IOException caused by setPreviewDisplay()", e);
}
}
/*
* (non-Javadoc)
*
* @see android.view.SurfaceHolder.Callback#surfaceDestroyed(android.view.
* SurfaceHolder)
*
* @since 16 Oct 2012
*/
public void surfaceDestroyed(SurfaceHolder holder) {
releaseCamera();
}
/*
* (non-Javadoc)
*
* @see
* android.view.SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder
* , int, int, int)
*
* @since 16 Oct 2012
*/
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
parameters.setPictureSize(mPreviewSize.width, mPreviewSize.height);
parameters.setPictureFormat(PixelFormat.JPEG);
mCamera.setDisplayOrientation(90);
requestLayout();
try {
mCamera.setParameters(parameters);
} catch (Exception e) {
System.out.print("hih");
}
mCamera.startPreview();
mCameraActive = true;
}
/**
* @param sizes
* of type List
* @param w
* of type int
* @param h
* of type int
* @return optionalSize of type Size function which will find the exact size
* required for teh camera view
* @since 16 Oct 2012
*/
private Size getPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
if (sizes == null)
return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
/**
* @author rajeshcp
* @since 16 Oct 2012
*/
public static interface IQCameraCallback {
public void onCameraCallback(final int type, final Object param);
}
}
Try this code have used for a project, hope this will help
这篇关于安卓相机preVIEW并不好看的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文