Android Camera 2 Preview Size And Devices Aspect Ratio
Solution 1:
If your Camera resolutions , texture view and your device's display dimensions are not same then you have to adjust the dimensions. For that you have to put your TextureView inside of FrameLayout. Below Code is applicable to all the devices with various Display resolutions.
Take your Display Dimetions if you are previewing in full screen.Take int DSI_height
, int DSI_width
global variable.
DisplayMetricsdisplayMetrics=newDisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
DSI_height = displayMetrics.heightPixels;
DSI_width = displayMetrics.widthPixels;
select your required resolutions from Camera2 API and assign to Size imageDimension
, Take private Size imageDimension
globally and use
setAspectRatioTextureView(imageDimension.getHeight(),imageDimension.getWidth());
and use below logic
privatevoidsetAspectRatioTextureView(int ResolutionWidth , int ResolutionHeight )
{
if(ResolutionWidth > ResolutionHeight){
intnewWidth= DSI_width;
intnewHeight= ((DSI_width * ResolutionWidth)/ResolutionHeight);
updateTextureViewSize(newWidth,newHeight);
}else {
intnewWidth= DSI_width;
intnewHeight= ((DSI_width * ResolutionHeight)/ResolutionWidth);
updateTextureViewSize(newWidth,newHeight);
}
}
privatevoidupdateTextureViewSize(int viewWidth, int viewHeight) {
Log.d(TAG, "TextureView Width : " + viewWidth + " TextureView Height : " + viewHeight);
textureView.setLayoutParams(newFrameLayout.LayoutParams(viewWidth, viewHeight));
}
Solution 2:
There might be edge cases where that approach would fail, but I don't have a perfect answer to your question why.
In contrast, I have a proper approach on how to implement a version that will most certainly work:
Looking at the Google API demos for the Camera 2, I found some sample code that should be helpful to you to make sure it will fit all screen sized correctly:
/**
* Given {@code choices} of {@code Size}s supported by a camera, choose the smallest one that
* is at least as large as the respective texture view size, and that is at most as large as the
* respective max size, and whose aspect ratio matches with the specified value. If such size
* doesn't exist, choose the largest one that is at most as large as the respective max size,
* and whose aspect ratio matches with the specified value.
*
* @param choices The list of sizes that the camera supports for the intended output
* class
* @param textureViewWidth The width of the texture view relative to sensor coordinate
* @param textureViewHeight The height of the texture view relative to sensor coordinate
* @param maxWidth The maximum width that can be chosen
* @param maxHeight The maximum height that can be chosen
* @param aspectRatio The aspect ratio
* @return The optimal {@code Size}, or an arbitrary one if none were big enough
*/privatestatic Size chooseOptimalSize(Size[] choices, int textureViewWidth,
int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {
// Collect the supported resolutions that are at least as big as the preview SurfaceList<Size> bigEnough = new ArrayList<>();
// Collect the supported resolutions that are smaller than the preview SurfaceList<Size> notBigEnough = new ArrayList<>();
int w = aspectRatio.getWidth();
int h = aspectRatio.getHeight();
for (Size option : choices) {
if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight &&
option.getHeight() == option.getWidth() * h / w) {
if (option.getWidth() >= textureViewWidth &&
option.getHeight() >= textureViewHeight) {
bigEnough.add(option);
} else {
notBigEnough.add(option);
}
}
}
// Pick the smallest of those big enough. If there is no one big enough, pick the// largest of those not big enough.if (bigEnough.size() > 0) {
return Collections.min(bigEnough, new CompareSizesByArea());
} elseif (notBigEnough.size() > 0) {
return Collections.max(notBigEnough, new CompareSizesByArea());
} else {
Log.e(TAG, "Couldn't find any suitable preview size");
return choices[0];
}
}
Also you should take a look at the whole Camera2BasicFragment.java and AutoFitTextureView.java classes for proper implementation.
Solution 3:
I solved this problem via a different approach. I get the screen width and height and calculate how much wider or higher the preview would have to be to fill the whole screen and keep aspect ratio. It works pretty well for me without any distortions.
Add a class member variable:
publicDisplayMetricsmMetrics=newDisplayMetrics();
Use the following as onMeasure
:
@OverrideprotectedvoidonMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
intwidth= MeasureSpec.getSize(widthMeasureSpec);
intheight= MeasureSpec.getSize(heightMeasureSpec);
if (0 == mRatioWidth || 0 == mRatioHeight) {
setMeasuredDimension(width, height);
} else {
WindowManagerwindowManager= (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(mMetrics);
doubleratio= (double)mRatioWidth / (double)mRatioHeight;
doubleinvertedRatio= (double)mRatioHeight / (double)mRatioWidth;
doubleportraitHeight= width * invertedRatio;
doubleportraitWidth= width * (mMetrics.heightPixels / portraitHeight);
doublelandscapeWidth= height * ratio;
doublelandscapeHeight= (mMetrics.widthPixels / landscapeWidth) * height;
if (width < height * mRatioWidth / mRatioHeight) {
setMeasuredDimension((int)portraitWidth, mMetrics.heightPixels);
} else {
setMeasuredDimension(mMetrics.widthPixels, (int)landscapeHeight);
}
}
}
Any feedback is greatly appreciated ;)
Best M
Solution 4:
Change the AutoFitTextureView.java
file and set value like below:
@Override
protectedvoid onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
if (0 == mRatioWidth || 0 == mRatioHeight) {
setMeasuredDimension(width, height);
} else {
if (width < height * mRatioWidth / mRatioHeight) {
setMeasuredDimension(width, height);
Log.d("rlijeolid1",String.valueOf(width)+"\t"+String.valueOf(height));
} else {
setMeasuredDimension(width , height);
Log.d("rlijeolid2",String.valueOf(height * mRatioWidth / mRatioHeight)+"\t"+String.valueOf(height));
}
}
}
Post a Comment for "Android Camera 2 Preview Size And Devices Aspect Ratio"