java에서 BufferedImage를 사용하여 이미지 채널 순서를 판단하고 RGB/BGR을 전환하는 방법

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;
  }
읽어주셔서 감사합니다. 여러분에게 도움이 되었으면 좋겠습니다. 본 사이트에 대한 지지에 감사드립니다!

좋은 웹페이지 즐겨찾기