2014-12-30 46 views
6

我正在實現android(api> 14)的3D卡片翻轉動畫,並遇到大屏幕平板電腦(> 2048 dpi)的問題。在問題調查期間,我已經到了以下基本塊:Android視圖在大分辨率屏幕上的3D旋轉轉換

嘗試使用矩陣和旋轉相機的矩陣和旋轉角度來轉換視圖(簡單的ImageView),並且它對角度< 60和角度> 120(轉換和顯示),但圖像消失(只是沒有顯示)時,角度爲60和120之間。這裏是我使用的代碼:

private void applyTransform(float degree) 
{ 
    float [] values = {1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}; 
    float centerX = image1.getMeasuredWidth()/2.0f; 
    float centerY = image1.getMeasuredHeight()/2.0f; 

    Matrix m = new Matrix(); 
    m.setValues(values); 

    Camera camera = new Camera(); 
    camera.save(); 

    camera.rotateY(degree); 
    camera.getMatrix(m); 

    camera.restore(); 

    m.preTranslate(-centerX, -centerY); // 1 draws fine without these 2 lines 
    m.postTranslate(centerX, centerY); // 2 

    image1.setImageMatrix(m); 
} 

這裏是我的佈局XML

<?xml version="1.0" encoding="utf-8"?> 
    <FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
    <ImageView 
     android:id="@+id/ImageView01" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:src="@drawable/naponer" 
     android:clickable="true" 
     android:scaleType="matrix"> 
    </ImageView> 
</FrameLayout> 

所以我有以下情況:

  • 如果在小屏幕800X480,1024x720,運行等工作正常的任何角度,任何中心點...
  • 工程確定爲角度< 60和大屏幕設備2048×1536運行時,> 120,2560×1600。 ..
  • 如果旋轉不居中,任何設備上的任何角度都可以正常工作(矩陣前後翻譯註釋掉)
  • 在大屏幕設備上運行時失敗(圖像消失),旋轉居中且角度介於60和120之間度。

請告訴我做錯了什麼,並建議一些解決方法...謝謝!

+0

如果您爲AndroidManifest.xml中的活動定義了android:hardwareAccelerated =「false」,問題是否消失? – samgak

+0

沒有效果,測試hardwareAccelerated啓用和禁用的情況下 – Henrik

+3

你試過玩相機的距離(例如'camera.setLocation(0,0,-20f)'? – matiash

回答

7

此問題是由用於計算轉換的相機距離造成的。雖然Camera類本身不說這個話題了,它更好地爲View.setCameraDistance() method(重點煤礦)的文件中解釋說:

設置的X沿Z軸的距離(垂直/ Y平面上 哪些視圖被繪製)從相機到這個視圖。相機的距離會影響3D變換,例如繞X軸和Y軸旋轉 。 (...)

攝像機與視平面之間的距離可能會影響視圖在圍繞x軸或y軸旋轉時的視角失真。例如,較大的距離將導致較大的視角,並且在視圖旋轉時不會有太多的視角失真 。如果旋轉視圖部分落後於 相機(這就是爲什麼建議使用至少爲 的距離,因此短距離可能導致更多的旋轉時的透視失真,,並且還可能導致一些 繪製僞影據該視圖的大小,如果視圖旋轉。)

說實話,我從來沒有見過這樣特別的效果(不繪製在所有),但我懷疑它可能是與我曾遇到過的this question related to perspective distortion有關。 :)

因此,解決方案是使用Camera.setLocation()方法來確保不會發生。

View.setCameraDistance()方法的一個重要區別是的單位不一樣,因爲setLocation()不使用像素。雖然setCameraDistance()調整密度,setLocation()不。因此,如果您想根據視圖的尺寸計算適當的z距離,請記住調整密度。例如:

float cameraDistance = Math.max(image1.getMeasuredHeight(), image1.getMeasuredWidth()) * 5; 
float densityDpi = getResources().getDisplayMetrics().densityDpi; 
camera.setLocation(0, 0, -cameraDistance/densityDpi); 
+0

偉大的解決方案...爲我工作...但我用更小的設備這種方法改變我的分辨率和相機角度...任何建議? –

0

而不是使用12線創建旋轉矩陣,你可以只實現這一個在第一線http://en.wikipedia.org/wiki/Rotation_matrix

取決於你想要的效果,你可能要居中圖像軸線要繞。 http://en.wikipedia.org/wiki/Transformation_matrix

對於圖像消失嗯,我猜想它與任何內存(內存不足 - 雖然這會帶來異常)或舍入問題有關。也許你可以嘗試提高精度來雙精度?

想到的一件事是,當alpha朝向PI/2時,cos(alpha)趨於0。除此之外,我沒有看到角度之間的任何關聯以及爲什麼它不適用於大圖像。

+0

確保矩陣計算可以優化到1-2行,但這對我來說不是至關重要的......現在的問題是在上面描述的範圍中應用最終矩陣後圖像消失,並且精度在這裏不起作用...如果它在PI/2度消失(就像在其他設備上那樣),我可以確定。似乎問題是有關範圍的部分圖像走出屏幕邊界,但我不明白爲什麼它必須消失? – Henrik

+0

每次精確到60度和120度都會消失嗎?還是有點隨意,有時在62歲,有時在58歲? – Jani

+0

另一件事前/後翻譯。你說它沒有這些線路的作品?問題可能是您在旋轉之前沒有對圖像進行居中。也許嘗試翻譯(中) - >旋轉 - >翻譯(後面)。 嘗試使用Camera.translate(x,y,z)http://developer.android.com/reference/android/graphics/Camera.html – Jani

0

您需要調整翻譯座標。在計算圖片的翻譯時,您還需要考慮圖片大小。當您執行矩陣計算時,您爲您的ImageView設置android:scaleType="matrix"。這會使您的圖像在默認情況下左上角對齊。然後,當您應用您的前/後翻譯時,您的圖片可能會從您的ImageView(特別是如果ImageView比較大並且圖像相對較小時(例如蜜蜂屏幕平板電腦的情況下))的邊界出現。

在圖像中以下翻譯結果繞其中心Y軸旋轉,並保持對齊左上角的圖像:

m.preTranslate(-imageWidth/2, 0); 
m.postTranslate(imageWidth/2, 0); 

以下圖像中的可替選結果圍繞其中心Y爲旋轉/ X軸系和圖象對齊到ImageView中心:

m.preTranslate(-imageWidth/2, -imageHeight/2); 
m.postTranslate(centerX, centerY); 

如果您的圖片,你可以使用固有寬度/高度的位圖:

Drawable drawable = image1.getDrawable(); 
imageHeight = drawable.getIntrinsicHeight(); 
imageWidth = drawable.getIntrinsicWidth(); 
+0

實際上我看不到這兩個中心點之間的任何區別...但是,測試您的建議和結果是完全相同的 - 圖像消失在同一範圍內... – Henrik

+0

你能提供你的活動佈局XML嗎?我使用簡單的佈局,包含單個'ImageView'拉伸以填充整個屏幕,它工作正常:) – stealth

+0

當然,將其添加到原始帖子...也用ImageView測試拉伸以填滿整個屏幕 - 沒有工作...我懷疑你沒有在高分辨率設備上測試> 2048x1536 – Henrik