android - tutorial - vista previa de cámara dentro de viewpager
viewpager android slider (0)
He creado un viewpager con un fragmento de adaptador de página y tengo dos fragmentos en él. En uno de mis fragmentos, estoy mostrando una vista previa de la cámara en vivo en un diseño de marco, pero el problema es que cada vez que paso de la primera página a la página de vista previa de la cámara, se retrasa. Así que obtengo barras negras entre el primer fragmento y el fragmento de vista previa de la cámara cuando estoy deslizando hacia la derecha, porque el diseño del marco con la cámara no sigue el deslizamiento correctamente. Pero esto solo sucede cuando estoy mostrando la vista previa en vivo de la cámara. Si tuviera que eliminar la vista previa y simplemente establecer el color de fondo en verde, no sería ningún retraso. Fragmento de cámara:
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;
}
}
}
Clase de vista previa de la cámara:
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;
}
}
Es un poco difícil de explicar, pero espero que entiendas lo que está sucediendo. ¡Gracias!