2017-07-01 55 views
1

我已經的Android Camera2 pcitures出現旋轉,畫廊

但是,當一個應用程序,它拍攝照片,使用Google Camera2 sample,一切正常,我可以把圖片,它們將被保存(肖像,風景或自拍)等。我打開手機(三星S7)圖庫,然後將所有自拍和人像圖片旋轉90度。風景圖片雖然很好。我看過很多關於如何以正確的方向讀取圖片的帖子,但是如何正確保存它們呢?

我有我自己的畫廊在我的應用程序和那裏圖片加載正確(使用滑翔)沒有任何特殊的旋轉修復,所以我不知道我做錯了什麼,最重要的是,我該如何解決這個問題?

+0

將其中一個圖像從設備上拉出來,並使用'exiftool'或其他東西進行檢查。或者,將一些使用'ExifInterface'的'com.android.support:exifinterface'版本的代碼一起扔掉。無論哪種情況,您都在查看是否存在具有期望值的定位EXIF標籤。如果存在,那麼問題不在於保存圖像,而是您正在使用的圖庫應用程序中的錯誤。歡迎嘗試在保存之前手動旋轉圖像(並刪除方向標記),但可能沒有足夠的堆空間來執行此操作。 – CommonsWare

+0

如果OTOH,該標籤丟失,那麼在保存圖像的方式上可能存在錯誤,這需要[mcve]。 – CommonsWare

+0

我在其中一個selfies上運行exiftool,並獲得了一個方向標籤:「旋轉270 CW」。所以我猜畫廊有問題嗎? – barouf

回答

0

圖像查看器應該檢查EXIF標籤並根據方向標籤旋轉圖像。這允許相機應用程序和類似軟件以任何方向保存圖像,而不必在保存圖像之前旋轉圖像。

圖書館一樣滑翔和畢加索會爲你做這個,如果你給他們訪問完整的JPEG(例如,fileUricontentUrihttps URL)。這是因爲他們可以訪問EXIF標記得到的ImageView,因此他們可以告訴ImageView旋轉圖像。

然而,並非每個人都使用這樣的庫。 ImageView自己處理諸如Bitmap之類的東西,其中那些EXIF標籤在解碼過程中已經丟失。

你,作爲一個攝像頭應用程序的作者,這裏有兩個主要的選項:

  1. 你可以檢查EXIF標籤,看到的圖像需要旋轉,自己旋轉它,並保存旋轉的圖像(刪除方向標籤,但安排保留其他)。但是,這可能會失敗,特別是對於攝像機圖像,因爲這些圖像往往很大。

  2. 你可能聳聳肩,繼續前進,因爲這不是你的問題。正如你注意到的,其他圖庫應用程序不會出現問題,因爲它們已經過充分測試,並且您嘗試的原始圖庫應用程序沒有。

如果使用選項#1,如果您獲得OutOfMemoryError,它會變成選項#2。

+0

我想提一提的是,即使使用選項1,看起來這種情況也不同於手機,因爲製造商似乎以不同的方式保存圖像。我想我會聳聳肩當然。謝謝你的幫助! – barouf

+0

@barouf:「這看起來不同於手機,因爲製造商似乎以不同的方式保存圖像」 - 哦,絕對。從我所看到的,我的猜測是,它與其他任何東西都與相機芯片組相關聯。有些會爲你旋轉圖像。其他人只需設置EXIF標籤。一些將會是越野車,並且都不會,並且你試圖或許使用傳感器來確定當時如何保持該裝置。 – CommonsWare

+0

與選項1一起使用,您不一定需要檢查EXIF。您的應用程序控制捕捉,您可以訪問方向傳感器,有時這可能會有所幫助。 –

1

您是否在您的靜止捕捉請求中使用了JPEG_ORIENTATION控件?如果沒有,那可能是問題 - 該控件告訴相機設備如何將最終的JPEG圖像旋轉爲正面朝上。

因此,您需要更新該控件中的值以描述圖像傳感器當前相對於世界的排列方式。

要做到這一點計算,你需要從加速度計輸入(它告訴你哪個方向是向下),然後是一些基本的數學 - 從上面的鏈接複製此:

private int getJpegOrientation(CameraCharacteristics c, int deviceOrientation) { 
    if (deviceOrientation == android.view.OrientationEventListener.ORIENTATION_UNKNOWN) return 0; 
    int sensorOrientation = c.get(CameraCharacteristics.SENSOR_ORIENTATION); 

    // Round device orientation to a multiple of 90 
    deviceOrientation = (deviceOrientation + 45)/90 * 90; 

    // Reverse device orientation for front-facing cameras 
    boolean facingFront = c.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT; 
    if (facingFront) deviceOrientation = -deviceOrientation; 

    // Calculate desired JPEG orientation relative to camera orientation to make 
    // the image upright relative to the device orientation 
    int jpegOrientation = (sensorOrientation + deviceOrientation + 360) % 360; 

    return jpegOrientation; 
} 

其中輸入deviceOrientation來自傳感器API。