Java: 自定义 BufferedImage / 多于 RGBA
Java: Custom BufferedImage / More than RGBA
我不仅要在图像中保存红色、绿色、蓝色和 Alpha。
每个像素还需要 Z-Depth 信息,比如它离相机有多远。
此外,我需要在 JFrame 中显示图像,因此我不能使用我的自定义图像 class,而是我需要一个 BufferedImage 或其子 class。
Z-Depth 不应在 JFrame 中可见。我只是想收藏一下。
我已经阅读了很多关于 BufferedImage 的文章 class。
我假设我将不得不扩展 classes,例如 SampleModel 或 ColorModel,但我不知道应该如何完成。
一个不错的解决方案是实例化一个新的 BufferedImage,但使用也存储深度的自定义 Pixelclass,而不实际扩展 BufferedImage。
但任何解决方案和任何想法都将不胜感激!
有人知道,为了在每个像素中保存更多信息,我必须扩展哪些 classes 吗?
我相信您正在寻找允许您定义 3D 像素阵列的 ImageComponent3D。
ImageComponent3D(int format, int width, int height, int depth)
Constructs an 3D image component object using the specified format, width, height and depth.
嗯,我仍然不明白为什么在这种情况下将额外的数据放入 BufferedImage
会更多 "flexible and extensible",所以我可能会自己做这样的事情:
public class DeepImage {
private final BufferedImage image;
private final float[] zIndex; // Must be image.width * image.height long
// TODO: Constructors and accessors as needed...
}
当然,如果您真的喜欢,您可以将 Z 深度放入 BufferedImage
:
public class DeepBufferedImage extends BufferedImage {
private final float[] zIndex;
public DeepImage(final BufferedImage image, final float[] zIndex) {
super(image.getColorModel(), image.getRaster(), image.getColorModel().isAlphaPremultiplied(), null);
if (zIndex.length != image.getWidth() * image.getHeight()) {
throw new IllegalArgumentException("bad zIndex length");
}
this.zIndex = zIndex; // Obviously not safe, but we'll go for performance here
}
public float getZ(int x, int y) {...};
public void setZ(int x, int y, float z) {...};
public float[] getZ(int x, int y, int w, int h) {...};
public void setZ(int x, int y, int w, int h, float[] z) {...};
}
上面的 class 在所有情况下都像普通的 BufferedImage
一样工作,除了它还恰好有每个像素的 Z 索引。
或者,您可以将 Z-index 设为 DataBuffer
/SampleModel
/Raster
的一部分,但我认为这也需要自定义 ColorModel
(或 ColorSpace
),并且需要相当大的努力。这些 classes 通常不适用于 "mixed" 数据类型。当然,您可以将所有样本打包成一个 long
每个像素,以避免混合数据类型:
long rgbaz = getRGB(x, y) << 32l | Float.toIntBits(getZ(x, y));
但是,这显然会降低性能。
所以,简而言之,我只是看不到这样做有什么好处。特别是因为除了 RGBA 值之外你不想可视化任何东西,而且我也没有任何文件格式可以支持这样的像素布局*。
综上所述,您可能仍有实施此功能的理由,只是考虑到目前提到的要求,我认为没有必要这样做。当然可能是我遗漏了一些重要的东西。 :-)
*) TIFF 格式将支持存储它,如果您对所有 5 个(R、G、B、A、Z)通道使用 float
个样本,或者打包 long
( 64 位)样本。但是,我认为只存储一个普通的 32 位 (8,8,8,8) RGBA 图像,然后存储一个单独的 1 通道 float
图像会简单得多(并且更兼容)在多页 TIFF 中。
我不仅要在图像中保存红色、绿色、蓝色和 Alpha。 每个像素还需要 Z-Depth 信息,比如它离相机有多远。 此外,我需要在 JFrame 中显示图像,因此我不能使用我的自定义图像 class,而是我需要一个 BufferedImage 或其子 class。 Z-Depth 不应在 JFrame 中可见。我只是想收藏一下。
我已经阅读了很多关于 BufferedImage 的文章 class。 我假设我将不得不扩展 classes,例如 SampleModel 或 ColorModel,但我不知道应该如何完成。 一个不错的解决方案是实例化一个新的 BufferedImage,但使用也存储深度的自定义 Pixelclass,而不实际扩展 BufferedImage。 但任何解决方案和任何想法都将不胜感激!
有人知道,为了在每个像素中保存更多信息,我必须扩展哪些 classes 吗?
我相信您正在寻找允许您定义 3D 像素阵列的 ImageComponent3D。
ImageComponent3D(int format, int width, int height, int depth) Constructs an 3D image component object using the specified format, width, height and depth.
嗯,我仍然不明白为什么在这种情况下将额外的数据放入 BufferedImage
会更多 "flexible and extensible",所以我可能会自己做这样的事情:
public class DeepImage {
private final BufferedImage image;
private final float[] zIndex; // Must be image.width * image.height long
// TODO: Constructors and accessors as needed...
}
当然,如果您真的喜欢,您可以将 Z 深度放入 BufferedImage
:
public class DeepBufferedImage extends BufferedImage {
private final float[] zIndex;
public DeepImage(final BufferedImage image, final float[] zIndex) {
super(image.getColorModel(), image.getRaster(), image.getColorModel().isAlphaPremultiplied(), null);
if (zIndex.length != image.getWidth() * image.getHeight()) {
throw new IllegalArgumentException("bad zIndex length");
}
this.zIndex = zIndex; // Obviously not safe, but we'll go for performance here
}
public float getZ(int x, int y) {...};
public void setZ(int x, int y, float z) {...};
public float[] getZ(int x, int y, int w, int h) {...};
public void setZ(int x, int y, int w, int h, float[] z) {...};
}
上面的 class 在所有情况下都像普通的 BufferedImage
一样工作,除了它还恰好有每个像素的 Z 索引。
或者,您可以将 Z-index 设为 DataBuffer
/SampleModel
/Raster
的一部分,但我认为这也需要自定义 ColorModel
(或 ColorSpace
),并且需要相当大的努力。这些 classes 通常不适用于 "mixed" 数据类型。当然,您可以将所有样本打包成一个 long
每个像素,以避免混合数据类型:
long rgbaz = getRGB(x, y) << 32l | Float.toIntBits(getZ(x, y));
但是,这显然会降低性能。
所以,简而言之,我只是看不到这样做有什么好处。特别是因为除了 RGBA 值之外你不想可视化任何东西,而且我也没有任何文件格式可以支持这样的像素布局*。
综上所述,您可能仍有实施此功能的理由,只是考虑到目前提到的要求,我认为没有必要这样做。当然可能是我遗漏了一些重要的东西。 :-)
*) TIFF 格式将支持存储它,如果您对所有 5 个(R、G、B、A、Z)通道使用 float
个样本,或者打包 long
( 64 位)样本。但是,我认为只存储一个普通的 32 位 (8,8,8,8) RGBA 图像,然后存储一个单独的 1 通道 float
图像会简单得多(并且更兼容)在多页 TIFF 中。