Saya ingin mengatur orientasi kamera sesuai dengan orientasi perangkat di Android tetapi sepertinya tidak ada yang berfungsi. Saya mencoba memutar Permukaan serta parameter kamera tetapi pratinjau kamera dalam mode potret selalu terbalik. Saya perlu memutarnya 90 derajat searah jarum jam agar benar. Berikut adalah kode yang saya gunakan sekarang yang hanya berfungsi dalam mode lanskap.
SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
initCamera();
}
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.2;
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) {
Log.d(TAG, "Checking size " + size.width + "w " + size.height
+ "h");
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;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Camera.Parameters parameters = camera.getParameters();
List<Size> sizes = parameters.getSupportedPreviewSizes();
Size optimalSize = getOptimalPreviewSize(sizes, width, height);
Log.d(TAG, "Surface size is " + width + "w " + height + "h");
Log.d(TAG, "Optimal size is " + optimalSize.width + "w " + optimalSize.height + "h");
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
// parameters.setPreviewSize(width, height);
camera.setParameters(parameters);
camera.startPreview();
}
};
android
camera
orientation
surfaceview
Abhinav
sumber
sumber
Jawaban:
Dari anggota lain dan masalah saya:
Masalah Rotasi Kamera bergantung pada Perangkat yang berbeda dan Versi tertentu.
Versi 1.6: untuk memperbaiki Masalah Rotasi, dan ini bagus untuk sebagian besar perangkat
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { p.set("orientation", "portrait"); p.set("rotation",90); } if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { p.set("orientation", "landscape"); p.set("rotation", 90); }
Versi 2.1: bergantung pada jenis perangkat, misalnya, Tidak dapat memperbaiki masalah dengan XPeria X10, tetapi bagus untuk X8, dan Mini
Camera.Parameters parameters = camera.getParameters(); parameters.set("orientation", "portrait"); camera.setParameters(parameters);
Versi 2.2: tidak untuk semua perangkat
camera.setDisplayOrientation(90);
http://code.google.com/p/android/issues/detail?id=1193#c42
sumber
Dari Javadocs untuk
setDisplayOrientation(int)
(Memerlukan API level 9):public static void setCameraDisplayOrientation(Activity activity, 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.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); }
sumber
CameraInfo
tidak diperkenalkan sampai API level 9, jadi metode yang saya posting membutuhkan API level 9.result = (360 - result) % 360; // compensate the mirror
harus dihapus , gambar dari kamera depan diputar secara tidak benarSolusi ini akan berfungsi untuk semua versi Android. Anda dapat menggunakan refleksi di Java agar berfungsi di semua perangkat Android:
Pada dasarnya Anda harus membuat pembungkus refleksi untuk memanggil Android 2.2 setDisplayOrientation, daripada memanggil metode tertentu.
Metode:
protected void setDisplayOrientation(Camera camera, int angle){ Method downPolymorphic; try { downPolymorphic = camera.getClass().getMethod("setDisplayOrientation", new Class[] { int.class }); if (downPolymorphic != null) downPolymorphic.invoke(camera, new Object[] { angle }); } catch (Exception e1) { } }
Dan alih-alih menggunakan camera.setDisplayOrientation (x) gunakan setDisplayOrientation (camera, x) :
if (Integer.parseInt(Build.VERSION.SDK) >= 8) setDisplayOrientation(mCamera, 90); else { if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { p.set("orientation", "portrait"); p.set("rotation", 90); } if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { p.set("orientation", "landscape"); p.set("rotation", 90); } }
sumber
Camera.Parameters
. Coba tambahkan baris berikut:Camera.Parameters p = camera.getParameters();
Saya menghadapi masalah ketika saya menggunakan ZBar untuk memindai di tab. Masalah orientasi kamera. Menggunakan kode di bawah ini saya dapat menyelesaikan masalah. Ini bukan keseluruhan cuplikan kode, Mohon bantuannya saja dari sini.
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if (isPreviewRunning) { mCamera.stopPreview(); } setCameraDisplayOrientation(mCamera); previewCamera(); } public void previewCamera() { try { // Hard code camera surface rotation 90 degs to match Activity view // in portrait mCamera.setPreviewDisplay(mHolder); mCamera.setPreviewCallback(previewCallback); mCamera.startPreview(); mCamera.autoFocus(autoFocusCallback); isPreviewRunning = true; } catch (Exception e) { Log.d("DBG", "Error starting camera preview: " + e.getMessage()); } } public void setCameraDisplayOrientation(android.hardware.Camera camera) { Camera.Parameters parameters = camera.getParameters(); android.hardware.Camera.CameraInfo camInfo = new android.hardware.Camera.CameraInfo(); android.hardware.Camera.getCameraInfo(getBackFacingCameraId(), camInfo); Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); int rotation = display.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 (camInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (camInfo.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (camInfo.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(result); } private int getBackFacingCameraId() { int cameraId = -1; // Search for the front facing camera int numberOfCameras = Camera.getNumberOfCameras(); for (int i = 0; i < numberOfCameras; i++) { Camera.CameraInfo info = new Camera.CameraInfo(); Camera.getCameraInfo(i, info); if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) { cameraId = i; break; } } return cameraId; }
sumber
Saya akhirnya memperbaikinya menggunakan aplikasi kamera Google. Itu mendapat orientasi telepon dengan menggunakan sensor dan kemudian mengatur tag EXIF dengan tepat. JPEG yang keluar dari kamera tidak diorientasikan secara otomatis.
Selain itu, pratinjau kamera berfungsi dengan baik hanya dalam mode lanskap. Jika Anda membutuhkan layout aktivitas Anda untuk diorientasikan dalam potret, Anda harus melakukannya secara manual menggunakan nilai dari sensor orientasi.
sumber
lihat solusi ini
public static void setCameraDisplayOrientation(Activity activity, 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.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); }
sumber
Masalah ini telah diselesaikan sejak lama tetapi saya mengalami beberapa kesulitan untuk menyatukan semua bagian jadi inilah solusi terakhir saya, saya harap ini akan membantu orang lain:
public void startPreview() { try { Log.i(TAG, "starting preview: " + started); // .... Camera.CameraInfo camInfo = new Camera.CameraInfo(); Camera.getCameraInfo(cameraIndex, camInfo); int cameraRotationOffset = camInfo.orientation; // ... Camera.Parameters parameters = camera.getParameters(); List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes(); Camera.Size previewSize = null; float closestRatio = Float.MAX_VALUE; int targetPreviewWidth = isLandscape() ? getWidth() : getHeight(); int targetPreviewHeight = isLandscape() ? getHeight() : getWidth(); float targetRatio = targetPreviewWidth / (float) targetPreviewHeight; Log.v(TAG, "target size: " + targetPreviewWidth + " / " + targetPreviewHeight + " ratio:" + targetRatio); for (Camera.Size candidateSize : previewSizes) { float whRatio = candidateSize.width / (float) candidateSize.height; if (previewSize == null || Math.abs(targetRatio - whRatio) < Math.abs(targetRatio - closestRatio)) { closestRatio = whRatio; previewSize = candidateSize; } } int rotation = getWindowManager().getDefaultDisplay().getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; // Natural orientation case Surface.ROTATION_90: degrees = 90; break; // Landscape left case Surface.ROTATION_180: degrees = 180; break;// Upside down case Surface.ROTATION_270: degrees = 270; break;// Landscape right } int displayRotation; if (isFrontFacingCam) { displayRotation = (cameraRotationOffset + degrees) % 360; displayRotation = (360 - displayRotation) % 360; // compensate // the // mirror } else { // back-facing displayRotation = (cameraRotationOffset - degrees + 360) % 360; } Log.v(TAG, "rotation cam / phone = displayRotation: " + cameraRotationOffset + " / " + degrees + " = " + displayRotation); this.camera.setDisplayOrientation(displayRotation); int rotate; if (isFrontFacingCam) { rotate = (360 + cameraRotationOffset + degrees) % 360; } else { rotate = (360 + cameraRotationOffset - degrees) % 360; } Log.v(TAG, "screenshot rotation: " + cameraRotationOffset + " / " + degrees + " = " + rotate); Log.v(TAG, "preview size: " + previewSize.width + " / " + previewSize.height); parameters.setPreviewSize(previewSize.width, previewSize.height); parameters.setRotation(rotate); camera.setParameters(parameters); camera.setPreviewDisplay(mHolder); camera.startPreview(); Log.d(TAG, "preview started"); started = true; } catch (IOException e) { Log.d(TAG, "Error setting camera preview: " + e.getMessage()); } }
sumber