2010-10-04 4 views
27

Was ich tue scheint scheint, es sollte einfach sein, aber ich bin immer noch verloren, nachdem ich jede mögliche Stackoverflow Antwort gelesen habe, die ich finden und alle googeln kann Artikel, den ich finden kann.Android Kamera unerklärliche Rotation auf Aufnahme für einige Geräte (nicht in EXIF)

Ich verwende eine Vorschau SurfaceView und Erfassen eines Bildes aus einer Aktivität, die für screenOrientation = "Landschaft" in meiner AndroidManifest.xml festgelegt ist.

Ich folgte dem Beispielcode der Kamera App und dachte, dass die Dinge funktionierten, bis ich meine App auf einigen Motorola-Geräten mit 1.5 versuchte.

Ich habe das OrientationEventListener OK laufen und ich verwende Reflexion, wenn die Drehung als solche eingestellt, um zu sehen:

final int latchedOrientation = roundOrientation(mLastOrientation + 90); 

Parameters parameters = preview.camera.getParameters(); 

JPLog.d("Setting camera rotation = %d", latchedOrientation); 
try { 
    // if >= 2.0 
    Method method = Camera.Parameters.class.getMethod("setRotation", 
     int.class); 

    if(method != null) { 
     method.invoke(parameters, latchedOrientation); 
    } 

} catch(Throwable t) { 
    // if < 2.0 
    parameters.set("rotation", latchedOrientation); 
} 

preview.camera.setParameters(parameters); 

NexusOne (OS 2.2) - hervorragend. latchedOrientation = 0, Bild OK ohne Drehung im EXIF-Header.

T-Mobile G1 (OS 1.6) - Funktioniert auch gut. latchedOrientation = 0, Bild OK.

Motorola Backflip (OS 1.5) - Bild gedreht. latchedOrientation = 0, Bild hat keine EXIF-Rotation.

Motorola CLIQ (OS 1.5) - Bild gedreht. latchedOrientation = 0, Bild hat keine EXIF-Rotation.

Was ist mit diesen Motorola-Geräten los? Ich dachte, mein Problem sei, dass der Motorola-Kameratreiber die Bilder nicht rotierte, also fand ich die Sanselan EXIF-Leseklassen für Android und bereitete mich darauf vor, sie selbst zu drehen. Lustig ist, es gibt EXIF-Header, aber kein Rotationselement.

Wenn ich die Drehung manuell auf 90 Grad einstellen, kommen die Bilder perfekt aus den Motorola-Geräten, aber jetzt haben die G1 und NexusOne Bilder, die um 90 Grad gedreht sind (nicht was ich will). Es muss etwas geben, was ich nicht hier bekomme.

Ich bezweifle, dass dies ein Problem 1.5 ist, oder jemand hätte Informationen darüber geschrieben?

+0

Antwort hier http://stackoverflow.com/questions/14066038/why-image-captured-using-camera-intent-gets -roated-on-many-devices-in-android –

Antwort

9

Dies ist ein gerätespezifisches Problem, das hauptsächlich Motorola-Geräte betrifft. Die Google-Entwickler haben einen Aufruf in API 8 setDisplayOrientation um das Problem zu umgehen. Der Hauptfehler ist here abgelegt.

Für diejenigen, die nicht mehr als 8 API gehen, die beide gemeinsamen Lösungen sind:

Aufschalten OnDraw
Aufschalten OnDraw in einer Top-Level-Viewgroup und dreht die Leinwand um 90 Grad zum Ausgleich Drehung. Beachten Sie, dass hier ein Vorbehalt besteht, da Ihre Berührungsereignisse ebenfalls gedreht werden müssen.

Verwendung Querformat-Modus
Sperren Sie die Aktivität auf Querformat, aber Vermögenswerte ziehen, als ob sie im Portrait sind. Das bedeutet, dass Sie Ihr Layout erstellen und Ihre Bildelemente so drehen, dass sie aussehen, als ob Sie sich im Hochformat befinden, sodass die Ansicht normal aussieht. Dies macht es leider schwierig, das Menü zu verwenden, da das Menü horizontal geöffnet wird.

Ich habe auch Leute gesehen, die einen Animations-Controller verwenden, um die Ansicht zu drehen. Der Nachteil, den ich nicht überwinden konnte, ist, dass sich die gedrehte Ansicht nicht ausdehnt, um den Bildschirm zu füllen. Eine Beispielimplementierung finden Sie unter answer by Georg.

+0

Leider gibt es keinen guten Weg, es zu tun und es sieht aus wie ein Fehler in den Moto-Kamera-Treibern. –

0

Es sieht so aus, als ob der Vorschlag "Landschaftsmodus verwenden" das einzige ist, was wirklich funktioniert. Es scheint in Ordnung zu sein, dass dies entweder im Manifest oder über einen Aufruf an setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) in der Aktivität onCreate erfolgt.

4

Hier ist der Code, den ich beiActivityResult() in meiner Aktivität verwendet habe. Die zurückgegebene Absicht war, ein Bild vom Typ image/* auszuwählen. Funktioniert gut für mich!

Uri imageUri = intent.getData(); 
       String[] orientationColumn = {MediaStore.Images.Media.ORIENTATION}; 
       Cursor cur = managedQuery(imageUri, orientationColumn, null, null, null); 
       int orientation = -1; 
       if (cur != null && cur.moveToFirst()) { 
        orientation = cur.getInt(cur.getColumnIndex(orientationColumn[0])); 
       } 
       Matrix matrix = new Matrix(); 
       matrix.postRotate(orientation); 
+0

Ich muss das Bild in meiner App erfassen und die Parameter wie in Das Snippet, das ich in der Frage gepostet habe, wäre jedoch einfacher, wenn ich eine Absicht auslösen könnte, eine andere App für mich zu erstellen. –

+0

Sie können dies immer noch auf dem URI verwenden, in dem Ihre App Bilder speichert die Kamera. Dies ist nur Code, um ein Bild mit einem URI in die richtige Ausrichtung zu drehen. Egal wo es herkommt. – dbaugh

44

Ich hatte dieses Problem, und ich habe diese Methode verwendet, um das Bild zu erfassen. (Ohne eine eigene Kamera zu schaffen)

final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image)); 
startActivityForResult(intent, 0); 

und tat den Rest in onActivityResult (int requestCode, int Result, Intent-Daten) {}

Aber das Originalbild (tatsächliche SD-Karte Bild) war richtig und Bitmap wurde gedreht, als ich so geholt habe. Bitmap bmp = BitmapFactory.decodeStream (..

Die Lösung:

try { 
     File f = new File(SD_CARD_IMAGE_PATH); 
     ExifInterface exif = new ExifInterface(f.getPath()); 
     int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); 

     int angle = 0; 

     if (orientation == ExifInterface.ORIENTATION_ROTATE_90) { 
      angle = 90; 
     } 
     else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) { 
      angle = 180; 
     } 
     else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) { 
      angle = 270; 
     } 

     Matrix mat = new Matrix(); 
     mat.postRotate(angle); 

     Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f), null, null); 
     Bitmap correctBmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mat, true);     
    } 
    catch (IOException e) { 
     Log.w("TAG", "-- Error in setting image"); 
    } 
    catch(OutOfMemoryError oom) { 
     Log.w("TAG", "-- OOM Error in setting image"); 
    } 
+6

Tolle Lösung, ich habe es nur etwas verbessert, da es im Fall von 'angle = 0' nicht notwendig ist, es zu entschlüsseln und ein zweites Bitmap mit einer Drehung von 0 zu erzeugen. Dies sollte im Fall eines nicht betroffenen Gerätes geschehen , reduzieren Sie den Speicherverbrauch für diesen Prozess um 50%. – WarrenFaith

+0

Wie ein Charme :) –

+5

funktioniert nicht für mich :( –

Verwandte Themen