Android视图3d旋转大分辨率屏幕上的转换

时间:2014-12-30 11:31:48

标签: android matrix rotation transform resolution

我正在为android(api> 14)实现3D卡片翻转动画,并且存在大屏幕平板电脑(> 2048 dpi)的问题。在问题调查期间,我来到以下基本块:

尝试使用矩阵和相机的旋转Y转换一个视图(简单的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等小屏幕上运行......
  • 适用于角度&lt; 60和&gt; 120在大屏幕设备上运行时2048x1536,2560x1600 ......
  • 适用于任何设备上的任何角度,如果旋转不居中(矩阵前后翻译已注释掉)
  • 在大屏幕设备上运行时失败(图像消失),旋转居中,角度在60到120度之间。

请告诉我我做错了什么并建议一些解决方法......谢谢!!!

3 个答案:

答案 0 :(得分:7)

此问题是由用于计算转换的相机距离引起的。虽然Camera类本身并没有对该主题说太多,但 View.setCameraDistance() method(强调我的)的文档中有更好的解释:

  

设置沿Z轴的距离(与X / 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);

答案 1 :(得分:0)

您可以在第一行[{3}}

中实现这一行,而不是使用12行来创建旋转矩阵

根据您想要的效果,您可能希望将图像居中放置到要旋转的轴上。 http://en.wikipedia.org/wiki/Rotation_matrix

对于图像消失,我猜它与内存(内存不足 - 虽然这会带来异常)或舍入问题有关。也许你可以尝试提高精度以达到双精度?

我想到的一点是,当alpha转向PI / 2时,cos(alpha)会变为0。除此之外,我没有看到角度之间的任何相关性以及为什么它对大图像无效。

答案 2 :(得分:0)

您需要调整翻译坐标。在计算图像的平移时,您还需要考虑图像尺寸。执行矩阵计算时,请为android:scaleType="matrix"设置ImageView。默认情况下,这会使您的图像在左上角对齐。然后,当您应用翻译前/后,您的图片可能会偏离ImageView的范围(特别是如果ImageView相对较大并且您的图像相对较小,例如在beeg屏幕的情况下片)。

以下平移会导致图像围绕其中心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();