이것은 Google 비전 API에 관한 것입니다. CameraPreview는 전체 화면에서 잘 작동합니다. 그러나 상자에서 카메라를 미리 볼 때 이미지가 왜곡됩니다.setPreviewSize 및 PictureSize와 같은 CameraSource 크기를 변경하는 방법
이것은 내가 사용한 코드입니다. 내 문제는 미리보기가 상자를 채우지 만 미리보기가 늘어나고 cameraPreview의 크기를 조정할 수 없다는 것입니다. 변수 CameraPreview는 SurfaceView 유형입니다. CameraSource를 사용하여 미리보기를 시작합니다. CameraPreview (SurfaceView)의 크기를 변경하고 미리보기 자르기를 상자에 맞게 만들 수있는 방법이 있습니까? 같은 문제가 '전체 화면' 카메라 미리보기 존재
cameraPreview.getHolder().addCallback(new SurfaceHolder.Callback() {
protected List<Camera.Size> mPreviewSizeList;
protected List<Camera.Size> mPictureSizeList;
protected Camera.Size mPreviewSize;
protected Camera.Size mPictureSize;
protected boolean mSurfaceChanged = false;
private int mSurfaceChangedCallDepth = 0;
private int mCenterPosX = -1;
private int mCenterPosY = 0;
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(ClientIdScannerActivity.this,
new String[]{Manifest.permission.CAMERA}, RequestCameraPermissionId);
Toast.makeText(ClientIdScannerActivity.this, "The App requires this permission", Toast.LENGTH_SHORT).show();
return;
}
try {
cameraSource.start(cameraPreview.getHolder());
} catch (Exception ex) {
ex.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
mSurfaceChangedCallDepth++;
/* cameraSource.stop();
Camera.Parameters cameraParams = mCamera.getParameters();
if (!mSurfaceChanged) {
Camera.Size previewSize = determinePreviewSize(cameraWidth, cameraHight);
Camera.Size pictureSize = determinePictureSize(previewSize);
mPreviewSize = previewSize;
mPictureSize = pictureSize;
mSurfaceChanged = adjustSurfaceLayoutSize(previewSize,i1, i2);
if (mSurfaceChanged && (mSurfaceChangedCallDepth <= 1)) {
return;
}
}
cameraParams.setRotation(270);
if (UtilFunctions.isTablet()) {
} else {
mCamera.setDisplayOrientation(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? 270 : 90);
}*/
// cameraParams.setRotation(270);
// mCamera.setDisplayOrientation(UtilFunctions.isTablet() ? 90 : 270);
/* cameraParams.set("orientation", "portrait");
// cameraParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
cameraParams.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
cameraParams.setPictureSize(mPictureSize.width, mPictureSize.height);
if (cameraParams.getSupportedFocusModes().contains(
Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
cameraParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}*/
mSurfaceChanged = false;
try {
if (ActivityCompat.checkSelfPermission(ClientIdScannerActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
Toast.makeText(ClientIdScannerActivity.this, "App requires Camera permission to scan ID", Toast.LENGTH_SHORT).show();
return;
}
cameraSource.start(cameraPreview.getHolder());
} catch (Exception e) {
// Remove failed size
// Reconfigure
if (mPreviewSizeList.size() > 0) { // prevent infinite loop
surfaceChanged(null, 0, i1, i2);
} else {
// Utils.showToast(CameraNewActivity.this, "Can't start preview", Toast.LENGTH_LONG);
}
}
mSurfaceChangedCallDepth--;
}
protected Camera.Size determinePreviewSize(int reqWidth, int reqHeight) {
int reqPreviewWidth = 640;//reqHeight; // requested width in terms of camera hardware
int reqPreviewHeight = 480;// reqWidth; // requested height in terms of camera hardware
Camera.Size retSize = null;
for (Camera.Size size : mPreviewSizeList) {
if (size.width == reqPreviewWidth && size.height == reqPreviewHeight) {
retSize = size;
}
}
// retSize = mPreviewSizeList.get(mPreviewSizeList.size()-1);
return retSize;
}
protected Camera.Size determinePictureSize(Camera.Size previewSize) {
Camera.Size retSize = null;
for (Camera.Size size : mPictureSizeList) {
if (size.equals(previewSize)) {
return size;
}
}
// if the preview size is not supported as a picture size
float reqRatio = ((float) previewSize.width)/previewSize.height;
float curRatio, deltaRatio;
float deltaRatioMin = Float.MAX_VALUE;
for (Camera.Size size : mPictureSizeList) {
curRatio = ((float) size.width)/size.height;
deltaRatio = Math.abs(reqRatio - curRatio);
if (deltaRatio < deltaRatioMin) {
deltaRatioMin = deltaRatio;
retSize = size;
}
}
return retSize;
}
protected boolean adjustSurfaceLayoutSize(Camera.Size previewSize,
int availableWidth, int availableHeight) {
float tmpLayoutHeight = previewSize.width;
float tmpLayoutWidth = previewSize.height;
float factH, factW, fact;
factH = availableHeight/tmpLayoutHeight;
factW = availableWidth/tmpLayoutWidth;
// if (factH < factW) {
// fact = factH;
// } else {
fact = factW;
// }
FrameLayout.LayoutParams layoutParams =(FrameLayout.LayoutParams) cameraPreview.getLayoutParams();
int layoutHeight = (int) (tmpLayoutHeight * fact);
int layoutWidth = (int) (tmpLayoutWidth * fact);
boolean layoutChanged;
if ((layoutWidth != cameraPreview.getWidth()) || (layoutHeight != cameraPreview.getHeight())) {
layoutParams.height = layoutHeight;
layoutParams.width = layoutWidth;
if (mCenterPosX >= 0) {
layoutParams.topMargin = mCenterPosY - (layoutHeight/2);
layoutParams.leftMargin = mCenterPosX - (layoutWidth/2);
}
cameraPreview.setLayoutParams(layoutParams); // this will trigger another surfaceChanged invocation.
layoutChanged = true;
} else {
layoutChanged = false;
}
return layoutChanged;
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
cameraSource.stop();
}
});
이 코드는 실행되지만 효과는 없습니다. 이전에는 Camera 변수를 사용했지만 더 이상 필요하지 않으므로 주석을 달았습니다. 내 이해가. –