前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java:图像(BufferedImage)色彩空间转换(灰度)暨获取图像矩阵数据byte[](sRGB/gray)

java:图像(BufferedImage)色彩空间转换(灰度)暨获取图像矩阵数据byte[](sRGB/gray)

作者头像
10km
发布2019-05-25 22:02:42
2.3K0
发布2019-05-25 22:02:42
举报
文章被收录于专栏:10km的专栏10km的专栏

版权声明:本文为博主原创文章,转载请注明源地址。 https://cloud.tencent.com/developer/article/1433579

ColorConvertOp

java.awt.image包下面有个类java.awt.image.ColorConvertOp,类名直译就是”颜色转换操作”。

顾名思义,它的作用就是将一个色彩空间(color space)的图像转换为另一个色彩空间的图像。有了这个神器我们就能轻易的将一张彩色图你像转换成灰度(gray)或其他色彩空间图像。

代码非常简单,只要一行。

代码语言:javascript
复制
    public BufferedImage toGray(BufferedImage srcImg){      
        return new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null).filter(srcImg, null);
    }

依此类推,你可以参照ColorConvertOp的参数说明将图像转为其他格式。

java.awt.color.ColorSpace中列出了很多支持的色彩空间定义TYPE_RGB,TYPE_CMYK,TYPE_HSV,TYPE_YCbCr….

Raster.getDataElements

有时我们通过ImageIO得到解码后的图像数据对象(BufferedImage)以后,需要获取图像矩阵的裸数据(即一个存储图像数据的byte数组)。

BufferedImage中提供了一个getRGB()方法,它返回的是一个ARGB格式int[]数组(每个int型元素的4个字节分别代表一个像素的Alpha,Red,Green,Blue四个通道)

如果你要从这个方法获取RGB的数组,你还得自己写转换代码:

代码语言:javascript
复制
    /**
     * 返回图像的RGB格式字节数组
     * @param image
     * @return
     */
    public static byte[] getMatrixRGB(BufferedImage image){
        int w = image.getWidth();
        int h = image.getHeight();
        int[] intArray = new int[w * h];
        byte[] matrixRGB = new byte[w * h * 3];
        image.getRGB(0, 0, w, h, intArray, 0, w);
        // ARGB->RGB
        for(int i=0,b=0;i<intArray.length;++i){
            matrixRGB[b++]=(byte) (matrixRGB[i]&0x000000FF);
            matrixRGB[b++]=(byte) ((matrixRGB[i]&0x0000FF00)>>8);
            matrixRGB[b++]=(byte) ((matrixRGB[i]&0x00FF0000)>>16);
        }
        return matrixRGB;
    }

好烦呐,我以前就是这么干的,真的没有提供更好的方法吗?

不是没有更好的方法,而是我学艺不精没找到而已。

在仔细研究了BufferedImage的代码之后,才明白getRGB()只是BufferedImage为默认 RGB 颜色模型 (TYPE_INT_ARGB)提供的一个便利性封装。

通过getRGB()源码可以知道BufferedImage对象中真正的图像数据是由成员对象raster(java.awt.image.WritableRaster)管理。而WritableRasterjava.awt.image.Raster的子类。Raster中getDataElements方法可以我们所需要的字节数组。

还以前面图像转灰度举例,如果要从灰度图像中获取图像矩阵的字节数组,代码示例如下:

代码语言:javascript
复制
    /**
     * 获取灰度图像的字节数组
     * @param image
     * @return
     */
    public static byte[] getMatrixGray(BufferedImage image) {
            // 转灰度图像
            BufferedImage grayImage = new BufferedImage(width, height,  
                        BufferedImage.TYPE_BYTE_GRAY);      
            new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null).filter(image, grayImage);
            // getData方法返回BufferedImage的raster成员对象
            return (byte[]) grayImage.getData().getDataElements(0, 0, image.getWidth(), image.getHeight(), null);       
    }

注意这里return语句使用了(byte[])强制类型转换,因为getDataElements返回的是打开声明 java.lang.Object对象。

也就是说getDataElements返回的未必是byte[]类型,为什么呢?看下面getDataElements方法的说明:

看不懂没关系,我们可以看到这里的返回的类型可能是:TYPE_BYTE,TYPE_USHORT,TYPE_INT,TYPE_SHORT,TYPE_FLOAT,TYPE_DOUBLE。并不一定是byte。

那么问题来了,如何控制返回的数组类型是byte[]呢?

同样,我们可以使用前面的ColorConvertOp对象进行转换。

比如我们需要得到图像的RGB数据:

代码语言:javascript
复制
    /**
     * 获取图像RGB格式数据
     * @param image
     * @return
     */
    public static byte[] getMatrixRGB(BufferedImage image){
        if(image.getType()!=BufferedImage.TYPE_3BYTE_BGR){
            // 转sRGB格式
            BufferedImage rgbImage = new BufferedImage(
                        image.getWidth(), 
                        image.getHeight(),  
                        BufferedImage.TYPE_3BYTE_BGR);
            new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_sRGB), null).filter(image, rgbImage);
            // 从Raster对象中获取字节数组
            return (byte[]) rgbImage.getData().getDataElements(0, 0, rgbImage.getWidth(), rgbImage.getHeight(), null);
        }else{
            return (byte[]) image.getData().getDataElements(0, 0, image.getWidth(), image.getHeight(), null);
        }
    }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016年07月09日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ColorConvertOp
  • Raster.getDataElements
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档