我试图实现我自己的相机视图,例如来自" SnapChat"的相机。来自Xamarin.Forms我很难理解我遇到的问题。有没有办法保持全屏并从相机视图中删除拉伸。
来自Xamarin.Forms,您可以轻松更改XAML中图像的外观,我无法在Xamarin.Android中找到任何类似的属性。有某种财产吗?
目前正在测试三星S8 +。
相机视图的工作方式与预期相似(拍照),但视图是拉伸的图像,您可以在此处看到
这是我的查看代码
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextureView
android:id="@+id/textureView"
android:layout_marginTop="-95dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/toggleFlashButton"
android:layout_width="37dp"
android:layout_height="37dp"
android:layout_gravity="top|left"
android:layout_marginLeft="25dp"
android:layout_marginTop="25dp"
android:background="@drawable/NoFlashButton" />
<Button
android:id="@+id/switchCameraButton"
android:layout_width="35dp"
android:layout_height="26dp"
android:layout_gravity="top|right"
android:layout_marginRight="25dp"
android:layout_marginTop="25dp"
android:background="@drawable/ToggleCameraButton" />
<Button
android:id="@+id/takePhotoButton"
android:layout_width="65dp"
android:layout_height="65dp"
android:layout_marginBottom="15dp"
android:layout_gravity="center|bottom"
android:background="@drawable/TakePhotoButton" />
</FrameLayout>
这是
背后的代码 public class CameraPage : PageRenderer, TextureView.ISurfaceTextureListener {
#region Fields
private Activity activity;
private Camera camera;
private CameraFacing cameraType;
private bool flashOn;
private byte[] imageBytes;
private SurfaceTexture surfaceTexture;
private Button switchCameraButton;
private Button takePhotoButton;
private TextureView textureView;
private Button toggleFlashButton;
private View view;
#endregion
#region Functions
public void OnSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
try {
camera = Camera.Open((int)cameraType);
textureView.LayoutParameters = new FrameLayout.LayoutParams(width, height, GravityFlags.FillVertical);
surfaceTexture = surface;
camera.SetPreviewTexture(surface);
PrepareAndStartCamera();
}
catch (Exception ex) {
System.Diagnostics.Debug.WriteLine(ex.Message);
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
}
}
public bool OnSurfaceTextureDestroyed(SurfaceTexture surface) {
try {
camera.StopPreview();
camera.Release();
return true;
}
catch (Exception ex) {
System.Diagnostics.Debug.WriteLine(ex.Message);
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
}
return true;
}
public void OnSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
PrepareAndStartCamera();
}
public void OnSurfaceTextureUpdated(SurfaceTexture surface) {
}
protected override void OnElementChanged(ElementChangedEventArgs<Page> e) {
base.OnElementChanged(e);
if (e.OldElement != null || Element == null)
return;
try {
activity = Context as Activity;
view = activity.LayoutInflater.Inflate(Resource.Layout.CameraLayout, this, false);
cameraType = CameraFacing.Back;
textureView = view.FindViewById<TextureView>(Resource.Id.textureView);
textureView.SurfaceTextureListener = this;
takePhotoButton = view.FindViewById<Button>(Resource.Id.takePhotoButton);
takePhotoButton.Click += TakePhotoButtonTapped;
switchCameraButton = view.FindViewById<Button>(Resource.Id.switchCameraButton);
switchCameraButton.Click += SwitchCameraButtonTapped;
toggleFlashButton = view.FindViewById<Button>(Resource.Id.toggleFlashButton);
toggleFlashButton.Click += ToggleFlashButtonTapped;
AddView(view);
}
catch (Exception ex) {
System.Diagnostics.Debug.WriteLine(ex.Message);
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
}
}
protected override void OnLayout(bool changed, int l, int t, int r, int b) {
try {
base.OnLayout(changed, l, t, r, b);
var msw = MeasureSpec.MakeMeasureSpec(r - l, MeasureSpecMode.AtMost);
var msh = MeasureSpec.MakeMeasureSpec(b - t, MeasureSpecMode.AtMost);
view.Measure(msw, msh);
view.Layout(0, 0, r - l, b - t);
}
catch (Exception ex) {
System.Diagnostics.Debug.WriteLine(ex.Message);
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
}
}
private void PrepareAndStartCamera() {
try {
camera.StopPreview();
var display = activity.WindowManager.DefaultDisplay;
if (display.Rotation == SurfaceOrientation.Rotation0) camera.SetDisplayOrientation(90);
if (display.Rotation == SurfaceOrientation.Rotation270) camera.SetDisplayOrientation(180);
camera.StartPreview();
}
catch (Exception ex) {
System.Diagnostics.Debug.WriteLine(ex.Message);
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
}
}
private void SwitchCameraButtonTapped(object sender, EventArgs e) {
try {
if (cameraType == CameraFacing.Front) {
cameraType = CameraFacing.Back;
camera.StopPreview();
camera.Release();
camera = Camera.Open((int)cameraType);
camera.SetPreviewTexture(surfaceTexture);
PrepareAndStartCamera();
}
else {
cameraType = CameraFacing.Front;
camera.StopPreview();
camera.Release();
camera = Camera.Open((int)cameraType);
camera.SetPreviewTexture(surfaceTexture);
PrepareAndStartCamera();
}
}
catch (Exception ex) {
System.Diagnostics.Debug.WriteLine(ex.Message);
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
}
}
private void ToggleFlashButtonTapped(object sender, EventArgs e) {
try {
flashOn = !flashOn;
if (flashOn) {
if (cameraType == CameraFacing.Back) {
toggleFlashButton.SetBackgroundResource(Resource.Drawable.FlashButton);
cameraType = CameraFacing.Back;
camera.StopPreview();
camera.Release();
camera = Camera.Open((int)cameraType);
var parameters = camera.GetParameters();
parameters.FlashMode = Camera.Parameters.FlashModeTorch;
camera.SetParameters(parameters);
camera.SetPreviewTexture(surfaceTexture);
PrepareAndStartCamera();
}
}
else {
toggleFlashButton.SetBackgroundResource(Resource.Drawable.NoFlashButton);
camera.StopPreview();
camera.Release();
camera = Camera.Open((int)cameraType);
var parameters = camera.GetParameters();
parameters.FlashMode = Camera.Parameters.FlashModeOff;
camera.SetParameters(parameters);
camera.SetPreviewTexture(surfaceTexture);
PrepareAndStartCamera();
}
}
catch (Exception ex) {
System.Diagnostics.Debug.WriteLine(ex.Message);
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
}
}
private async void TakePhotoButtonTapped(object sender, EventArgs e) {
try {
camera.StopPreview();
DialogService.ShowLoading("Capturing...");
var image = textureView.Bitmap;
using (var imageStream = new MemoryStream()) {
await image.CompressAsync(Bitmap.CompressFormat.Png, 75, imageStream);
image.Recycle();
imageBytes = imageStream.ToArray();
}
camera.StartPreview();
await App.NavigationController.PushAsync(new ImagePreviewView(imageBytes));
DialogService.HideLoading();
}
catch (Exception ex) {
System.Diagnostics.Debug.WriteLine(ex.Message);
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
}
}
#endregion
}
答案 0 :(得分:1)
尝试在onMeasure中获得宽高比:
protected void onMeasure(int widthSpec, int heightSpec) {//}
检查链接Camera Preview Stretched, Camera Preview
尝试原始here
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// We purposely disregard child measurements because act as a
// wrapper to a SurfaceView that centers the camera preview instead
// of stretching it.
int width = ResolveSize(SuggestedMinimumWidth, widthMeasureSpec);
int height = ResolveSize(SuggestedMinimumHeight, heightMeasureSpec);
SetMeasuredDimension(width, height);
if (_mSupportedPreviewSizes != null)
{
_mPreviewSize = GetOptimalPreviewSize(_mSupportedPreviewSizes, width, height);
}
}
检查此链接:
Camera Preview Stretched on few Devices
希望这可以帮助你。