viewpager中的相机预览

时间:2015-09-26 21:42:15

标签: android android-viewpager android-camera

我创建了一个带有片段页面适配器的viewpager,其中有两个片段。在我的一个片段中,我在帧布局中显示相机实时预览,但问题是,每当我从第一页滑动到相机预览页面时,它都会延迟。因此,当我向右滑动时,第一个片段和相机预览片段之间出现黑条,因为相机的帧布局不能正确滑动。但这只发生在我正在显示相机实时预览时。如果我要删除预览并将背景颜色设置为绿色,则不会有任何延迟。 相机碎片:

public class CameraFragment extends Fragment {

    private Context mContext;
    private Camera mCamera;
    private CameraPreview mCameraPreview;
    private FrameLayout frameLayout;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.camera_layout, container, false);
        mContext = getActivity();
        frameLayout = (FrameLayout) v.findViewById(R.id.camera_preview);
        new Thread() {
            public void run() {
                Looper.prepare();
                mCamera = getCameraInstance();
                mCameraPreview = new CameraPreview(mContext, mCamera, frameLayout);
                try {
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            frameLayout.addView(mCameraPreview);
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();
        return v;
    }

    private Camera getCameraInstance() {
        Camera camera = null;
        try {
            camera = getFrontFacingCamera();
        } catch (Exception e) {
            // cannot get camera or does not exist
        }
        return camera;
    }

    private Camera getFrontFacingCamera() {
        int cameraCount = 0;
        Camera cam = null;
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        cameraCount = Camera.getNumberOfCameras();
        for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
            Camera.getCameraInfo(camIdx, cameraInfo);
            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                try {
                    cam = Camera.open(camIdx);
                } catch (RuntimeException e) {
                    Log.e("CameraFragment", "Camera failed to open: " + e.getLocalizedMessage());
                }
            }
        }
        return cam;
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        releaseCamera();
    }

    private void releaseCamera() {
        if (mCamera != null) {
            mCamera.release();
            mCamera = null;
        }
    }
}

相机预览课程:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private Camera mCamera;
    private String TAG = CameraPreview.class.getSimpleName();
    private Context mContext;
    private FrameLayout frameLayout;
    private List<Camera.Size> mSupportedPreviewSizes;
    private Camera.Size mPreviewSize;
    boolean done = false;

    public CameraPreview(Context context, Camera camera, FrameLayout frameLayout) {
        super(context);
        mContext = context;
        mCamera = camera;
        mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
        for (Camera.Size str : mSupportedPreviewSizes)
            Log.e(TAG, str.width + "/" + str.height);
        this.frameLayout = frameLayout;
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        if (mHolder.getSurface() == null) {
            return;
        }
        try {
            mCamera.stopPreview();
        } catch (Exception e) {
            // ignore: tried to stop a non-existent preview
        }
        try {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setPreviewSize(mPreviewSize.height, mPreviewSize.width);
            mCamera.setParameters(parameters);
            mCamera.setDisplayOrientation(90);
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();
        } catch (Exception e) {
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);

        if (mSupportedPreviewSizes != null) {
            mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height, true);
            if (mPreviewSize == null) {
                mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height, false);
            }
        }

        float ratio = (float) mPreviewSize.height / (float) mPreviewSize.width;
        if ((int) (width * ratio) >= height) {
            setMeasuredDimension(width, (int) (width * ratio));
        } else {
            setMeasuredDimension(width, height);
        }
        done = true;
    }

    private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h, boolean minSize) {
        if (sizes == null) {
            return null;
        }
        Camera.Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;
        double frameRatio = (double) h / w;
        double testRatio;
        int width, height;
        for (Camera.Size size : sizes) {
            width = size.height;
            height = size.width;
            if (width > height) {
                int t_width = width;
                width = height;
                height = t_width;
            }
            if (height < h / 2 && minSize) continue;
            testRatio = (double) height / width;
            if (Math.abs(frameRatio - testRatio) < minDiff) {
                if (optimalSize == null) optimalSize = sizes.get(0);
                // else if (frameRatio - testRatio <= 0 && optimalSize.height > height) continue;
                optimalSize.width = width;
                optimalSize.height = height;
                minDiff = Math.abs(frameRatio - testRatio);
                Log.d("", "" + frameRatio + ", " + testRatio);
            } else if (Math.abs(frameRatio - testRatio) == minDiff) {
                if (optimalSize.height > height) continue;
                if (optimalSize == null) optimalSize = sizes.get(0);
                optimalSize.width = width;
                optimalSize.height = height;
                minDiff = Math.abs(frameRatio - testRatio);
                Log.d("", "" + frameRatio + ", " + testRatio);
            }
        }
        Log.d("", "" + optimalSize.width + ", " + optimalSize.height);
        return optimalSize;
    }
}

这有点难以解释,但我希望你了解发生了什么。谢谢!

0 个答案:

没有答案