【问题标题】:Converting Android Bitmap to LibGdx's Texture将 Android 位图转换为 LibGdx 的纹理
【发布时间】:2013-02-02 12:56:09
【问题描述】:

我正在尝试通过转换将位图转换为 libGDX 纹理:

  1. Android Bitmapbyte[]
  2. byte[] 到 libGDX Pixmap
  3. libGDX Pixmap 到 libGDX Texture

我面临的问题是转换为纹理的位图正在从资产文件夹中的纹理打包器中绘制精灵表

public void onByteArrayOfCroppedImageReciever(byte[] bytes) {
    try {
        pmap=new Pixmap(bytes, 0, bytes.length);
        tex=new Texture(pmap);
        face=new Sprite(tex);
        // game.setScreen(new GameScreen(game, batcher, face));
    } catch(Exception e) {
        Gdx.app.log("KS", e.toString());
        e.printStackTrace();
    }
}

【问题讨论】:

  • 在像素图中看到错误的内容很奇怪。你确定你正在绘制你期望的像素图吗?尝试使用已知内容创建一个新的 Pixmap()(例如,使用“drawCircle”)并确保您看到您显示的像素图。此外,您当前使用的 Pixmap 构造函数需要 JPG/PNG/BMP 编码字节。您是如何从 Android 位图中获取字节的?

标签: android libgdx


【解决方案1】:

如果目标是将 Android 位图转换为 libgdx 纹理,则根本不需要使用 Pixmap。您可以在简单的 OpenGL 和 Android GLUtils 的帮助下直接完成。尝试以下方法;它比您的解决方案快 100 倍。我假设你不在渲染线程中(你不应该很可能)。如果是,则无需调用 postRunnable()。

       Gdx.app.postRunnable(new Runnable() {
        @Override
        public void run() {
          Texture tex = new Texture(bitmap.getWidth(), bitmap.getHeight(), Format.RGBA8888);
          GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tex.getTextureObjectHandle());
          GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
          GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
          bitmap.recycle();
          // now you have the texture to do whatever you want
        }
      });

【讨论】:

  • 非常感谢,兄弟会尝试一下,我以后肯定会需要它谢谢
  • Android 位图存储 alpha 预乘像素。您可以使用 batch.setBlendFunction(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA);绘制纹理然后对此进行补偿
  • 这太棒了。比使用像素图快得多。我想知道是否可以创建宽度/高度翻转的纹理,然后绑定旋转 90/270 度的位图?这是因为画廊中的许多图像的方向不正确,因为旋转存储在 Exif 数据中。我正在寻找一种快速的解决方案来旋转它们,而不需要典型的昂贵的矩阵变换。
【解决方案2】:

hmm 另一种可能性是您遇到了线程问题。我在 UI 线程上加载我自己的非托管纹理时注意到了这种问题,而 libgdx 在渲染线程上同时加载纹理。 如果这是问题,简单的解决方案是使用 Gdx.app.postRunnable 将纹理的创建与渲染线程同步。即:

public void onByteArrayOfCroppedImageReciever(byte[] bytes) {
    try {
        pmap=new Pixmap(bytes, 0, bytes.length);
        Gdx.app.postRunnable(new Runnable() {
            @Override
            public void run() {            
                tex=new Texture(pmap);
                face=new Sprite(tex);
            }
        });
    } catch(Exception e) {
        Gdx.app.log("KS", e.toString());
        e.printStackTrace();
    }
}

【讨论】:

【解决方案3】:

您必须在新线程上编写代码,因为 pixmap 类需要时间进行字节转换,并且有时会返回一个临时 pixmap,以防进程尚未完成,因此最好在单独的线程上运行,您的问题将得到解决。

【讨论】:

    【解决方案4】:

    您是否致力于该运营渠道?这是进行您要求的转换的另一种方法:

    1. 实现 com.badlogic.gdx.graphics.TextureData 以在构造函数中获取 android.graphics.Bitmap。
    2. 在 prepare() 中,使用 Bitmap.getPixels 分配和填充 IntBuffer。
    3. 使用位数学将缓冲区中的数据从 ARGB 交换为 RGBA:(arr[i] << 8) | (arr[i]>>24)
    4. 在 getType() 中返回 TextureData.TextureDataType.Compressed
    5. 在 consumeCompressedData() 中调用 glTexImage2D 将数据输入(预绑定)纹理。

    您上面的管道包括像素数据的多个副本和重新压缩;此管道允许您将位图数据直接输入到纹理中,只需一个副本(无论如何都是字节格式转换所必需的)。这对你有用吗?

    【讨论】:

    • 一定会试一试,如果这样做能解决我的目的,会告诉你
    猜你喜欢
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多