Ich versuche, meine eigene Kameraansicht wie die Kamera von "SnapChat" zu implementieren. Ich komme aus Xamarin.Forms Ich habe eine wirklich harte Zeit, um das Problem zu verstehen, das ich habe. Gibt es eine Möglichkeit, den gesamten Bildschirm beizubehalten und den Stretch aus der Kameraansicht zu entfernen?Xamarin.Android Kamera auf TextureView immer gestreckt
Kommend von Xamarin.Forms können Sie leicht den Aspekt des Bildes im XAML ändern, ich konnte keine ähnliche Eigenschaft in Xamarin.Android finden. Gibt es eine Art von Eigentum?
Derzeit testen auf Samsung S8 +.
Die Kamera-Ansicht funktioniert wie erwartet (Aufnehmen von Bildern), aber die Aussicht ist Bild Stretched Sie hier sehen können
dies meine Ansicht Code ist
<?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>
und dies ist der Code hinter
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
}
1) Kameras von verschiedenen OEMs haben unterschiedliche Seitenverhältnisse. 2) Ich sehe nicht, wo Sie die Vorschaugrößen der Kamera bekommen, die benötigt werden, um die Ausgabe richtig zu transformieren, es gibt viele Beispiele, die herum schweben: zB https://Stackoverflow.com/a/17878832/4984832 – SushiHangover
Ich habe getestet Die App auf verschiedenen Geräten und die Probleme bestehen auf einer Vielzahl von Geräten. Das ist mein Problem, dass ich keine Funktion oder eine Eigenschaft finden kann, wo ich die Vorschaugröße einstellen kann. –
Holen Sie sich die Vorschaugröße und verwandeln Sie sie in die TextureView, lesen Sie die vorhandenen Antworten (es gibt viele ;-): https://StackOverflow.com/search?q=android+camera+preview+aspect+Ratio+textureview – SushiHangover