我在使用目标sdk 22构建的应用程序中使用自定义相机。我在许多设备上通过我的应用程序测试了相机,包括三星S5,三星Note 4和华为登高伙伴7,图像预览很好。
但是当我在Samsung Galaxy S4(Android 5.0.1)中通过我的应用程序打开相机时,我的相机预览失真了。以下是预览图片:
我在stackoverflow上看过很多帖子,但是他们在捕获图像之后发现了我的问题是在捕获图片之前。
以下是我用于预览的代码:
surfaceChanged方法
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
try {
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Camera.Parameters parameters = camera.getParameters();
try {
List<Camera.Size> supportedSizes = null;
supportedSizes = Compatibility.getSupportedPreviewSizes(parameters);
//preview form factor
float ff = (float)w/h;
Log.d("", "Screen res: w:"+ w + " h:" + h + " aspect ratio:" + ff);
//holder for the best form factor and size
float bff = 0;
int bestw = 0;
int besth = 0;
Iterator<Camera.Size> itr = supportedSizes.iterator();
while(itr.hasNext()) {
Camera.Size element = itr.next();
//current form factor
float cff = (float)element.width/element.height;
Log.d("Camera", "Candidate camera element: w:"+ element.width + " h:" + element.height + " aspect ratio:" + cff);
int currentRes = element.width*element.height;
//ff = Asp ratio of current Screen
// cff = Asp ratio of current Size from Size list
// bff = Asp ratio of current best aspect ratio selected
if ((Math.abs(ff-cff) <= Math.abs(ff-bff) ) ) {
bff=cff;
bestw = element.width;
besth = element.height;
}
}
Log.d("Camera", "Chosen camera element: w:"+ bestw + " h:" + besth + " aspect ratio:" + bff);
if ((bestw == 0) || (besth == 0)){
Log.d("Camera", "Using default camera parameters!");
bestw = 480;
besth = 320;
Log.d("Camera","Using default camera parameters! aspect ratio "+480/320);
}
parameters.setPreviewSize(bestw, besth);
//Handling camera angle
switch(this.getWindowManager().getDefaultDisplay().getRotation()){
case 0:
camera.setDisplayOrientation(90);
break;
case 1:
camera.setDisplayOrientation(0);
break;
case 2:
case 3:
camera.setDisplayOrientation(180);
break;
}
} catch (Exception ex) {
parameters.setPreviewSize(480 , 320);
}
camera.setParameters(parameters);
camera.startPreview();
} catch (Exception ex) {
ex.printStackTrace();
}
}
Compatibility.getSupportedPreviewSizes(参数)方法
@SuppressWarnings("unchecked")
public static List<Camera.Size> getSupportedPreviewSizes(Camera.Parameters params) {
List<Camera.Size> retList = null;
try {
Object retObj = mParameters_getSupportedPreviewSizes.invoke(params);
if (retObj != null) {
retList = (List<Camera.Size>)retObj;
}
}
catch (InvocationTargetException ite) {
/* unpack original exception when possible */
Throwable cause = ite.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
} else {
/* unexpected checked exception; wrap and re-throw */
throw new RuntimeException(ite);
}
} catch (IllegalAccessException ie) {
//System.err.println("unexpected " + ie);
}
return retList;
}
我会感激任何帮助。
提前致谢。
答案 0 :(得分:0)
在Samsung Note IV上,我意识到你不应该使用setPreviewSize(),即使从getSupportedPreviewSizes()
获得的大小应该合法且可用。
三星的低级相机软件是一个尴尬的错误。 Uncool,三星!它仅使用某些设备进行复制。
但是,拍摄仍然无可挑剔。 所以,这是我的代码: Camera.Parameters parameters = camera.getParameters();
boolean currentPreviewSettingsAreValid = parameters != null;
currentPreviewSettingsAreValid = currentPreviewSettingsAreValid && parameters.getPreviewSize() != null;
currentPreviewSettingsAreValid = currentPreviewSettingsAreValid && parameters.getPreviewSize().width > 0 && parameters.getPreviewSize().height > 0;
if (parameters != null && !currentPreviewSettingsAreValid) {
Camera.Size bestSize = getBestSizeOfSupported(parameters.getSupportedPreviewSizes(), width, height);
if (bestSize != null) {
parameters.setPreviewSize(bestSize.width, bestSize.height);
}
}
希望它可以帮助任何人