我发现当我使用PreviewFrameLayout
时,CameraPreview显示在一个小区域中,当我使用宽高比和FrameLayout
时,它会被拉伸。
以下是我目前用于设置Camera Preview和FrameLayout大小的代码:
private Size getOptimalPreviewSize(Activity currentActivity,
List<Size> sizes, double targetRatio) {
// Use a very small tolerance because we want an exact match.
final double ASPECT_TOLERANCE = 0.001;
if (sizes == null) return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
// Because of bugs of overlay and layout, we sometimes will try to
// layout the viewfinder in the portrait orientation and thus get the
// wrong size of mSurfaceView. When we change the preview size, the
// new overlay will be created before the old one closed, which causes
// an exception. For now, just get the screen size
Display display = currentActivity.getWindowManager().getDefaultDisplay();
int targetHeight = Math.min(display.getHeight(), display.getWidth());
if (targetHeight <= 0) {
// We don't know the size of SurfaceView, use screen height
targetHeight = display.getHeight();
}
// 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. This should not happen.
// Ignore the requirement.
if (optimalSize == null) {
Log.w(TAG, "No preview size match the aspect ratio");
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;
}
//this is what I really want to use:
private Size getDesiredPictureSize(List<Size> supportedSizeList)
{
//Resolution is widthxheight
Size result=null;
final int minArea=500*500;
final int maxArea=1000*1000;
for(Size size:supportedSizeList)
{
if(size.width*size.height>minArea && size.width*size.height<maxArea)
{
if(result==null)
result=size;
else
{
int resultArea=result.width*result.height;
int sizeArea=size.width*size.height;
if(resultArea<sizeArea)
{
result=size;
}
}
}
}
return result;
}
//I am just testing with this method:
private Size getBestPictureSize(List<Size> supportedSizeList)
{
Size result=null;
for(Size size:supportedSizeList)
{
if(result==null)
result=size;
int resultArea=result.width*result.height;
int sizeArea=size.width*size.height;
if(resultArea<sizeArea)
result=size;
}
return result;
}
List<Size> supportedPictureSizes=mParameters.getSupportedPictureSizes();
List<Size> supportedPreviewSizes=mParameters.getSupportedPreviewSizes();
Log.d(TAG,"Setting picture size");
mPictureSize=getBestPictureSize(supportedPictureSizes);
Log.d(TAG,"The Picture Width: "+mPictureSize.width+" The Picture Height: "+mPictureSize.height);
double targetRatio=(double)mPictureSize.width/mPictureSize.height;
mPreviewSize=getOptimalPreviewSize(this,supportedPreviewSizes, targetRatio);
Log.d(TAG, "The Preview Width:"+mPreviewSize.width+" Preview Height: "+mPreviewSize.height);
double ratio=(double)mPreviewSize.width/mPreviewSize.height;
Log.d(TAG,"Picture Ratio: "+targetRatio);
Log.d(TAG, "Preview Ratio: "+ratio);
int new_width=0, new_height=0;
if(getResources().getConfiguration().orientation==Configuration.ORIENTATION_PORTRAIT)
{
if((double)previewFrame.getWidth()/previewFrame.getHeight()<ratio)
{
new_width=(int)(Math.round(previewFrame.getHeight()*ratio));
new_height=getWindowManager().getDefaultDisplay().getHeight();
}
else
{
new_width=getWindowManager().getDefaultDisplay().getHeight();
new_height=(int)Math.round((double)new_width/ratio);
}
}
if(getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE)
{
if((double)previewFrame.getWidth()/previewFrame.getHeight()<ratio)
{
new_width=(int)(Math.round(previewFrame.getHeight()*ratio));
new_height=getWindowManager().getDefaultDisplay().getHeight();
}
else
{
new_width=getWindowManager().getDefaultDisplay().getWidth();
new_height=(int)Math.round((double)new_width/ratio);
}
}
//Should I set the size of the container first???
mParameters.setPictureSize(mPictureSize.width, mPictureSize.height);
mParameters.setPreviewSize(mPreviewSize.width,mPreviewSize.height);
previewFrame.setLayoutParams(new RelativeLayout.LayoutParams(new_width, new_height));
我发现使用AOSP中的PreviewFrameLayout
在一个方框中显示我的CDamera预览而不是全屏,我可以在Camera Preview does not appear full screen(displayed in a box)找到我使用PreviewFrameLayout的详细信息
答案 0 :(得分:1)
首先,如果你在xml中使用FrameLayout来托管 previewFrame ,你也应该调用
previewFrame.setLayoutParams(new FrameLayout.LayoutParams(new_width, new_height));
接下来,您可以看到getResources().getConfiguration().orientation
== Configuration.ORIENTATION_PORTRAIT
或Configuration.ORIENTATION_LANDSCAPE
是否进行相同的计算,因此这种方向根本不相关。
最后,您应该在屏幕旋转时set the camera orientation。
我相信你可以找到一个[这里的工作示例](https://stackoverflow.com/a/19448369/192373)。