Android 相机-纹理视图预览在某些设备中闪烁
我已经用TextureView实现了我的自定义CamerView,它工作得非常好。虽然在一些设备中,如Motorolla G4-棉花糖,联想KNote-棒棒糖相机预览闪烁,屏幕上出现绿色方形视图 这是我的评论Android 相机-纹理视图预览在某些设备中闪烁,android,android-textureview,Android,Android Textureview,我已经用TextureView实现了我的自定义CamerView,它工作得非常好。虽然在一些设备中,如Motorolla G4-棉花糖,联想KNote-棒棒糖相机预览闪烁,屏幕上出现绿色方形视图 这是我的评论 public class CameraTextureView extends TextureView implements TextureView.SurfaceTextureListener { private static final String TAG = CameraTextur
public class CameraTextureView extends TextureView implements TextureView.SurfaceTextureListener {
private static final String TAG = CameraTextureView.class.getSimpleName();
private Camera mCamera;
private List<Camera.Size> mSupportedPreviewSizes;
private Camera.Size mPreviewSize;
private SurfaceTexture mSurfaceTexture;
private Handler mHandler;
private Context mContext;
public void setCamera(Camera mCamera) {
try {
this.mCamera = mCamera;
if (mCamera == null) {
return;
}
startCameraPreview();
} catch (Exception e) {
FileLog.e(TAG, e);
}
}
public Camera getCamera() {
return mCamera;
}
public CameraTextureView(Context context, Camera mCamera) {
super(context);
try {
this.setSurfaceTextureListener(this);
this.mCamera = mCamera;
this.mSurfaceTexture = getSurfaceTexture();
this.mHandler = new Handler();
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
this.mContext = context;
} catch (Exception e) {
FileLog.e(TAG, e);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
try {
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
float ratio;
if (mPreviewSize.height >= mPreviewSize.width)
ratio = (float) mPreviewSize.height / (float) mPreviewSize.width;
else
ratio = (float) mPreviewSize.width / (float) mPreviewSize.height;
setMeasuredDimension(width, ApplicationLoader.getPreferences().isToShowTeamList() == true ? (int) (width * ratio) : height);
} catch (Exception e) {
FileLog.e(TAG, e);
}
}
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
try {
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;
} catch (Exception e) {
FileLog.e(TAG, e);
}
return null;
}
public void startCameraPreview() {
try {
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
mCamera.setPreviewTexture(getSurfaceTexture());
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
parameters.setRotation(90);
mCamera.setDisplayOrientation(90);
mCamera.setParameters(parameters);
mCamera.startPreview();
} catch (Exception e) {
FileLog.e(TAG, e);
}
}
};
Thread thread = new Thread(runnable);
thread.start();
} catch (Exception e) {
FileLog.e(TAG, e);
}
}
private void setCameraDisplayOrientation(Context mContext, android.hardware.Camera camera) {
try{
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
/*int rotation = mContext.getWindowManager().getDefaultDisplay().getRotation();*/
Display display = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int rotation = display.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}catch(Exception e){
FileLog.e(TAG, e.toString());
}
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
startCameraPreview();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
}
公共类CamerateTextReview扩展了TextureView实现了TextureView.SurfaceTextureListener{
私有静态最终字符串标记=cameratexturereview.class.getSimpleName();
私人摄像机麦卡梅拉;
私有列表msupportedpreviews;
私人摄像机。尺寸mPreviewSize;
私人表面结构;
私人经理人;
私有上下文;
公共摄像机(摄像机mCamera){
试一试{
this.mCamera=mCamera;
if(mCamera==null){
返回;
}
startCameraPreview();
}捕获(例外e){
FileLog.e(TAG,e);
}
}
公共摄像机{
返回mCamera;
}
公共摄像机评论(上下文,摄像机mCamera){
超级(上下文);
试一试{
this.setSurfaceTextureListener(this);
this.mCamera=mCamera;
this.mSurfaceTexture=getSurfaceTexture();
this.mHandler=新处理程序();
mSupportedPreviewSizes=mCamera.getParameters().getSupportedPreviewSizes();
this.mContext=上下文;
}捕获(例外e){
FileLog.e(TAG,e);
}
}
@凌驾
测量时的保护空隙(内部宽度测量等级、内部高度测量等级){
试一试{
最终整数宽度=resolveSize(getSuggestedMinimumWidth(),widthMeasureSpec);
最终整数高度=resolveSize(getSuggestedMinimumHeight(),heightMeasureSpec);
if(mSupportedPreviewSizes!=null){
mPreviewSize=getOptimalPreviewSize(MSSupportedPreviewSize、宽度、高度);
}
浮动比率;
如果(mPreviewSize.height>=mPreviewSize.width)
比率=(float)mPreviewSize.height/(float)mPreviewSize.width;
其他的
比率=(浮动)mPreviewSize.width/(浮动)mPreviewSize.height;
setMeasuredDimension(宽度,ApplicationLoader.getPreferences().isToShowTeamList()==true?(int)(宽度*比率):高度);
}捕获(例外e){
FileLog.e(TAG,e);
}
}
私人相机。大小getOptimalPreviewSize(列表大小,整数w,整数h){
试一试{
最终双纵横比公差=0.1;
双目标率=(双)高/低;
如果(size==null)返回null;
照相机。大小优化大小=空;
double minDiff=double.MAX_值;
int targetHeight=h;
用于(相机尺寸:尺寸){
双倍比率=(双倍)size.width/size.height;
如果(数学abs(比率-目标比率)>纵横比公差)继续;
if(数学绝对值(尺寸高度-目标光)