【问题标题】:Drawing mirrored bitmaps in android在android中绘制镜像位图
【发布时间】:2011-12-17 00:55:26
【问题描述】:

我正在尝试学习如何在 android 中制作动画精灵,但不知道如何组织我的位图。我有一个我的角色向右走的精灵表:一个角色的五个副本的位图,等距(每 45 像素),在一个行走周期中。

我计划通过一次绘制精灵表位图的一小部分来绘制每一帧:

Rect sourceRect = new Rect(0, 0, 45, 75);
canvas.drawBitmap(spriteSheetBitmap, sourceRect, new Rect(0, 0, 45, 75), null);

然后对于下一帧,将“sourceRect.x”增加 45,然后重绘等等。

但是,我现在不确定如何让我的精灵向左移动。我最初以为我可以镜像我正在绘制的矩形以获得翻转的图片。比如:

sourceRect = new Rect(45, 0, 0, 75);

这似乎不起作用(不确定这里实际发生了什么,但没有任何东西被吸引到我的表面)。

在网上搜索,看来我应该复制我的原始位图,用变换矩阵对其进行镜像,然后在向左行走时使用该位图进行绘图。然而,我也发现了许多较小的位图对象从原始精灵表中创建、存储(并为镜像运动进行转换)然后根据需要使用的实现。

所以我想知道在这种情况下什么是最好的,或者是否真的有任何区别(性能/内存):

方法一:加载我原来的精灵表,创建一个新的位图实例,镜像它,然后计算所有的矩形并使用那些+两个完整的表来绘制(诚然有一些未使用精灵表的额外位图空间)。

方法 2: 加载到我的原始精灵表中,为每一帧创建一个新的两个位图对象(1 个镜像,1 个正常)并存储它们以供绘制。

方法3:其他更好的方法?

【问题讨论】:

    标签: android bitmap


    【解决方案1】:

    方法 2 太贵了,而且你不需要画布来翻转位图。只需创建另一个应用了 Matrix 的位图,如下所示:

    BitmapDrawable flip(BitmapDrawable d)
    {
        Matrix m = new Matrix();
        m.preScale(-1, 1);
        Bitmap src = d.getBitmap();
        Bitmap dst = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), m, false);
        dst.setDensity(DisplayMetrics.DENSITY_DEFAULT);
        return new BitmapDrawable(dst);
    }
    

    【讨论】:

    • 从你当时的说法来看,方法1似乎更好?最好保留 2 个“大”主位图实例,然后拥有多个位图实例:两个位图实例为 225 像素 x 75 像素,而十个位图实例为 45 像素 x 75 像素
    • 有很多小的位图实例,所以每帧要读取的数据更少。
    • 我用matrix.preScale(1, -1)修复了镜像效果。出于某种原因,matrix.preScale(-1, 1) 垂直镜像了图像。
    【解决方案2】:

    要镜像您的精灵,只需在画布上应用以下变换:scale(-1, 1)。您还必须将精灵偏移其宽度。

    【讨论】:

    • 我也确实考虑过这一点,对于这种特定情况,它可以工作,因为只有一个精灵。但是,如果我在画布上预先绘制了多个精灵,然后再绘制多个精灵,我想一切都会被翻转?
    • 只需使用 save()/restore() 应用/取消应用镜像效果。
    • +1 用于指出位图需要一个偏移量(它的宽度)!
    • @JaySoyer 因为当您在枢轴为 0 时按 -1 缩放时,您最右边的像素的 x 坐标将乘以 -1,因此它将是负数(它将是 -width)。这就是为什么您需要将所有像素移回 0 原点。这是通过将宽度添加到坐标来完成的。
    • 这绝对是要走的路。学习使用矩阵进行转换——它们在我所知道的每个平台上都使用,它们是 gpu 计算东西的方式。您不想为每个转换后的精灵创建位图。一般流程是这样的,您使用普通(通常是单位)矩阵进行绘制,然后当您想要旋转/翻转/缩放等精灵时,您应用一个新矩阵,绘制精灵,然后返回到之前的矩阵。需要说明的是:您之前绘制的元素不会受此影响。
    【解决方案3】:

    canvas 上绘制垂直镜像位图bmp

    Matrix m = new Matrix();
    // Mirror is basically a rotation
    m.setScale( -1 , 1 );
    // so you got to move your bitmap back to it's place. otherwise you will not see it
    m.postTranslate(canvas.getWidth(), 0);
    canvas.drawBitmap(bmp, m, p);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-10
      • 1970-01-01
      • 1970-01-01
      • 2011-05-08
      相关资源
      最近更新 更多