【问题标题】:ImageView not using alphachannel of bitmapImageView 不使用位图的 alphachannel
【发布时间】:2015-03-13 15:46:16
【问题描述】:

在将对象渲染到屏幕外以创建它的位图并将其显示在图像视图中时,我遇到了一点问题。它没有正确拍摄 Alpha 通道。

当我将位图保存为 png 并加载它时,它工作正常。但是当我直接将它加载到imageview中时,我会看到一个白色的背景,这是没有alpha通道的实际背景颜色。

这里是从我的 EGL Surface 导出位图的代码:

public Bitmap exportBitmap() {
    ByteBuffer buffer = ByteBuffer.allocateDirect(w*h*4);
    GLES20.glReadPixels(0, 0, w, h, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buffer);
    Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    bitmap.copyPixelsFromBuffer(buffer);
    Log.i("Render","Terminating");
    EGL14.eglMakeCurrent(oldDisplay, oldDrawSurface, oldReadSurface, oldCtx);
    EGL14.eglDestroySurface(eglDisplay, eglSurface);
    EGL14.eglDestroyContext(eglDisplay, eglCtx);
    EGL14.eglTerminate(eglDisplay);
    return bitmap;
}

这里是设置imageview的代码(r是包含前一个函数的类):

Bitmap bm;
bm = r.exportBitmap();
ImageView infoView = (ImageView)findViewById(R.id.part_icon);
infoView.setImageBitmap(bm);

我是否必须在 ImageView 上设置一些标志或在位图的配置中设置一些东西?

我将添加一些代码示例和图像来澄清问题: 首先是我希望它的工作方式:

bm = renderer.exportBitmap();

第二种工作方式,保存为 png 解决方法:

bm = renderer.exportBitmap();

//PNG To Bitmap
String path = Environment.getExternalStorageDirectory()+"/"+getName()+".png";
bm.compress(CompressFormat.PNG, 100, new FileOutputStream(new File(path)));
bm = BitmapFactory.decodeFile(path);

第三要澄清我的预乘。 Alpha 是考虑错误的方式:

        bm = renderer.exportBitmap();
        for(int x=bm.getWidth()-50; x<bm.getWidth(); x++) {
            for(int y=bm.getHeight()-50; y<bm.getHeight(); y++) {
                int px = bm.getPixel(x,y);
                bm.setPixel(x, y, 
                        Color.argb(255,
                        Color.red(px),
                        Color.green(px),
                        Color.blue(px)));
            }
        }  

抱歉,帖子太长了。

【问题讨论】:

  • 您是否查看了在glReadPixels 之后获得的原始字节?你能在那里看到正确的 alpha 值吗?此外,您是否为 EGL 上下文启用了 alpha 通道?当您从glReadPixels 接收 RGBA 数据但创建具有 ARGB 字节顺序的位图时,您确定字节顺序正确吗?
  • 我确实在 egl 配置中启用了 alpha 通道。对象的着色是正确的(实际测试的蓝色、红色、绿色)。另外,如果我通过 bm.compress(Bitmap.CompressFormat.PNG, 100, new FileOutputStream(new File(path))) 将位图保存为 png;它具有正确的颜色和 Alpha 通道。
  • 我刚刚检查过了。应该是半透明的白色值是 0。所以 (0,0,0,0)。这应该意味着这些值是预乘的。当我将 alphachannel 设置为 255 时,图像是黑色的。所以这似乎是一个 android 显示问题,因为它不会呈现实际的黑色值而是显示白色值。
  • 我想我还是没有完全理解这个问题。当您的值为 (0,0,0,0) 时,它们是完全半透明的,这意味着应该绘制图像“下方”的背景。如果此背景默认为白色(我不知道),则将呈现白色。当您将 Alpha 通道设置为 255 时,这意味着您将获得 (0,0,0,255) 个 RGBA 值,那么它应该是黑色的。
  • 这正是问题所在。值为 (0,0,0,0)。下面的颜色是一些灰度值,白色被图像绘制。所以 android 识别 alpha 通道,但不显示 imageview 下方的背景。再次。如果我将其保存并加载为 png 图像是半透明的。

标签: android opengl-es imageview alpha


【解决方案1】:

我更改了 exportBitmap() 函数。基本上我读取像素并再次写入它们。这是在解决问题。我真的不知道为什么。如果有人可以向我解释,那就太好了。为这些位图数据创建一个新的整数数组并不那么干净。

public Bitmap exportBitmap() {
    ByteBuffer buffer = ByteBuffer.allocateDirect(w*h*4);
    GLES20.glReadPixels(0, 0, w, h, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buffer);
    Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    bitmap.copyPixelsFromBuffer(buffer);

    //This is the modification
    int[] pixels = new int[w*h];
    bitmap.getPixels(pixels, 0, w,0, 0,w, h);
    bitmap.setPixels(pixels, 0, w,0, 0,w, h);

    EGL14.eglMakeCurrent(oldDisplay, oldDrawSurface, oldReadSurface, oldCtx);
    EGL14.eglDestroySurface(eglDisplay, eglSurface);
    EGL14.eglDestroyContext(eglDisplay, eglCtx);
    EGL14.eglTerminate(eglDisplay);
    return bitmap;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-28
    • 2015-07-29
    • 1970-01-01
    • 2015-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多