[英]Camera landscape preview in portrait mode
我有一個對話框設計,其中相機預覽應該在人像模式下為橫向(請參見圖片)。 我通過getOptimalPreviewSize()正確選擇了預覽大小,當我不使用setDisplayOrientation(90)時,我得到了:
當我使用setDisplayOrientation(90)時,我得到了:
有人有任何解決辦法的想法嗎? android可以做這種事情嗎?
答案(感謝Eddy Talvala):
由於當您在xml中的cam視圖為水平時無法以縱向方式處理整個cam圖片,因此應進行裁剪。 我決定水平放置並在底部裁剪所有內容:
| |
| _________ | _____
|| || | |
|| || | ^-^ |
|| ______ || | \_/ |
|| | ^-^ ||| | | |
|| |_\_/_ ||| |__|__|
|| image || sensor
|| ||
|| ||
||_________||
|| < O [] ||
|___________|
device
您應該使用TextureView為擬合和裁剪指定矩陣。 像這樣的東西(kotlin):
fun camInit() {
val camParam = camera.parameters
val optimalSize = getOptimalPortraitPreviewSize(camParam.supportedPreviewSizes, width, height)
camParam.setPreviewSize(optimalSize.width, optimalSize.height)
camera.parameters = camParam
camera.setPreviewTexture(surface)
val scaleDelta = optimalSize.height - preview.width // for portrait
val scaleY: Float = (optimalSize.width.toFloat() - scaleDelta) / preview.height // for portrait
val matrix = Matrix()
matrix.setScale(1f, scaleY) // 1f cause we fit horizontally
preview.setTransform(matrix)
camera.startPreview()
}
請注意,對於人像模式,您應該使用特定的getOptimalProtraitPreviewSize(),因為每個人都可以使用標准功能來獲得相機預覽的最佳尺寸(使用ASPECT_TOLERANCE等),可以返回具有較小分辨率的尺寸。 嘗試這樣的事情:
fun getOptimalPortraitPreviewSize(sizes: List<Camera.Size>, previewWidth: Int) {
var selectedSize: Camera.Size = sizes[0]
for (size in sizes) {
// use size's height cause of portrait
val currentSizeWidthDelta = abs(size.height - previewWidth)
val selectedSizeWidthDelta = abs(selectedSize.height - previewWidth)
if (currentSizeWidthDelta < selectedSizeWidthDelta) selectedSize = size
}
return selectedSize
}
圖像傳感器的長邊與設備的長邊對齊。
(bad ascii art):
____________
| |
| _________ | _____
|| || | |
|| || | |
|| || | |
|| || | |
|| || |_____|
|| || sensor
|| || physical
|| || orientation
||_________||
|| < O [] ||
|___________|
device
鑒於此,您無法像這樣繪制圖像:
_____________
| |
| _________ | _____
|| || | |
|| || | |
|| ______ || | |
|| | ||| | |
|| |______||| |_____|
|| image || sensor
|| ||
|| ||
||_________||
|| < O [] ||
|___________|
device
除非您旋轉圖像(在這種情況下不向上旋轉):
_____________
| |
| _________ | _____
|| || | |
|| || | ^-^ |
|| ______ || | \_/ |
|| | <-\__||| | | |
|| |_<-/__||| |__|__|
|| image || sensor
|| ||
|| ||
||_________||
|| < O [] ||
|___________|
device
或者您水平拉伸圖像,看起來很糟糕:
_____________
| |
| _________ | _____
|| || | |
|| || | ^-^ |
|| ______ || | \_/ |
|| | ^___^||| | | |
|| |___|__||| |__|__|
|| image || sensor
|| ||
|| ||
||_________||
|| < O [] ||
|___________|
device
或裁剪圖像的一部分,從而大大降低了FOV:
_____________
| |
| _________ | _____
|| || | |
|| || | ^-^ |
|| ______ || | \_/ |
|| | ^-^ ||| | | |
|| |_\_/__||| |__|__|
|| image || sensor
|| ||
|| ||
||_________||
|| < O [] ||
|___________|
device
因為當手機處於橫向時圖像傳感器是橫向的,所以如果沒有這三種情況之一,就無法在縱向UI中放置橫向預覽。 您可能需要在肖像UI中進行肖像預覽,或者需要裁剪圖像。 這不是Android的限制,只是幾何的限制。
如果要裁剪,則可能需要將相機數據發送到SurfaceTexture,然后如果要實時預覽,則要在OpenGL中裁剪。
如果您正在使用Camera2 API。 當通過ChooseOptimalSize獲得mPreviewSize時,可以交換寬度和高度。 (寬度和高度從您的角度來看)。 接着
textureView.setAspectRatio(mPreviewSize.Height, mPreviewSize.Width);
創建預覽會話時
texture.SetDefaultBufferSize(mPreviewSize.Width, mPreviewSize.Height);
然后您將預覽普通圖像
感謝@Eddy Talvala和@blinker! 我帶上我的功能可以在任何方向正確更新尺寸:
public void invalidateSize(TextureView textureView) {
Point cameraResolution = getCameraResolution();
int previewRotation = getPreviewRotation();
// Camera and preview on screen in the opposite orientation
if (previewRotation == 90 || previewRotation == 270) {
//noinspection SuspiciousNameCombination
cameraResolution = new Point(cameraResolution.y, cameraResolution.x);
}
float cameraAspectRatio = cameraResolution.x / (float) cameraResolution.y;
float textureAspectRatio = textureView.getWidth() / (float) textureView.getHeight();
float scaleX = cameraAspectRatio / textureAspectRatio;
float scaleY = textureAspectRatio / cameraAspectRatio;
if (scaleX > scaleY) {
scaleY = 1;
} else {
scaleX = 1;
}
Matrix matrix = new Matrix();
matrix.setScale(scaleX, scaleY,
textureView.getWidth() / 2f, textureView.getHeight() / 2f);
textureView.setTransform(matrix);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.