在网上找资料后说预览变形是因为surfaceview的大小和传入的大小不匹配导致的,但是我在设置surfaceview的大小后预览为什么依然是变形的,我少做了哪一步吗。
经过实际测试,只有在surfaceview的长宽比设为1:1的时候预览图片才是不会变形的,但是camera2理应会根据surface的大小比例来动态调整输出,而我并没有找到跳过surfaceview直接设置surface的长宽比例的办法,想来是不可行的。
直接设置一个固定1:1的预览并不是不可行,但是我依然想要知道错在哪里
以下是我的代码:
通过characteristics获取合适的尺寸。
//获取适配尺寸
val map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
if (map == null) {
Toast.makeText(this@MainActivity, "您的手机不支持预览", Toast.LENGTH_SHORT).show()
return
}
viewSize = map.getOutputSizes(ImageFormat.JPEG).getOptimalPreviewSize(windowWidth, ratio)
getOptimalPreviewSize方法
fun Array<Size>.getOptimalPreviewSize(height: Int, ratio: Float): Size {
val TAG = "Utils.Array<Size>"
var minDiff = Double.MAX_VALUE
var optimalSize: Size = Size(0, 0)
for (size in this) {
if (abs(size.height - height) < minDiff && ratio == size.height.toFloat() / size.width) {
minDiff = abs(size.height - height).toDouble()
optimalSize = size
}
}
if (minDiff == Double.MAX_VALUE) {
for (size in this) {
if (abs(size.height - height) < minDiff) {
minDiff = Math.abs(size.height - height).toDouble()
optimalSize = size
}
}
}
if (optimalSize == Size(0, 0))
Log.d(TAG, "getOptimalPreviewSize: List<Size> is empty")
return optimalSize
}
修改surfaceview大小并获取surfaceview
//配置预览view
//这里用holder.setFixedSize(viewSize.height, viewSize.width)一样会变形
val preview: SurfaceView = findViewById<SurfaceView>(R.id.preview)
val layoutParams = preview.layoutParams
layoutParams.width = viewSize.height
layoutParams.height = viewSize.width
//从holder获取surface并传入camera
val holder = preview.holder
previewSurface = holder.surface
holder.setKeepScreenOn(true)
holder.addCallback(object : SurfaceHolder.Callback {
override fun surfaceCreated(holder: SurfaceHolder) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
outputs.add(PREVIEW_INDEX, OutputConfiguration(previewSurface))
// outputs.add(PICTURE_INDEX, OutputConfiguration(imageReader.surface))
createCameraDevice(cameraManager, cameraId, outputs)
}
}
override fun surfaceChanged(
holder: SurfaceHolder,
format: Int,
width: Int,
height: Int,
) {
return
}
override fun surfaceDestroyed(holder: SurfaceHolder) {
return
}
})
创建预览会话
@RequiresApi(Build.VERSION_CODES.P)
private fun createCaptureSession(
cameraDevice: CameraDevice,
outputs: List<OutputConfiguration>,
) {
Log.i(TAG, "myCreateCaptureSession: ====>Create Capture Session init")
cameraDevice.createCaptureSession(
SessionConfiguration(
SessionConfiguration.SESSION_REGULAR,
outputs,
{ runnable -> runnable.run() },
object : CameraCaptureSession.StateCallback() {
override fun onConfigured(session: CameraCaptureSession) {
Log.i(TAG, "onConfigured: ====>CreateCameraCaptureSession Successful")
//开启预览
val previewBuilder =
cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
previewBuilder.addTarget(previewSurface)
cameraCaptureSession = session
cameraCaptureSession.setRepeatingRequest(previewBuilder.build(), null, null)
}
override fun onConfigureFailed(session: CameraCaptureSession) {
Log.e(TAG, "onConfigureFailed: ====>Create CameraCaptureSession Failed")
}
})
)
}
最后结果