我已经写了相机应用(活动),需要一个图片,而是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