java:BufferedImage判断图像通道顺序并转RGB/BGR

一般来说java ImageIO处理读取图像时,一般是RGB或ARGB格式,但是有的时候,我们需要图像是BGR格式,

比如通过JNI将图像矩阵传递给动态库,动态库里用OpenCV来处理矩阵,而用OpenCV处理图像时默认通道顺序是BGR,这时就需要一个到BGR转换。

翻了好Java API好久,还真没发现有直接将RGB转BGR的方法,于是只好自己写一个,以下是代码片段,用于实现判断BufferedImage图像类型及通道顺序,并将BufferedImage转为RGB或BGR

    /**
     * @param image
     * @param bandOffset 用于判断通道顺序
     * @return
     */
    private static boolean equalBandOffsetWith3Byte(BufferedImage image,int[] bandOffset){
        if(image.getType()==BufferedImage.TYPE_3BYTE_BGR){
            if(image.getData().getSampleModel() instanceof ComponentSampleModel){
                ComponentSampleModel sampleModel = (ComponentSampleModel)image.getData().getSampleModel();
                if(Arrays.equals(sampleModel.getBandOffsets(), bandOffset)){
                    return true;
                }
            }
        }
        return false;       
    }
    /**
     * 判断图像是否为BGR格式
     * @return 
     */
    public static boolean isBGR3Byte(BufferedImage image){
        return equalBandOffsetWith3Byte(image,new int[]{0, 1, 2});
    }
    /**
     * 判断图像是否为RGB格式
     * @return 
     */
    public static boolean isRGB3Byte(BufferedImage image){
        return equalBandOffsetWith3Byte(image,new int[]{2, 1, 0});
    }
    /**
     * 对图像解码返回RGB格式矩阵数据
     * @param image
     * @return 
     */
    public static byte[] getMatrixRGB(BufferedImage image) {
        if(null==image)
            throw new NullPointerException();
        byte[] matrixRGB;
        if(isRGB3Byte(image)){
            matrixRGB= (byte[]) image.getData().getDataElements(0, 0, image.getWidth(), image.getHeight(), null);
        }else{
            // 转RGB格式
            BufferedImage rgbImage = new BufferedImage(image.getWidth(), image.getHeight(),  
                    BufferedImage.TYPE_3BYTE_BGR);
            new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_sRGB), null).filter(image, rgbImage);
            matrixRGB= (byte[]) rgbImage.getData().getDataElements(0, 0, image.getWidth(), image.getHeight(), null);
        } 
        return matrixRGB;
    }
    /**
     * 对图像解码返回BGR格式矩阵数据
     * @param image
     * @return
     */
    public static byte[] getMatrixBGR(BufferedImage image){
        if(null==image)
            throw new NullPointerException();
        byte[] matrixBGR;
        if(isBGR3Byte(image)){
            matrixBGR= (byte[]) image.getData().getDataElements(0, 0, image.getWidth(), image.getHeight(), null);
        }else{          
            // ARGB格式图像数据
            int intrgb[]=image.getRGB(0, 0, image.getWidth(), image.getHeight(), null, 0, image.getWidth());
            matrixBGR=new byte[image.getWidth() * image.getHeight()*3];
            // ARGB转BGR格式
            for(int i=0,j=0;i<intrgb.length;++i,j+=3){
                matrixBGR[j]=(byte) (intrgb[i]&0xff);
                matrixBGR[j+1]=(byte) ((intrgb[i]>>8)&0xff);
                matrixBGR[j+2]=(byte) ((intrgb[i]>>16)&0xff);
            }
        } 
        return matrixBGR;
    }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏WOLFRAM

Mathematica 之微分特征系统

1306
来自专栏蜉蝣禅修之道

LeetCode之Climbing Stairs与斐波那契数列的联想

1324
来自专栏数据结构与算法

LOJ#137. 最小瓶颈路 加强版(Kruskal重构树 rmq求LCA)

853
来自专栏Jack的Android之旅

高仿QQ运动的周报界面

这次高仿的是QQ运动的周报界面的网图。这个控件刚开始的时候以为代码量不大,没想到一路下来界面代码在加上动画代码还是蛮多的。好了老规矩先上图:

914
来自专栏hightopo

纯Shading Language绘制飞机火焰效果

1736
来自专栏linux驱动个人学习

NC和NO、耳机美标和欧标的区别

NO是常开(NORMAL OPEN),就是通常即未通电状态下,是断开的,通电后在电磁线圈的作用下(吸合)处于闭合状态。NC是常闭(NORMAL CLOSE),就...

3336
来自专栏数据小魔方

Xcelsius(水晶易表)系列2——单值部件

今天专门跟大家分享水晶易表中的一大类部件——单值部件。 单值部件使用频率很高,从它的名称就能猜个大概,它是用来表达单个指标的图表部件。 水晶易表中的单值部件大体...

2495
来自专栏鸿的学习笔记

写给开发者的机器学习指南(十一)

Using unsupervised learning to mergefeatures (PCA)

512
来自专栏PPV课数据科学社区

用python对汽车油耗进行数据分析(anaconda python3.6完全跑通)

编者按:前两天我们微信发了一篇文章《用python对汽车油耗进行数据分析》,有一网友学习后用python3.6重新跑了一下数据,请大家比较阅读。PPV课致力于为...

2786
来自专栏深度学习入门与实践

【深度学习系列】用PaddlePaddle进行车牌识别(一)

小伙伴们,终于到了实战部分了!今天给大家带来的项目是用PaddlePaddle进行车牌识别。车牌识别其实属于比较常见的图像识别的项目了,目前也属于比较成熟的应...

50110

扫码关注云+社区