2016-01-06 4 views
7

Meine Frage ist ganz einfach: 1-Verhältnis und ohne Verformung wie Instagram:Wie bekomme ich eine Android Camera2 mit 1: 1-Verhältnis wie Instagram?

Wie ein Android android.hardware.Camera2 mit 1 zu bekommen?

Ich habe mit dem GoogeSamples-Projekt android-Camera2Basic getestet. Aber wenn ich die Vorschau im Verhältnis 1: 1 verändere, wird das Bild verformt. Hat jemand eine Idee dazu?

enter image description here

+1

- wir können nicht helfen Sie Ihren Code debuggen, wenn Sie Ihren Code zur Verfügung stellen, als Teil eines [minimal, vollständig und nachprüfbar Beispiel] (http://stackoverflow.com/help/mcve). Im Allgemeinen lautet die Antwort, dass "SurfaceView" oder "TextureView" das gleiche Seitenverhältnis wie das Bild von der Kamera haben, aber dann negative Ränder oder äquivalente Rendertricks verwenden, um nur eine quadratische Teilmenge dessen anzuzeigen, was von der Kamera kommt Kamera. – CommonsWare

+0

Danke @CommonsWare. Verwenden Sie negative Ränder, um mein Problem zu korrigieren. Ich poste meinen Code als Antwort. –

+0

@ lopez.michael Wie hast du das Seitenverhältnis geändert? werfen Sie einen Blick http://StackOverflow.com/Questions/41221284/How-to-change-aspect-Ratio-of-Camera2-preview –

Antwort

2

Dank @CommonsWare.

Ich folgte Ihrem Ratschlag mit negativen Rand (oben und unten) und es funktioniert.

, das zu tun, ich aktualisieren AutoFitTextureView nur die GoogeSamples projizieren android-Camera2Basic auf diese Weise:

public class AutoFitTextureView extends TextureView { 

    //... 
    private boolean mWithMargin = false; 

    //... 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     super.onMeasure(widthMeasureSpec, widthMeasureSpec); 
     int width = MeasureSpec.getSize(widthMeasureSpec); 
     int height = MeasureSpec.getSize(heightMeasureSpec); 
     int margin = (height - width)/2; 

     if(!mWithMargin) { 
      mWithMargin = true; 
      ViewGroup.MarginLayoutParams margins = ViewGroup.MarginLayoutParams.class.cast(getLayoutParams()); 
      margins.topMargin = -margin; 
      margins.bottomMargin = -margin; 
      margins.leftMargin = 0; 
      margins.rightMargin = 0; 
      setLayoutParams(margins); 
     } 

     if (0 == mRatioWidth || 0 == mRatioHeight) { 
      setMeasuredDimension(width, height); 
     } else { 
      if (width < height) { 
       setMeasuredDimension(width, width * mRatioHeight/mRatioWidth); 
      } else { 
       setMeasuredDimension(height * mRatioWidth/mRatioHeight, height); 
      } 
     } 
    } 
} 

enter image description here

+2

Hallo! Ich habe das gleiche Problem. Ich füge Ihre Implementierung von AutoFitTextureView hinzu, aber es funktioniert immer noch nicht. Kannst du bitte etwas mehr Code von dir App zur Verfügung stellen, um Kamera-Vorschau und Bilder in quadratischer Weise zu machen? danke! –

+0

Wenn ich dies tue, bekomme ich eine schwarze Leiste am Ende der Vorschau .. irgendwelche Ideen? – Dave

0

benutzerdefinierte Textur Ansicht wie folgt erstellen:

public class AutoFitTextureView extends TextureView { 

    private int mCameraWidth = 0; 
    private int mCameraHeight = 0; 
    private boolean mSquarePreview = false; 

    public AutoFitTextureView(Context context) { 
     this(context, null); 
    } 

    public AutoFitTextureView(Context context, AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public AutoFitTextureView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    public void setAspectRatio(int width, int height, boolean squarePreview) { 
     if (width < 0 || height < 0) { 
      throw new IllegalArgumentException("Size cannot be negative."); 
     } 
     mCameraWidth = width; 
     mCameraHeight = height; 
     mSquarePreview = squarePreview; 
     requestLayout(); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
     int width = MeasureSpec.getSize(widthMeasureSpec); 
     int height = MeasureSpec.getSize(heightMeasureSpec); 
     if (0 == mCameraWidth || 0 == mCameraHeight) { 
      setMeasuredDimension(width, height); 
     } else { 
      /** 
      * Vertical orientation 
      */ 
      if (width < height) { 
       if (mSquarePreview) { 
        setTransform(squareTransform(width, height)); 
        setMeasuredDimension(width, width); 
       } else { 
        setMeasuredDimension(width, width * mCameraHeight/mCameraWidth); 
       } 
      } 
      /** 
      * Horizontal orientation 
      */ 
      else { 
       if (mSquarePreview) { 
        setTransform(squareTransform(width, height)); 
        setMeasuredDimension(height, height); 
       } else { 
        setMeasuredDimension(height * mCameraWidth/mCameraHeight, height); 
       } 
      } 
     } 
    } 

    private Matrix setupTransform(int sw, int sh, int dw, int dh) { 
     Matrix matrix = new Matrix(); 
     RectF src = new RectF(0, 0, sw, sh); 
     RectF dst = new RectF(0, 0, dw, dh); 
     RectF screen = new RectF(0, 0, dw, dh); 

     matrix.postRotate(-90, screen.centerX(), screen.centerY()); 
     matrix.mapRect(dst); 

     matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER); 
     matrix.mapRect(src); 

     matrix.setRectToRect(screen, src, Matrix.ScaleToFit.FILL); 
     matrix.postRotate(-90, screen.centerX(), screen.centerY()); 

     return matrix; 
    } 

    private Matrix squareTransform(int viewWidth, int viewHeight) { 
     Matrix matrix = new Matrix(); 

     if (viewWidth < viewHeight) { 
      MyLogger.log(AutoFitTextureView.class, "Horizontal"); 
      matrix.setScale(1, (float) mCameraHeight/(float) mCameraWidth, viewWidth/2, viewHeight/2); 
     } else { 
      MyLogger.log(AutoFitTextureView.class, "Vertical"); 
      matrix.setScale((float) mCameraHeight/(float) mCameraWidth, 1, viewWidth/2, viewHeight/2); 
     } 

     return matrix; 
    } 
} 

Und setAspectRatio rufen Sie für Ihre Texturansicht in Aktivität/Fragment. „Aber wenn ich die Vorschau ändern mit einem Verhältnis von 1: 1 Bild verformt“

if (mVideoSize.width > mVideoSize.height) { 
    mTextureView.setAspectRatio(mVideoSize.height, mVideoSize.width, true); 
} else { 
    mTextureView.setAspectRatio(mVideoSize.width, mVideoSize.height, true); 
} 
mCamera.setPreviewTexture(mTextureView.getSurfaceTexture()); 
mCamera.startPreview(); 
+1

Hallo Mikhael! Ich versuche, Ihre Lösung zu implementieren, funktioniert aber nicht. Könnten Sie mir bitte eine vollständige Implementierung bereitstellen oder senden? das wird fantastisch sein! – anthony

Verwandte Themen