我試圖創建一個研究簡單的攝像頭應用程序。 我閱讀Android Camera Official Document,然後開始編碼。 所以我做了一些步驟,以得到它的工作攝像頭:setDisplayOrientation功能不工作了三星Galaxy ACE採用Android 2.3.6
相機功能所需1.添加權限的應用程序。
2.locked我的活動只肖像模式。
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
3.增加了幾個相機回調讓我的相機工作。
- SurfaceHolder.Callback,
- Camera.PreviewCallback
- AutoFocusCallback
- ShutterCallback
- PictureCallback對RAW圖像數據
- PictureCallback爲JPG圖像數據
4.In surfaceChanged方法我正在自定義相機設置。 到目前爲止我得到了工作這對於幾乎所有的Android設備
- LG
- 香料
- 三星
- HTC
- Micromax的
- 索尼
- 摩托羅拉
- 谷歌Nexus系列。
但然後我就三星Galaxy ACE測試了Android 2.3.6版本和 發現攝像機畫面預覽旋轉爲橫向模式。
所以把日誌貓/破發點,我才知道,下面的方法是不能用於該特定型號後
//This method is not working for Samsung Galaxy ACE
camera.setDisplayOrientation(90);
//or
parameters.set("orientation", "portrait");
//or
parameters.setRotation(90);
注:我搜遍了一堆對谷歌的解決方案和SO以及但至今沒有得到任何運氣在這個
- 伊蘇斯報道here
- android camera surfaceview orientation
- Android portrait locked Camera Preview
- Android - Camera preview is sideways
- Android camera rotate
- Android: Camera preview Rotated
- How to set Android camera orientation properly?
供您參考我的示例代碼低於
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
Log.v(TAG, "surfaceChanged get called");
if (previewing) {
camera.stopPreview();
previewing = false;
}
if (camera != null) {
try {
Camera.Parameters parameters = camera.getParameters();
List<Size> sizes = parameters.getSupportedPictureSizes();
Camera.Size result = null;
for (int i = 0; i < sizes.size(); i++) {
result = (Size) sizes.get(i);
Log.i("PictureSize", "Supported Size. Width: "
+ result.width + "height : " + result.height);
if (result.width == 640) {
parameters.setPreviewSize(result.width, result.height);// 640*480
parameters.setPictureSize(result.width, result.height);
} else {
}
}
//**************************************************************//
/*
* Here is the logic I have added to Manage Camera Display Orientation
* It checks Current Orientation and SDK and then rotate display to make it Portrait view.
*/
int currentSDKVersion = android.os.Build.VERSION.SDK_INT;
Log.d(TAG, "currentVersion " + currentSDKVersion);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
if (currentSDKVersion != 7) {
camera.setDisplayOrientation(90);
parameters.setRotation(90);
} else {
parameters.setRotation(90);
/*
* params.set("orientation", "portrait");
* params.set("rotation",90);
*/
}
} else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
if (currentSDKVersion != 7) {
camera.setDisplayOrientation(0);
} else {
parameters.set("orientation", "landscape");
parameters.set("rotation", 90);
}
}
//**************************************************************//
camera.setParameters(parameters);
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
camera.autoFocus(myAutoFocusCallback);
camera.setOneShotPreviewCallback(cameraPreviewCallback);
previewing = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
我的相機活動(MainActivity.java)的完整代碼:
public class MainActivity extends Activity implements SurfaceHolder.Callback,
OnClickListener {
public static final String TAG = "CameraActivity";
private Context context = null;
Camera camera = null;
private SurfaceView surfaceView = null;
private SurfaceHolder surfaceHolder = null;
boolean previewing = false;
private LayoutInflater controlInflater = null;
private Button buttonTakePicture = null;
//private TextView textViewResultInfo = null;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.v(TAG, "onCreate get called");
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//textViewResultInfo = (TextView) findViewById(R.id.textViewResultInfo);
context = this;
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.control, null);
LayoutParams layoutParamsControl = new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
this.addContentView(viewControl, layoutParamsControl);
buttonTakePicture = (Button) findViewById(R.id.takepicture);
buttonTakePicture.setOnClickListener(this);
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
Log.v(TAG, "surfaceCreated get called");
camera = Camera.open();
if (camera != null) {
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
Log.v(TAG, "surfaceChanged get called");
if (previewing) {
camera.stopPreview();
previewing = false;
}
if (camera != null) {
try {
//new MainActivity().setCameraDisplayOrientation();
Camera.Parameters parameters = camera.getParameters();
// List<String> focusModes =
// parameters.getSupportedFocusModes();
// if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO))
// {
// parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// }
List<Size> sizes = parameters.getSupportedPictureSizes();
Camera.Size result = null;
for (int i = 0; i < sizes.size(); i++) {
result = (Size) sizes.get(i);
Log.i("PictureSize", "Supported Size. Width: "
+ result.width + "height : " + result.height);
if (result.width == 640) {
parameters.setPreviewSize(result.width, result.height);// 640*480
parameters.setPictureSize(result.width, result.height);
} else {
}
}
//**************************************************************//
Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int rotation = display.getRotation();
Log.v(TAG, "Current Device Orientation is ="+rotation);
/*
* Here is the logic I have added to Manage Camera Display Orientation
* It checks Current Orientation and SDK and then rotate display to make it Portrait view.
*/
int currentSDKVersion = android.os.Build.VERSION.SDK_INT;
Log.d(TAG, "currentVersion " + currentSDKVersion);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
if (currentSDKVersion != 7) {
Log.i(TAG, "ORIENTATION_PORTRAIT +SDK is: " + currentSDKVersion
+ "rotate 90");
camera.setDisplayOrientation(90);
parameters.setRotation(90);
} else {
Log.i(TAG, "ORIENTATION_PORTRAIT +SDK is: " + currentSDKVersion
+ "rotate 90");
parameters.setRotation(90);
/*
* params.set("orientation", "portrait");
* params.set("rotation",90);
*/
}
} else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
if (currentSDKVersion != 7) {
Log.i(TAG, "ORIENTATION_LANDSCAPE +SDK is: " + currentSDKVersion
+ "rotate 90");
camera.setDisplayOrientation(0);
} else {
Log.i(TAG, "ORIENTATION_LANDSCAPE +SDK is: " + currentSDKVersion
+ "rotate 90");
parameters.set("orientation", "landscape");
parameters.set("rotation", 90);
}
}
//**************************************************************//
camera.setParameters(parameters);
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
camera.autoFocus(myAutoFocusCallback);
camera.setOneShotPreviewCallback(cameraPreviewCallback);
previewing = true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
Log.v(TAG, "surfaceDestroyed get called");
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
public void setCameraDisplayOrientation()
{
Log.v(TAG, "setCameraDisplayOrientation get called");
if (camera == null)
{
Log.d(TAG,"setCameraDisplayOrientation - camera null");
return;
}
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(1, info);
WindowManager winManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
int rotation = winManager.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);
}
@Override
public void onClick(View v) {
Log.v(TAG, "onClick get called");
if (v == buttonTakePicture) {
camera.takePicture(myShutterCallback, myPictureCallback_RAW,
myPictureCallback_JPG);
}
}
private Camera.PreviewCallback cameraPreviewCallback = new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Log.i(TAG, "onPreviewFrame size=" + data.length);
}
};
AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback() {
@Override
public void onAutoFocus(boolean arg0, Camera arg1) {
Log.v(TAG, "onAutoFocus get called");
buttonTakePicture.setEnabled(true);
}
};
ShutterCallback myShutterCallback = new ShutterCallback() {
@Override
public void onShutter() {
Log.v(TAG, "onShutter get called");
}
};
PictureCallback myPictureCallback_RAW = new PictureCallback() {
@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
Log.v(TAG, "onPictureTaken-RAW get called");
}
};
public static Bitmap RotateBitmap(Bitmap source, float angle) {
Matrix matrix = new Matrix();
matrix.postRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(),
source.getHeight(), matrix, true);
}
PictureCallback myPictureCallback_JPG = new PictureCallback() {
@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
Bitmap rawImage = BitmapFactory.decodeByteArray(arg0, 0,
arg0.length);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
Log.v(TAG, "##### ORIENTATION_PORTRAIT ####");
rawImage = MainActivity.RotateBitmap(rawImage, 90);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
rawImage.compress(Bitmap.CompressFormat.JPEG, 100, stream);
arg0 = stream.toByteArray();
} else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
Log.v(TAG, "##### ORIENTATION_LANDSCAPE #####");
}
Intent intent = new Intent(MainActivity.this, ResultActivity.class);
intent.putExtra("picture", arg0);
startActivity(intent);
Log.v(TAG, "onPictureTaken-JPG get called");
}
};
/**
* Get the size in bitmap.
*
* @param bitmap
* @return size in bytes
*/
@TargetApi(12)
public static int getBitmapSize(Bitmap bitmap) {
if (MainActivity.hasHoneycombMR1()) {
return bitmap.getByteCount();
}
// Pre HC-MR1
return bitmap.getRowBytes() * bitmap.getHeight();
}
public static boolean hasHoneycombMR1() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1;
}
}
編輯:我已經發表的評論上Developer forum,但沒有任何反應。
請!有人對這個問題有任何想法。
我真的很感激任何形式的建議。
爲什麼你不使用manifest屬性'android:screenOrientation =「portrait」'的任何特定原因?你可能想嘗試一下,儘管我不會指望它有任何改變。此外,您是否嘗試在「裸露」項目中重現該問題 - 僅僅是爲了排除它實際上是設備特定的問題,而不是潛在的實施錯誤? –
@MH。親!感謝您的評論。上面的清單標籤,我已經添加,這是爲應用程序屏幕沒有相機預覽屏幕,btw標籤工作正常,所以應用程序屏幕始終在肖像模式,但我想旋轉相機預覽得到旋轉。即使我手動嘗試Java反射旋轉,也檢查了三星開發者網站和谷歌Android開發者的所有問題,但沒有運氣。 – swiftBoy
嘿RDC,你在最後弄明白了嗎?看起來好像沒有答案真的可以100%正常工作,例如:一旦嘗試了大部分答案,我都可以讓三星手機和仿真器工作,但Nexus例如失敗。任何想法?謝謝! –