【问题标题】:Problem with draw bitmap on rotated canvas around X axis在围绕 X 轴旋转的画布上绘制位图的问题
【发布时间】:2011-08-04 15:42:34
【问题描述】:

早安,

我在绘制图像时遇到了奇怪的问题。代码和图片比文字更能说明问题。

mCamera.save();
mCamera.rotateX(rotateX);
mCamera.getMatrix(mMatrix);
mCamera.restore();

canvas.save();
canvas.setMatrix(mMatrix);

// here I draw images
...

canvas.restore();

结果如下图所示。第一张图片有角度 0,第二张大约 45 度,最后一张。这取决于我要绘制的区域大小(位图数量)。我注意到当我绘制完全适合画布边界的位图时,它工作正常。但问题主要是当我用类似的东西绘制图像时(所以部分在画布之外)

canvas.drawBitmap(image, -100, -100, null)

和图片(嗯,因为我是新来的,我不能直接发布图片......)

ttp://locus.asamm.cz/data/_temp/1311873666794.png

http://locus.asamm.cz/data/_temp/1311873695945.png

http://locus.asamm.cz/data/_temp/1311873782054.png

所以问题是,是否有任何可行的解决方案或至少有任何提示。另外,如果有经验的人可以判断使用 OpenGL 绘制是否可以帮助解决此问题,如果可以,请指出任何可以帮助我绘制变化很大的位图的信息源(它是地图应用程序,因此用户使用地图移动),因为我仍然找不到任何简单明了的信息来源。

非常感谢大家

【问题讨论】:

    标签: android canvas bitmap


    【解决方案1】:

    这是 2D 绘图 API 的限制。要制作真正的 3D,您应该使用 OpenGL。

    【讨论】:

    • 嗯,我担心我会收到这个答案。所以还有第二个问题。示例解决方案的任何提示可以帮助我更好地理解如何在 OpenGL 中显示动态加载的位图?我知道有很多教程,但每个教程都只展示如何显示已经预加载的位图或一些矢量。谢谢
    • 在一年多的另一个积极发展之后不得不接受这个答案。似乎普通的“画布”方式不足以完成这项任务,使用 OpenGL 是唯一的解决方案。感谢两位的帮助
    【解决方案2】:

    我希望你正在尝试产生一个谷歌地图倾斜/旋转效果,我已经成功地为谷歌地图完成了,因为他们认为我们不需要更新 ;-) 我需要它来用于我的应用程序,即使你是使用你自己的瓷砖基本上是一样的。

    有助于实现相机矩阵的旋转是在左上角执行的。

    因此,您应该转换到适当的位置(取决于旋转轴和您的预期结果)然后返回,类似于...在我阅读文档并弄清楚之前,您得到的效果与我的非常相似.

    camera.save();
        camera.rotateX(tilt);  // tilt forward or backward
        camera.rotateY(0);
        camera.rotateZ(angle); // Rotate around Z access (similar to canvas.rotate)                                 
    
         camera.getMatrix(cameraMatrix);
    
         // This moves the center of the view into the upper left corner (0,0) 
         // which is necessary because Matrix always uses 0,0, as it's transform point
         // use the center of the canvas, or the bottom center dependent on your results 
         cameraMatrix.preTranslate(-centerX, -centerY);
    
         // NOTE: Camera Rotations logically happen here when the canvas has the matrix applied  
         // This happens after the camera rotations are applied, moving the view back to 
         // where it belongs, allowing us to rotate around the center or any point we choose 
    
         // Move it back after the rotations are applied
         cameraMatrix.postTranslate(centerX, centerY);
    
    camera.restore();
    
    canvas.concat(cameraMatrix);
    

    要做的另一件事是加大容器的尺寸,以便在倾斜/旋转操作后没有空间(或至少限制它),您可以通过计算所需的超大尺寸、显示器的对角线来做到这一点适用于基本旋转,如果您使用它,则基于倾斜的百分比。

    使用 pre/postTranslate 可以给你一些有趣的结果。

    至于移动位图,我不确定你为什么要这样做,可能是平移,但只要画布被填满就没有关系

    更新

    这是我超大画布的方法,我尝试使用 LayoutParams 来执行此操作,但运气不佳,因此 Measure 是我的最佳选择。

    @Override 
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        if (!isInEditMode())
            super.onMeasure(View.MeasureSpec.makeMeasureSpec(scaledDimensionsW,
            View.MeasureSpec.EXACTLY),
            View.MeasureSpec.makeMeasureSpec(scaledDimensionsH,
            View.MeasureSpec.EXACTLY));
       else
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
    

    【讨论】:

    • 感谢您的回复。通过您的代码,我可以看到我所做的一切都是相同的(或几乎相同)。正如您在我的第一篇文章中的附加图片中看到的那样,我正在以正确的方式(围绕中心)旋转画布。也完成了超大尺寸。例如,当屏幕为 800x480 时,我将地图绘制区域设置为 2000x2000,并将有效转换应用于矩阵以将地图放置在正确的位置。即使这样,图像也非常相似......显示无效行。正如Romain所提到的,我将不得不使用一些OpenGL方法,但是经过半天的搜索,我仍然不知道如何将画布简单地更改为OpenGL
    • 嗯,它对我来说没问题,我对此没有真正的问题,我将倾斜度限制在 45 度,因为我不需要更多,但我已经上升到 60 作为测试,仍然没有问题。你如何超大画布?你也在做事前翻译吗?
    • 嗯该死的......是的,我使用的是完全相同的机制。但是在您使用 centerX, Y 的 preTranslate 的地方,我使用 preTranslate 来自定义定义的大小。这个大小也定义了绘制瓷砖的区域。嗯,但看起来它必须以某种方式工作。请问您是否直接更改画布的大小(如果可能的话)?因为我不是。我只是“对我的地图说”,画布大小是 2000x2000(即使它只有 480x800),我只是在“这个”(区域 2000x2000)上绘制。所以我 preTranslate(-1000, -1000) 和 postTranslate(240, 400)。当我只围绕 Z 旋转时,它工作得很好。 X 左右会引起麻烦。
    • 嗯很有趣!!必须尝试,我会告诉你。谢谢!!
    • Idistic,我的解决方案没有成功。完全相同的问题。我创建了示例和非常简单的应用程序 (dl.dropbox.com/u/8015949/Locus%20%28dev%29/RotateTest.zip),这要归功于 SeekBar,使用我的方法旋转一些矩形,在那里你可以简单地看到哪里出了问题。所以如果你有一点时间,看看它。也许你会看到我做错了什么。并且还想,我怎样才能回报你的时间:)。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    • 1970-01-01
    • 2017-06-30
    • 2022-01-24
    • 2015-02-24
    • 2017-07-11
    相关资源
    最近更新 更多