Я пытаюсь реализовать собственную камеру, используя класс Camera и SurfaceView.Но изображение, снятое камерой, поворачивается.Предварительный просмотр в SurfaceView также вращался, но в коде я исправил его с помощью метода setCameraDisplayOrientation () . Ниже приведены изображения, которые генерируются на экране, и я делал снимки экрана.
SurfaceView: ImageView:
И код, который я использую:
public class CustomCameraActivity extends AppCompatActivity implements PictureCallback, SurfaceHolder.Callback
{
private Camera mCamera;
private ImageView mCameraImage;
private SurfaceView mCameraPreview;
private Button mCaptureImageButton;
private byte[] mCameraData;
private boolean mIsCapturing;
private OnClickListener mCaptureImageButtonClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
App.getInstance().setCapturedPhotoData(null);
captureImage();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_camera);
mImgViewCover = (ImageView) findViewById(R.id.imgVw_customCameraCover);
mCameraImage = (ImageView) findViewById(R.id.camera_image_view);
mCameraImage.setVisibility(View.INVISIBLE);
mCameraPreview = (SurfaceView) findViewById(R.id.preview_view);
final SurfaceHolder surfaceHolder = mCameraPreview.getHolder();
surfaceHolder.addCallback(this);
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mCaptureImageButton = (Button) findViewById(R.id.capture_image_button);
mCaptureImageButton.setOnClickListener(mCaptureImageButtonClickListener);
mIsCapturing = true;
}
@Override
protected void onResume() {
super.onResume();
if (mCamera == null) {
try {
mCamera = Camera.open();
mCamera.setPreviewDisplay(mCameraPreview.getHolder());
if (mIsCapturing) {
mCamera.startPreview();
}
} catch (Exception e) {
Toast.makeText(CustomCameraActivity.this, "Unable to open camera.", Toast.LENGTH_LONG)
.show();
}
}
}
@Override
protected void onPause() {
super.onPause();
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
@Override
public void onPictureTaken(byte[] data, Camera camera) {
mCameraData = data;
setupImageDisplay();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (holder.getSurface() == null)
return;
try { mCamera.stopPreview();
} catch (Exception e) { }
if (mCamera != null) {
try {
Camera.Parameters parameters = mCamera.getParameters();
List<Size> sizes = parameters.getSupportedPreviewSizes();
Size optimalSize = getOptimalPreviewSize(sizes, width, height);
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
mCamera.setParameters(parameters);
setCameraDisplayOrientation(this, Camera.CameraInfo.CAMERA_FACING_BACK, mCamera );
if (mIsCapturing) {
mCamera.startPreview();
}
} catch (Exception e) {
Toast.makeText(CustomCameraActivity.this, "Unable to start camera preview.", Toast.LENGTH_LONG).show();
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder)
{
try {
mCamera = Camera.open();
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCamera != null)
{ mCamera.stopPreview();
mCamera.release();
mCamera = null;}
}
private void captureImage() {
mCamera.takePicture(null, null, this);
}
private void setupImageCapture() {
mCameraImage.setVisibility(View.INVISIBLE);
mCameraPreview.setVisibility(View.VISIBLE);
mCamera.startPreview();
mCaptureImageButton.setText("capture image");
mCaptureImageButton.setOnClickListener(mCaptureImageButtonClickListener);
}
private void setupImageDisplay() {
Bitmap bitmap = BitmapFactory.decodeByteArray(mCameraData, 0, mCameraData.length);
mCameraImage.setImageBitmap(bitmap);
mCamera.stopPreview();
mCameraPreview.setVisibility(View.INVISIBLE);
mCameraImage.setVisibility(View.VISIBLE);
if (mCameraData != null) {
Intent intent = new Intent();
intent.putExtra(EXTRA_CAMERA_DATA, mCameraData);
setResult(RESULT_OK, intent);
} else {
setResult(RESULT_CANCELED);
}
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.5;
double targetRatio = (double) w / h;
if (sizes == null) return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
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;
}
public static void setCameraDisplayOrientation(Context context,
int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = ((Activity)context).getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
// camera.getParameters().setRotation(result);
}
}
Я могу повернуть растровое изображение до 90, прежде чем показывать в режиме просмотра изображений, используя код:
public static Bitmap rotateImage(Bitmap img, int degree) {
Matrix matrix = new Matrix();
matrix.postRotate(degree);
Bitmap rotatedImg = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, true);
img.recycle();
return rotatedImg;
}
Но это не должен быть правильный способ его решения.Итак, как мне исправить это и показать неповоротное изображение в imageView?