相机previewView在一些Android设备streched [英] Camera PreviewView is streched in some android devices
问题描述
现在IM播放与谷歌和IM有一些问题,我的code中的API2相机。我有两个不同CameraSessions,一个用于视频,另一个用于图像。要做到这一点更有效的I改变code使用唯一的会话,使应用程序更高效。
做到这一点后,我的相机preVIEW没有充分的工作。当即时通讯使用的是4:3纵横比我的preVIEW成为高度streched。 9比例:在其他的方式,它使用16时,林看起来不错。
在这两种情况下,我的图片看起来不错,我的意思是,正确的preVIEW不工作,但我抽放的照片,有正确的纵横比。
我已经检查不同岗位同样的问题:
<一href=\"http://stackoverflow.com/questions/30049293/camera-$p$pview-stretched-on-few-android-devices/30153071#30153071\">Camera preVIEW舒展了几个Android设备
<一个href=\"http://stackoverflow.com/questions/16727836/camera-display-$p$pview-in-full-screen-does-not-maintain-aspect-ratio-image-i#comment32834289_16733405\">Camera在全屏幕显示/ preVIEW不保持高宽比 - 图像歪斜,以适应屏幕上的捉襟见肘
但不同的答案没有帮助我。我知道这个问题是我里面的 onMeasure(),setTransformMatrix()或OnLayoutChangeListener()
方法,但我不知道我在做什么错。
忽略code左右轮换,现在它的动态。它总是在别的条件下进入。
下面是我的code:
私人OnLayoutChangeListener mLayoutListener =新OnLayoutChangeListener(){
@覆盖
公共无效onLayoutChange(视图V,诠释离开,诠释顶部,向右诠释,
INT底部,诠释oldLeft,诠释oldTop,诠释oldRight,诠释oldBottom){ Log.d(TAG,[onLayoutChange]+ mCameraUI.getTextureView()getMeasuredWidth()+×+ mCameraUI.getTextureView()getMeasuredHeight()); INT宽度=右 - 左;
INT高=底 - 顶;
如果(M previewWidth!= ||宽度米previewHeight!=身高
|| (mOrientationResize!= M prevOrientationResize)
|| mAspectRatioResize || mOrientationChanged){ Log.i(TAG[onLayoutChange]布局改变);
米previewWidth =宽度;
米previewHeight =高度;
Log.i(TAG[onLayoutChange] preVIEW大小:+ M previewWidth +X+ M previewHeight);
setTransformMatrix(宽度,高度);
mController.onScreenSizeChanged((INT)mSurfaceTextureUncroppedWidth,
(INT)mSurfaceTextureUncroppedHeight);
mAspectRatioResize = FALSE;
mOrientationChanged = TRUE;
}
}
};
的setTransform
私人无效setTransformMatrix(INT宽度,高度INT){
Log.i(TAG,屏幕显示:+ M previewWidth +X+ M previewHeight); mMatrix =新的Matrix();
//mCameraUI.getTextureView().getTransform(mMatrix);
漂浮的scaleX = 1F,的scaleY = 1F;
浮scaledTextureWidth,scaledTextureHeight; mAspectRatio =(浮点)高度/(浮点)宽度;
如果(mAspectRatio ==(4F / 3F)){ scaledTextureWidth = Math.max(宽度,
(中间体)(高度/ mAspectRatio));
scaledTextureHeight = Math.max(高度,
(INT)(宽* mAspectRatio));
Log.i(TAG[PhotoUIManager]:宽高比4:3 =+ scaledTextureWidth +X+ scaledTextureHeight);
}
其他{
scaledTextureWidth = Math.max(宽度,
(中间体)(高度/ mAspectRatio));
scaledTextureHeight = Math.max(高度,
(INT)(宽* mAspectRatio));
Log.i(TAG[PhotoUIManager]:宽高比16:9 =+ scaledTextureWidth +X+ scaledTextureHeight);
}
如果(mSurfaceTextureUncroppedWidth!= scaledTextureWidth || mSurfaceTextureUncroppedHeight!= scaledTextureHeight){
Log.e(TAG,MI SurfaceWidth =+ mSurfaceTextureUncroppedWidth +和MI scaledWidth =+ scaledTextureWidth);
Log.e(TAG,MI SurfaceHeigh =+ mSurfaceTextureUncroppedHeight +和MI scaledHeight =+ scaledTextureHeight);
mSurfaceTextureUncroppedWidth = scaledTextureWidth;
mSurfaceTextureUncroppedHeight = scaledTextureHeight;
Log.e(TAG,面+ mSurfaceTextureUncroppedWidth +X+ mSurfaceTextureUncroppedHeight);
如果(mSurfaceTextureSizeListener!= NULL){
mSurfaceTextureSizeListener.onSurfaceTextureSizeChanged(
(INT)mSurfaceTextureUncroppedWidth,(INT)mSurfaceTextureUncroppedHeight);
}
}
将scaleX = scaledTextureWidth /宽度;
的scaleY = scaledTextureHeight /高度;
mMatrix.setScale(将scaleX,的scaleY,scaledTextureWidth / 2,scaledTextureHeight / 2);
Log.e(TAG,规模:X =+ +的scaleXY =+ +的scaleYWIDTH =+ scaledTextureWidth +HEIGHT =+ scaledTextureHeight); //初始化的位置(这似乎是必要过于当该比值16/9
mCameraUI.getTextureView()setX的(0)。
。mCameraUI.getTextureView()SETY(0); //翻译了preVIEW用旋转宽比为4/3
如果(mAspectRatio == 4F / 3F){
Log.e(TAG,宽高比标准);
浮verticalTranslateOffset =(mCameraUI.getTextureView()getMeasuredHeight() - scaledTextureHeight。)/ 2;
浮horizontalTranslateOffset =(mCameraUI.getTextureView()getMeasuredWidth() - scaledTextureWidth。)/ 2;
INT旋转= CameraUtil.getDisplayRotation(mActivity);
开关(旋转){
情况下0:
//电话画像;翻译preVIEW起来
。mCameraUI.getTextureView()塞蒂(-verticalTranslateOffset);
mFaceView.setStandard previewTranslationOffset(-verticalTranslateOffset);
mFocusView.setStandard previewTranslationOffset(-verticalTranslateOffset);
打破;
案例90:
//电话景观:翻译preVIEW左
。mCameraUI.getTextureView()setX的(-horizontalTranslateOffset);
mFaceView.setStandard previewTranslationOffset(-horizontalTranslateOffset);
mFocusView.setStandard previewTranslationOffset(-horizontalTranslateOffset);
打破;
案例180:
//电话倒挂:翻译preVIEW底部
。mCameraUI.getTextureView()塞蒂(verticalTranslateOffset);
mFaceView.setStandard previewTranslationOffset(verticalTranslateOffset);
mFocusView.setStandard previewTranslationOffset(verticalTranslateOffset);
打破;
案例270:
//反转景观:翻译preVIEW权
。mCameraUI.getTextureView()setX的(horizontalTranslateOffset);
mFaceView.setStandard previewTranslationOffset(horizontalTranslateOffset);
mFocusView.setStandard previewTranslationOffset(horizontalTranslateOffset);
打破;
} }其他{
Log.e(TAG,宽高比全);
mFaceView.setStandard previewTranslationOffset(0);
mFocusView.setStandard previewTranslationOffset(0);
} mRenderOverlay.updateLayout();
mCameraUI.getTextureView()的setTransform(mMatrix)。 RectF previewRect =新RectF(0,0,宽度,高度); mController.on previewRectChanged(CameraUtil.rectFToRect(previewRect));}
onMeasure
保护无效onMeasure(INT widthMeasureSpec,诠释heightMeasureSpec){
super.onMeasure(widthMeasureSpec,heightMeasureSpec);
INT宽度= MeasureSpec.getSize(widthMeasureSpec);
INT高度= MeasureSpec.getSize(heightMeasureSpec); Log.d(TAGonMeasure preVIOUS宽x高。[+ widthMeasureSpec +=+宽+X+ heightMeasureSpec +=+高度+]); INT旋转=((活动)的getContext())getWindowManager()getDefaultDisplay()getRotation()。;
布尔isInHorizontal = Surface.ROTATION_90 == ||旋转Surface.ROTATION_270 ==转动; INT newWidth;
INT newHeight; 如果(isInHorizontal){ newHeight = getMeasuredHeight();
newWidth =(INT)(newHeight * mAspectRatio);
}其他{ newWidth = getMeasuredWidth();
newHeight =(INT)(newWidth * mAspectRatio);
} setMeasuredDimension(newWidth,newHeight);
Log.d(TAG。onMeasure宽度x高度[+ newWidth +×+ newHeight +]);}
解决了!
我对我的纹理缓冲区大小,当我inicializated一个新的会话或变更后的比例后刚刚重新启动缺省值。但没有更新,比对纹理的宽度和高度值,因此它成为一次又一次streched。
我解决它改变了我的defaultbufferSize与previewSizes我始终认为我改变比例进行更新。
公共无效createCamera previewSession(尺寸previewsize,表面recordingSurface){
尝试{
如果(mCaptureSession!= NULL){
mCaptureSession.sto prepeating();
mCaptureSession.close();
mCaptureSession = NULL;
} 质地表面纹理= mTextureView.getSurfaceTexture();
断言质感!= NULL; 清单&lt;表面&GT;表面=新的ArrayList&lt;表面&GT;(); //我们配置默认缓冲区的大小是我们想要的相机preVIEW的大小。
texture.setDefaultBufferSize(previewsize.getWidth(),previewsize.getHeight());
;
//这是我们需要开始preVIEW输出表面。
面面=新的表面(质感);
.......
Right now im playing with the API2 Camera of google and im having some problems with my code. I had two different CameraSessions, one for video and another one for images. To do it more efficient I change the code to use a unique Session and make the app more efficient.
After do this, my camera preview is not working adequately. When Im using a 4:3 aspect ratio my preview become streched at height. In other way it looks fine when Im using 16:9 ratio. In both cases my pictures looks fine, I mean, preview doesnt work correctly but the pictures that I taked, have the correct aspect ratio.
I already check different post with the same problem: Camera Preview Stretched on Few Android Devices
But the different answers didnt help me. I know that the problem is inside my onMeasure() , setTransformMatrix() or OnLayoutChangeListener()
methods, but I dont know what iḿ doing wrong.
Ignore the code about Rotation, right now its dynamic. It always enter at else condition.
Here is my code:
private OnLayoutChangeListener mLayoutListener = new OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right,
int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
Log.d(TAG, "[onLayoutChange] " + mCameraUI.getTextureView().getMeasuredWidth() + "x" + mCameraUI.getTextureView().getMeasuredHeight());
int width = right - left;
int height = bottom - top;
if (mPreviewWidth != width || mPreviewHeight != height
|| (mOrientationResize != mPrevOrientationResize)
|| mAspectRatioResize || mOrientationChanged) {
Log.i(TAG, "[onLayoutChange] Layout changed");
mPreviewWidth = width;
mPreviewHeight = height;
Log.i(TAG, "[onLayoutChange] Preview size: "+ mPreviewWidth + "x" + mPreviewHeight);
setTransformMatrix(width, height);
mController.onScreenSizeChanged((int) mSurfaceTextureUncroppedWidth,
(int) mSurfaceTextureUncroppedHeight);
mAspectRatioResize = false;
mOrientationChanged = true;
}
}
};
setTransform
private void setTransformMatrix(int width, int height) {
Log.i(TAG, "Screen: " + mPreviewWidth + "x" + mPreviewHeight);
mMatrix = new Matrix();
//mCameraUI.getTextureView().getTransform(mMatrix);
float scaleX = 1f, scaleY = 1f;
float scaledTextureWidth, scaledTextureHeight;
mAspectRatio= (float)height/(float)width;
if (mAspectRatio==(4f / 3f)){
scaledTextureWidth = Math.max(width,
(int) (height / mAspectRatio));
scaledTextureHeight = Math.max(height,
(int) (width * mAspectRatio));
Log.i(TAG, "[PhotoUIManager]: Aspect Ratio 4:3=" + scaledTextureWidth + "x" + scaledTextureHeight );
}
else{
scaledTextureWidth = Math.max(width,
(int) (height / mAspectRatio));
scaledTextureHeight = Math.max(height,
(int) (width * mAspectRatio));
Log.i(TAG, "[PhotoUIManager]: Aspect Ratio 16:9=" + scaledTextureWidth + "x" + scaledTextureHeight );
}
if (mSurfaceTextureUncroppedWidth != scaledTextureWidth || mSurfaceTextureUncroppedHeight != scaledTextureHeight) {
Log.e(TAG,"mi SurfaceWidth = " + mSurfaceTextureUncroppedWidth + "and mi scaledWidth=" + scaledTextureWidth);
Log.e(TAG,"mi SurfaceHeigh = " + mSurfaceTextureUncroppedHeight + "and mi scaledHeight=" + scaledTextureHeight);
mSurfaceTextureUncroppedWidth = scaledTextureWidth;
mSurfaceTextureUncroppedHeight = scaledTextureHeight;
Log.e(TAG,"Surfaces: " + mSurfaceTextureUncroppedWidth + "x" + mSurfaceTextureUncroppedHeight);
if (mSurfaceTextureSizeListener != null) {
mSurfaceTextureSizeListener.onSurfaceTextureSizeChanged(
(int) mSurfaceTextureUncroppedWidth, (int) mSurfaceTextureUncroppedHeight);
}
}
scaleX = scaledTextureWidth / width;
scaleY = scaledTextureHeight / height;
mMatrix.setScale(scaleX, scaleY, scaledTextureWidth/2, scaledTextureHeight/2);
Log.e(TAG, "scale: X= " + scaleX + " Y=" + scaleY + "Width= " + scaledTextureWidth + "Height= " + scaledTextureHeight);
// init the position (this seems to be necessary too when the ratio is 16/9
mCameraUI.getTextureView().setX(0);
mCameraUI.getTextureView().setY(0);
// Translate the preview with the rotation is aspect ration is 4/3
if (mAspectRatio == 4f / 3f) {
Log.e(TAG, "aspect ratio standard");
float verticalTranslateOffset = (mCameraUI.getTextureView().getMeasuredHeight() - scaledTextureHeight) / 2;
float horizontalTranslateOffset = (mCameraUI.getTextureView().getMeasuredWidth() - scaledTextureWidth) / 2;
int rotation = CameraUtil.getDisplayRotation(mActivity);
switch (rotation) {
case 0:
// phone portrait; translate the preview up
mCameraUI.getTextureView().setY(-verticalTranslateOffset);
mFaceView.setStandardPreviewTranslationOffset(-verticalTranslateOffset);
mFocusView.setStandardPreviewTranslationOffset(-verticalTranslateOffset);
break;
case 90:
// phone landscape: translate the preview left
mCameraUI.getTextureView().setX(-horizontalTranslateOffset);
mFaceView.setStandardPreviewTranslationOffset(-horizontalTranslateOffset);
mFocusView.setStandardPreviewTranslationOffset(-horizontalTranslateOffset);
break;
case 180:
// phone upside down: translate the preview bottom
mCameraUI.getTextureView().setY(verticalTranslateOffset);
mFaceView.setStandardPreviewTranslationOffset(verticalTranslateOffset);
mFocusView.setStandardPreviewTranslationOffset(verticalTranslateOffset);
break;
case 270:
// reverse landscape: translate the preview right
mCameraUI.getTextureView().setX(horizontalTranslateOffset);
mFaceView.setStandardPreviewTranslationOffset(horizontalTranslateOffset);
mFocusView.setStandardPreviewTranslationOffset(horizontalTranslateOffset);
break;
}
} else {
Log.e(TAG, "aspect ratio full");
mFaceView.setStandardPreviewTranslationOffset(0);
mFocusView.setStandardPreviewTranslationOffset(0);
}
mRenderOverlay.updateLayout();
mCameraUI.getTextureView().setTransform(mMatrix);
RectF previewRect = new RectF(0, 0, width, height);
mController.onPreviewRectChanged(CameraUtil.rectFToRect(previewRect));
}
onMeasure
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
Log.d(TAG, "onMeasure PREVIOUS. Width x Height [" + widthMeasureSpec + " = " + width + "x" + heightMeasureSpec + " = " + height + "]");
int rotation = ((Activity) getContext()).getWindowManager().getDefaultDisplay().getRotation();
boolean isInHorizontal = Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation;
int newWidth;
int newHeight;
if (isInHorizontal) {
newHeight = getMeasuredHeight();
newWidth = (int) (newHeight * mAspectRatio);
} else {
newWidth = getMeasuredWidth();
newHeight = (int) (newWidth * mAspectRatio);
}
setMeasuredDimension(newWidth, newHeight);
Log.d(TAG, "onMeasure. Width x Height [" + newWidth + "x" + newHeight + "]");
}
Solved!
I had a default values for the BufferSize of my texture, which just are restarted when I inicializated a new Session or after change the after ratio. But the Width and Height values for the texture were not updated with the ratio, so it becomes streched again and again.
I solved it changing my defaultbufferSize with the PreviewSizes which I update always that i change the ratio.
public void createCameraPreviewSession(Size previewsize, Surface recordingSurface) {
try {
if (mCaptureSession != null) {
mCaptureSession.stopRepeating();
mCaptureSession.close();
mCaptureSession = null;
}
SurfaceTexture texture = mTextureView.getSurfaceTexture();
assert texture != null;
List<Surface> surfaces = new ArrayList<Surface>();
// We configure the size of default buffer to be the size of camera preview we want.
texture.setDefaultBufferSize(previewsize.getWidth(),previewsize.getHeight());
;
// This is the output Surface we need to start preview.
Surface surface = new Surface(texture);
.......
这篇关于相机previewView在一些Android设备streched的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!