[英]How to display HDR picture in Android?
I'm doing an android app to decompress, decode and display HDR pictures.我正在做一个 android 应用程序来解压缩、解码和显示 HDR 图片。
These HDR pictures use 2 bytes per component (A,R,G,B) so one pixel is represented by a 8 bytes value that can only fit with the long type.这些 HDR 图片的每个组件(A、R、G、B)使用 2 个字节,因此一个像素由 8 个字节的值表示,该值只能适合 long 类型。
I'm using android's Bitmap to display picture as they have a constructor allowing to do HDR by using Bitmap.Config.RGBA_F16
:我正在使用 android 的 Bitmap 来显示图片,因为它们有一个构造函数,允许使用
Bitmap.Config.RGBA_F16
进行 HDR:
int width = 1;
int height = 1;
Bitmap image = Bitmap.createBitmap(width, height, Bitmap.Config.RGBA_F16);
Unfortunately I can't find any way to fill a pixel of the Bitmap.不幸的是,我找不到任何方法来填充位图的像素。 I use the recommended formula but it cannot be used in the setPixel(x,y,color) method of Bitmap because color has to be a int:
我使用了推荐的公式,但它不能用在 Bitmap 的 setPixel(x,y,color) 方法中,因为颜色必须是一个整数:
long color = (A & 0xffff) << 48 | (B & 0xffff) << 32 | (G & 0xffff) << 16 | (R & 0xffff);
image.setPixel(0,0,color); //Argument type error
. .
I have also tried with Color ( which has a HDR compatible method ), Paint and Canvas but no Bitmap method accepts them to set only one pixel.我也尝试过使用 Color( 它具有 HDR 兼容方法)、Paint 和 Canvas,但没有 Bitmap 方法接受它们只设置一个像素。
Thanks for any help!谢谢你的帮助!
If you need to open an HDR file, such as 16-bit png, and then display it, you can use ImageDecoder.setTargetColorSpace to create bitmap with format Bitmap.Config.RGBA_F16
like so:如果您需要打开一个 HDR 文件,例如 16 位 png,然后显示它,您可以使用 ImageDecoder.setTargetColorSpace 创建格式为
Bitmap.Config.RGBA_F16
位图, Bitmap.Config.RGBA_F16
所示:
File file = new File(...);
ImageDecoder.Source source = ImageDecoder.createSource(file);
Drawable drawable = ImageDecoder.decodeDrawable(source, (decoder, info, src) -> {
decoder.setTargetColorSpace(ColorSpace.Named.EXTENDED_SRGB);
});
If you need to display HDR image that is stored in memory you can use Bitmap.copyPixelsFromBuffer
, as this method allows to set pixels of the bitmap without conversion of color space the way Bitmap.setPixel
does.如果您需要显示存储在内存中的 HDR 图像,您可以使用
Bitmap.copyPixelsFromBuffer
,因为此方法允许设置位图的像素,而无需像Bitmap.setPixel
那样转换颜色空间。 In this case you need to pack 4 channels represented byHalf
values into long for each pixel, then write these long values into a Buffer
and finally copy pixels from the buffer to the bitmap.在这种情况下,您需要将每个像素的
Half
值表示的 4 个通道打包为 long,然后将这些 long 值写入一个Buffer
,最后将像素从缓冲区复制到位图。
LongBuffer buffer = LongBuffer.allocate(width * height);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// fill pixels values as needed
float r = (float)y / height;
float g = (float)y / height;
float b = (float)y / height;
float a = 1f;
long rBits = Half.halfToShortBits(Half.toHalf(r));
long gBits = Half.halfToShortBits(Half.toHalf(g));
long bBits = Half.halfToShortBits(Half.toHalf(b));
long aBits = Half.halfToShortBits(Half.toHalf(a));
long color = aBits << 48 | bBits << 32 | gBits << 16 | rBits;
buffer.put(color);
}
}
buffer.rewind();
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGBA_F16);
bitmap.copyPixelsFromBuffer(buffer);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.