[解決済み] Android Camera Preview Stretched
質問
Androidでカスタムカメラのアクティビティを作成しているのですが、カメラを回転させるとサーフェスビューの縦横比がおかしくなってしまいます。
アクティビティのoncreateで、カメラのパラメータを表示するサーフェスビューを保持するframelayoutを設定しました。
//FrameLayout that will hold the camera preview
FrameLayout previewHolder = (FrameLayout) findViewById(R.id.camerapreview);
//Setting camera's preview size to the best preview size
Size optimalSize = null;
camera = getCameraInstance();
double aspectRatio = 0;
if(camera != null){
//Setting the camera's aspect ratio
Camera.Parameters parameters = camera.getParameters();
List<Size> sizes = parameters.getSupportedPreviewSizes();
optimalSize = CameraPreview.getOptimalPreviewSize(sizes, getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
aspectRatio = (float)optimalSize.width/optimalSize.height;
}
if(optimalSize!= null){
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, (int)(getResources().getDisplayMetrics().widthPixels*aspectRatio));
previewHolder.setLayoutParams(params);
LayoutParams surfaceParams = new LayoutParams(LayoutParams.MATCH_PARENT, (int)(getResources().getDisplayMetrics().widthPixels*aspectRatio));
cameraPreview.setLayoutParams(surfaceParams);
}
cameraPreview.setCamera(camera);
//Adding the preview to the holder
previewHolder.addView(cameraPreview);
次に、Surfaceビューで、カメラのパラメータを表示するように設定します。
public void setCamera(Camera camera) {
if (mCamera == camera) { return; }
mCamera = camera;
if (mCamera != null) {
requestLayout();
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
e.printStackTrace();
}
if(mCamera != null){
//Setting the camera's aspect ratio
Camera.Parameters parameters = mCamera.getParameters();
List<Size> sizes = parameters.getSupportedPreviewSizes();
Size optimalSize = getOptimalPreviewSize(sizes, getResources().getDisplayMetrics().widthPixels, getResources().getDisplayMetrics().heightPixels);
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
mCamera.setParameters(parameters);
}
/*
Important: Call startPreview() to start updating the preview surface. Preview must
be started before you can take a picture.
*/
mCamera.startPreview();
}
}
<イグ
携帯電話を回転させると、レゴマンが背伸びをしたり痩せたりするのがわかります。
カメラビューのアスペクト比が正しいことを確認するにはどうすればよいですか?
どのように解決するのですか?
APIデモを元に、この方法を使ってプレビューサイズを取得しています。
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio=(double)h / w;
if (sizes == null) return null;
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
for (Camera.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);
}
}
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
見ての通り、画面の幅と高さを入力する必要があります。このメソッドは、これらの値に基づいて画面の比率を計算し、サポートされているプレビューサイズのリストから、利用可能なものの中からあなたに最適なものを選択します。CameraオブジェクトがNULLでない場合は、以下のようにしてsupportedPreviewSizeのリストを取得します。
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
そしてonMeasureで、このように最適なpreviewSizeを取得することができます。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
}
そして、(私のコードではsurfaceChangedメソッドで、私がCameraActivityコードのAPI Demos構造を使用していると言ったように、あなたはEclipseでそれを生成することができます)。
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
mCamera.setParameters(parameters);
mCamera.startPreview();
あと、私もほぼ同じアプリをやっていたので、一つヒントを。カメラアプリの場合、ステータスバーを非表示にするのが良い方法です。Instagramのようなアプリケーションは、それをやっている。画面の高さの値が小さくなり、比率の値も変わります。端末によってはプレビューサイズがおかしくなる可能性があります(SurfaceViewが少し削られます)。
ご質問の件ですが、プレビューの比率が正しいかどうかを確認するにはどうしたらよいでしょうか。という質問に対して、「プレビューの比率が正しいかどうかを確認する方法」ということで、「パラメータで設定した高さと幅を取得する。
mCamera.setParameters(parameters);
設定された比率は高さ/幅と同じです。もしカメラが画面上できれいに見えるようにしたいなら、カメラに設定したパラメータの高さと幅の比率は、画面の高さ(ステータスバーを除く)/幅の比率と同じでなければなりません。
関連
-
Android.mk:7: *** セパレータがありません。
-
プログラム "git.exe "を実行できない場合の正しい解決方法です。CreateProcessエラー=2
-
RuntimeException: アクティビティを開始できません ComponentInfo solution
-
Android ProgressBarの色を変更する
-
アンドロイドの遅延実行のいくつかの方法
-
android.content.ActivityNotFoundException を解決します。Intent問題を処理するActivityが見つからない
-
[解決済み] Androidのソフトキーボードをプログラムで閉じる/隠すにはどうすればよいですか?
-
[解決済み] Androidでアクティビティ起動時にEditTextにフォーカスが当たらないようにする方法
-
[解決済み] Androidの「コンテキスト」とは何ですか?
-
[解決済み】Android UserManager.isUserAGoat()の正しい使用例?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
ジャークとして。起動アクティビティを特定できませんでした。デフォルトのアクティビティが見つかりません アクティビティ起動中のエラー
-
AndroidでListViewを使ってカスタムテーブルを描画する
-
Androidの美しいSeekBarスタイルのカスタマイズ
-
Android Get set image.setImageResource(R.drawable.xxx) リソース
-
Android基本アプレット
-
Androidカスタムドロップダウンリストボックスコントロール
-
アンドロイドシェイプ、グラデーション、角丸、ボーダーラインの設定
-
アプリの実行エラー。ターゲットデバイスが見つからない問題
-
Android Studio常见错误之:Rendering Problems/The following classes could not be instantiated
-
android studioが新しいプロジェクトを作成しますが、プロジェクトの同期に成功するまでデザインエディタが使用できません。