Androidアプリケーションは、getSupportedPreviewSizes()
で指定されたプレビューサイズに関係なく、歪みなしでカメラプレビューをフルスクリーンで表示する必要があります。これにより、いずれかのプレビューがある程度トリミングされると思います。高さや幅ですが、これは私には関係ありません。これを実行しようとする理由は、特定のAndroidカメラ(Samsung Galaxy SII前面カメラなど)が同じプレビューを返さないためです。ディスプレイとしてのアスペクト比。したがって、引き伸ばしてクリップする必要があります。
カメラのプレビューを表示サイズよりも大きいビューに完全に拡大することは可能ですか?返されるプレビューピクセルの寸法よりも大きくSurfaceViewを拡大することは可能ですか?サーフェスビューのレイアウトパラメータをmatch_parentに設定するだけですが、これにより、ある方向に歪みが生じ、プレビューが表示いっぱいになるまでしか可能ではありません。これは、ディスプレイの外部でのプレビューが不可能であり、ハードウェア(またはOS)がそのような動作を制限していることを示しているようです。
このトピックには 別の質問 がありますが、その質問では、ログで見つけたように、画面のサイズよりも大きいSurfaceViewを作成することはできません。これは誤りです。ただし、カメラのプレビューを巨大なSurfaceViewのフルサイズに拡大することはできません。
私の試み:
相対レイアウトがあり、その中にFrameLayoutがあり、その中にSurfaceViewを作成します。相対レイアウト全体の幅は、デバイスの画面サイズの約2倍である635dpに設定されています。 FrameLayoutはこのサイズに一致し、SurfaceViewも一致します(後でプログラムで追加されます)
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/camera_activity_layout"
Android:layout_width="635dp"
Android:layout_height="match_parent" >
<FrameLayout
Android:id="@+id/camera_preview"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
</FrameLayout>
</RelativeLayout>
以下は、プレビューサイズを取得および設定するコードです。ここでは、カメラのプレビューを拡大して、FrameLayout全体(画面幅の2倍)を埋めたいと思います。ビューは完全に正常に表示および破棄されるため、この特定の質問に関係のないコードは、本質的な質問の邪魔になるため削除し、ビューを表示サイズよりも簡単かつ単純に拡大しようとしています。
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
...
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Camera.Parameters parameters = mCamera.getParameters();
final DisplayMetrics dm = this.getResources().getDisplayMetrics();
//getBestPreviewSize returns the best preview size, don't worry
//but some devices do not return one for all camera matching the aspect ratio
cameraSize = getBestPreviewSize(parameters, dm.heightPixels, dm.widthPixels);
if (cameraSize!=null) {
parameters.setPreviewSize(cameraSize.width, cameraSize.height);
mCamera.setParameters(parameters);
}
FrameLayout.LayoutParams frameParams = (FrameLayout.LayoutParams) this.getLayoutParams();
frameParams.width = 800; //For argument's sake making this ~double the width of the display. Same result occurs if I use MATCH_PARENT
frameParams.height = LayoutParams.MATCH_PARENT;
this.setLayoutParams(frameParams);
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
Log.d("surfChange","W/H of CamPreview (child) is "+this.getWidth()+"/"+this.getHeight()+" while parent is ");
Log.d("surfChange","W/H of holder (child) is "+mHolder.getSurfaceFrame().width()+"/"+mHolder.getSurfaceFrame().height()+" while parent is ");
} catch (Exception e){
}
}
};
この試みを成功させる唯一の方法は、なんとかしてopenGLサーフェスにレンダリングすることだと私は心配していますが、これは どうやら フルカラーでは遅すぎるかもしれません。カメラのプレビューを単純に引き伸ばしてクリップできるのも面倒です。
解決策を試みてくれたことに感謝します。
わかりました、これは答えとして非常に遅いことを私は知っていますが、それは可能です。以下は、Android SDKサンプルのコードです。この実装の残りのコードを確認するには、Android sdkサンプルをダウンロードして、Samples/Android-10(one I used, could try whichever you want to target)/ApiDemos/src/com/example/Android/apis/graphics/CameraPreview.Java
class PreviewSurface extends ViewGroup implements SurfaceHolder.Callback {
...
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed && getChildCount() > 0) {
final View child = getChildAt(0);
final int width = r - l;
final int height = b - t;
int previewWidth = width;
int previewHeight = height;
if (mPreviewSize != null) {
previewWidth = mPreviewSize.width;
previewHeight = mPreviewSize.height;
}
// Center the child SurfaceView within the parent.
if (width * previewHeight > height * previewWidth) {
final int scaledChildWidth = previewWidth * height / previewHeight;
child.layout((width - scaledChildWidth) / 2, 0,
(width + scaledChildWidth) / 2, height);
} else {
final int scaledChildHeight = previewHeight * width / previewWidth;
child.layout(0, (height - scaledChildHeight) / 2,
width, (height + scaledChildHeight) / 2);
}
}
}
}
このコードは、プレビューを最小の寸法(aspcect比を台無しにしない)に合わせ、中央に他の寸法に黒いバーを配置することを目的としています。しかし、代わりに>
を<
に反転すると、目的の結果が得られます。例:
if (width * previewHeight < height * previewWidth) {...