首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用非ARGB颜色空间在Java BufferedImages中设置像素?

如何使用非ARGB颜色空间在Java BufferedImages中设置像素?
EN

Stack Overflow用户
提问于 2021-05-06 00:12:59
回答 1查看 118关注 0票数 0

我正在编写一个应用程序,它需要使用16位的"5-5-5“RGB颜色(也就是说,每种颜色5位,还有一点填充)。为了处理这些图像,我使用了AWT提供的BufferedImage类。BufferedImage类特别允许使用非RGB颜色空间,方法是采用ColorModel对象或预定义的图像类型常量--其中之一是我需要的5-5-5像素格式。

我的问题是: BufferedImage "setRGB()“方法在其描述中声明,所提供的颜色值”假定在默认的RGB颜色模型、TYPE_INT_ARGB和默认的sRGB颜色空间“(根据BufferedImage文档页)。没有其他方法似乎接受为不同颜色空间设计的值。

是否有一种直接使用BufferedImage的非标准颜色空间的方法,或者我是否必须依赖类的内部颜色转换机制来处理所有的颜色?(还是我只是误读/误解了类的工作方式?)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-06 12:43:41

BufferedImage.TYPE_USHORT_555_RGB仍然使用一个完全标准的RGB颜色空间(实际上,它使用的是sRGB),所以我不认为您要寻找的是不同的颜色空间。

如果您想在Java中执行绘图或其他操作,只需使用常规的方法,如setRGB/getRGB()createGraphics()/Grapics2D。一切都将正确地转换为和从打包的USHORT_555_RGB格式为您。

例如:

代码语言:javascript
复制
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_USHORT_555_RGB);

// Do some custom painting
Graphics2D g = image.createGraphics();
g.drawImage(otherImage, 0, 0, null); // image type here does not matter
g.setColor(Color.ORANGE);            // Color in sRGB, but does not matter
g.fillOval(0, 0, w, h);
g.dispose();

image.setRGB(0, h/2, w, 1, new int[w]); // Silly way to create a horizontal black line at the center of the image... Don't do this, use fillRect(0, h/2, 1, w)! ;-)  

// image will still be USHORT_555_RGB *internally*

但是,如果您有USHORT_555_RGB格式的像素数据(即。在外部库/api/service中,将这些值直接设置到光栅/数据库可能更快、更准确。或者,如果需要将像素值传递回同一个库/api/service。

例如,使用Raster

代码语言:javascript
复制
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_USHORT_555_RGB);

// Some fictional API. It's assumed that data.length == w * h
short[] apiPixels = api.getPixelsUSHORT_555_RGB(w, h);

WritableRaster raster = image.getRaster();

// Set short values to image
raster.setDataElements(0, 0, w, h, apiPixels);
        
// Get short values from image
short[] pixels = (short[]) raster.getDataElements(0, 0, w, h, null); // TYPE_USHORT_555_RGB -> always short[]
api.setPixels(pixels, w, h); // Another fictional API

或者,或者使用DataBuffer

代码语言:javascript
复制
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_USHORT_555_RGB);

// Some fictional API. It's assumed that data.length == w * h
short[] apiPixels = api.getPixelsUSHORT_555_RGB(w, h);

DataBufferUShort buffer = (DataBufferUShort) image.getRaster().getDataBuffer(); // TYPE_USHORT_555_RGB -> always DataBufferUShort

// Set short values to image
System.arraycopy(apiPixels, 0, buffer.getData(), 0, apiPixels.length);

// Get short values from image
api.setPixels(buffer.getData(), w, h);

在大多数情况下,使用哪种方法并不重要,但是第一种方法(仅使用Raster )可能会保持图像管理,这将使图像在屏幕上显示得更快。

PS:如果你真正需要的是不同的颜色空间。外部库/api/service中的像素数组使用不同的颜色空间,您需要查看这个颜色空间中的像素),您可以创建一个具有如下自定义颜色空间的USHORT_555_RGB样式的USHORT_555_RGB

代码语言:javascript
复制
// Either use one of the built-in color spaces, or load one from disk
ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
ColorSpace colorSpaceToo = new ICC_ColorSpace(ICC_Profile.getInstance(Files.newInputStream(new File("/path/to/custom_rgb_profile.icc").toPath())));

// Create a color model using your color space, TYPE_USHORT and 5/5/5 mask, no transparency
ColorModel colorModel = new DirectColorModel(colorSpace, 15, 0x7C00, 0x03E0, 0x001F, 0, false, DataBuffer.TYPE_USHORT);

// And finally, create an image from the color model and a compatible raster
BufferedImage imageToo = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(w, h), colorModel.isAlphaPremultiplied(), null);

请记住,由于Java2D图形操作和setRGB/getRGB仍然在使用sRGB,现在图像上的所有操作都将在颜色空间和sRGB之间来回转换。表现就不会那么好了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67410298

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档