Sto cercando (di nuovo) per creare la logica anteprima fotocamera che effettivamente funziona correttamente, per tutti gli scenari:Come si determina l'orientamento di default dei fotogrammi di anteprima della videocamera?
- qualsiasi dispositivo: telefono, tablet, tostapane, qualunque sia
- qualsiasi fotocamera: anteriore-rivestimento, posteriore-rivestimento, in senso longitudinale, cane-facing, qualunque
android.hardware.Camera
eandroid.hardware.camera2
- orientamento verticale e orizzontale dei dispositivi
Poiché il mio minSdkVersion
è 15, e poiché non sono particolarmente preoccupato per le prestazioni, sto cercando di utilizzare un TextureView
. E, seguendo il consiglio di Fadden in luoghi come here e here, sto cercando di utilizzare setTransform()
su quel TextureView
con un appropriato Matrix
che:
- orienta l'anteprima correttamente, prendendo l'orientamento del dispositivo in considerazione
- riempie la
TextureView
completamente, al prezzo del ritaglio in cui il rapporto di aspettoTextureView
non corrisponde al rapporto di aspetto del fotogramma di anteprima - non allunga l'immagine, in modo che un'anteprima di un elemento quadrato (ad esempio, un 3 "Post-It Note ®) mostra il quadrato nel p recensione
Nel mio caso, lo TextureView
riempie lo schermo, meno la barra di stato e la barra di navigazione.
A partire dalla adjustAspectRatio()
da Grafika's PlayMovieActivity.java
, ora ho questo:
private void adjustAspectRatio(int videoWidth, int videoHeight,
int rotation) {
if (iCanHazPhone) {
int temp=videoWidth;
videoWidth=videoHeight;
videoHeight=temp;
}
int viewWidth=getWidth();
int viewHeight=getHeight();
double aspectRatio=(double)videoHeight/(double)videoWidth;
int newWidth, newHeight;
if (getHeight()>(int)(viewWidth*aspectRatio)) {
newWidth=(int)(viewHeight/aspectRatio);
newHeight=viewHeight;
}
else {
newWidth=viewWidth;
newHeight=(int)(viewWidth*aspectRatio);
}
int xoff=(viewWidth-newWidth)/2;
int yoff=(viewHeight-newHeight)/2;
Matrix txform=new Matrix();
getTransform(txform);
float xscale=(float)newWidth/(float)viewWidth;
float yscale=(float)newHeight/(float)viewHeight;
txform.setScale(xscale, yscale);
switch(rotation) {
case Surface.ROTATION_90:
txform.postRotate(270, newWidth/2, newHeight/2);
break;
case Surface.ROTATION_270:
txform.postRotate(90, newWidth/2, newHeight/2);
break;
}
txform.postTranslate(xoff, yoff);
setTransform(txform);
}
Qui, videoWidth
e videoHeight
sono le dimensioni della fotocamera anteprima, e il metodo stesso è implementato su una sottoclasse di TextureView
. Sto chiamando questo metodo quando ho stabilito quale sia la dimensione dell'anteprima della fotocamera e dopo che lo stesso TextureView
è stato ridimensionato.
Questo sembra essere vicino ma non completamente corretto. In particolare, lo modellino — ha capovolto la larghezza e l'altezza del video — è una pugnalata al buio, poiché senza questo, mentre un Tablet Sony Z2 funziona bene, un Nexus 5 risulta orribile (un'anteprima allungata che non riempie lo schermo).
Con iCanHazPhone
impostato true
, ottengo buoni risultati su un Nexus 5:
Con iCanHazPhone
insieme a false
, ho cose del genere:
Allo stesso modo, con iCanHazPhone
set per false
, ottengo buoni risultati su un Sony Tablet Z2:
Ma se I flip a true
, ottengo:
Il mio attuale la teoria è che i diversi dispositivi hanno diversi orientamenti predefiniti della fotocamera e, a seconda dell'orientamento predefinito, è necessario capovolgere la larghezza e l'altezza dell'anteprima nei miei calcoli.
Quindi, le domande:
è la macchina fotografica garantita (tanto quanto qualsiasi coinvolgono hardware Android) per avere un orientamento di default che corrisponde all'orientamento del dispositivo di default? Ad esempio, un Nexus 9 funziona correttamente con
iCanHazPhone
impostato sutrue
, ad indicare che non si tratta di telefono o tablet ma di impostazione predefinita rispetto a predefinito.C'è un modo migliore per affrontare questo?
Non molto tempo fa ho ricevuto le seguenti e-mail brevi relative a una delle mie applicazioni della fotocamera; _ Abbiamo rilevato che su dispositivi con orientamento orizzontale predefinito, come Nexus 10, l'immagine di anteprima appare ruotata di 90 gradi e stirata. Che cosa mai significhi - mi è ancora sconosciuto - ma quello che stai spiegando qui mi ha ricordato questa vecchia email. Eppure da solo, come posso gestire la rotazione della telecamera su tali dispositivi che non possiedo :) – harism
@harism: Beh, usando [questo algoritmo] (http://stackoverflow.com/a/31806201/115145) per rilevare i default- i dispositivi portrait vs. default-landscape sembrano funzionare per me, in alternativa al valore hard-coded di 'iCanHazPhone' citato nella mia domanda. Questo presume che le mie supposizioni siano corrette, che è la vera domanda. Ma i tuoi sintomi suonano sicuramente come quello che stavo vedendo nei miei test. – CommonsWare
Fantastico, grazie per avermelo fatto notare. Questo mi aiuta anche a correggere la mia app, spero. – harism