All Downloads are FREE. Search and download functionalities are using the official Maven repository.

thirdparty.mortennobel.ImageUtils Maven / Gradle / Ivy

There is a newer version: 4.2.0
Show newest version
/*
 * Copyright 2013, Morten Nobel-Joergensen
 *
 * License: The BSD 3-Clause License
 * http://opensource.org/licenses/BSD-3-Clause
 */
package thirdparty.mortennobel;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;

/**
 * @author Heinz Doerr
 * @author Morten Nobel-Joergensen
 */
public class ImageUtils {

   public static int nrChannels(BufferedImage img) {
      switch (img.getType()) {
         case BufferedImage.TYPE_3BYTE_BGR:
         case BufferedImage.TYPE_INT_BGR:
         case BufferedImage.TYPE_INT_RGB:
         case BufferedImage.TYPE_USHORT_555_RGB:
         case BufferedImage.TYPE_USHORT_565_RGB:
            return 3;
         case BufferedImage.TYPE_4BYTE_ABGR:
         case BufferedImage.TYPE_INT_ARGB:
         case BufferedImage.TYPE_CUSTOM:
         case BufferedImage.TYPE_4BYTE_ABGR_PRE:
         case BufferedImage.TYPE_INT_ARGB_PRE:
            return 4;
         case BufferedImage.TYPE_BYTE_GRAY:
         case BufferedImage.TYPE_USHORT_GRAY:
            return 1;
      }
      return 0;
   }

   /**
    * returns one row (height == 1) of byte packed image data in BGR or AGBR form
    */
   public static void getPixelsBGR(BufferedImage img, int y, int w, byte[] array, int[] temp) {
      final int x = 0;
      final int h = 1;

      assert array.length == temp.length * nrChannels(img);
      assert (temp.length == w);

      int imageType = img.getType();
      Raster raster;
      switch (imageType) {
         case BufferedImage.TYPE_3BYTE_BGR:
         case BufferedImage.TYPE_4BYTE_ABGR:
         case BufferedImage.TYPE_4BYTE_ABGR_PRE:
         case BufferedImage.TYPE_BYTE_GRAY:
            raster = img.getRaster();
            //int ttype= raster.getTransferType();
            raster.getDataElements(x, y, w, h, array);
            break;
         case BufferedImage.TYPE_INT_BGR:
            raster = img.getRaster();
            raster.getDataElements(x, y, w, h, temp);
            ints2bytes(temp, array, 0, 1, 2);  // bgr -->  bgr
            break;
         case BufferedImage.TYPE_INT_RGB:
            raster = img.getRaster();
            raster.getDataElements(x, y, w, h, temp);
            ints2bytes(temp, array, 2, 1, 0);  // rgb -->  bgr
            break;
         case BufferedImage.TYPE_INT_ARGB:
         case BufferedImage.TYPE_INT_ARGB_PRE:
            raster = img.getRaster();
            raster.getDataElements(x, y, w, h, temp);
            ints2bytes(temp, array, 2, 1, 0, 3);  // argb -->  abgr
            break;
         case BufferedImage.TYPE_CUSTOM: // TODO: works for my icon image loader, but else ???
            img.getRGB(x, y, w, h, temp, 0, w);
            ints2bytes(temp, array, 2, 1, 0, 3);  // argb -->  abgr
            break;
         default:
            img.getRGB(x, y, w, h, temp, 0, w);
            ints2bytes(temp, array, 2, 1, 0);  // rgb -->  bgr
            break;
      }
   }

   /**
    * converts and copies byte packed  BGR or ABGR into the img buffer,
    * the img type may vary (e.g. RGB or BGR, int or byte packed)
    * but the number of components (w/o alpha, w alpha, gray) must match
    * does not unmange the image for all (A)RGN and (A)BGR and gray imaged
    */
   public static void setBGRPixels(byte[] bgrPixels, BufferedImage img, int x, int y, int w, int h) {
      int imageType = img.getType();
      WritableRaster raster = img.getRaster();
      //int ttype= raster.getTransferType();
      if (imageType == BufferedImage.TYPE_3BYTE_BGR ||
         imageType == BufferedImage.TYPE_4BYTE_ABGR ||
         imageType == BufferedImage.TYPE_4BYTE_ABGR_PRE ||
         imageType == BufferedImage.TYPE_BYTE_GRAY) {
         raster.setDataElements(x, y, w, h, bgrPixels);
      } else {
         int[] pixels;
         if (imageType == BufferedImage.TYPE_INT_BGR) {
            pixels = bytes2int(bgrPixels, 2, 1, 0);  // bgr -->  bgr
         } else if (imageType == BufferedImage.TYPE_INT_ARGB ||
            imageType == BufferedImage.TYPE_INT_ARGB_PRE) {
            pixels = bytes2int(bgrPixels, 3, 0, 1, 2);  // abgr -->  argb
         } else {
            pixels = bytes2int(bgrPixels, 0, 1, 2);  // bgr -->  rgb
         }
         if (w == 0 || h == 0) {
            return;
         } else if (pixels.length < w * h) {
            throw new IllegalArgumentException("pixels array must have a length" + " >= w*h");
         }
         if (imageType == BufferedImage.TYPE_INT_ARGB ||
            imageType == BufferedImage.TYPE_INT_RGB ||
            imageType == BufferedImage.TYPE_INT_ARGB_PRE ||
            imageType == BufferedImage.TYPE_INT_BGR) {
            raster.setDataElements(x, y, w, h, pixels);
         } else {
            // Unmanages the image
            img.setRGB(x, y, w, h, pixels, 0, w);
         }
      }
   }

   public static void ints2bytes(int[] in, byte[] out, int index1, int index2, int index3) {
      for (int i = 0; i < in.length; i++) {
         int index = i * 3;
         int value = in[i];
         out[index + index1] = (byte) value;
         value = value >> 8;
         out[index + index2] = (byte) value;
         value = value >> 8;
         out[index + index3] = (byte) value;
      }
   }

   public static void ints2bytes(int[] in, byte[] out, int index1, int index2, int index3, int index4) {
      for (int i = 0; i < in.length; i++) {
         int index = i * 4;
         int value = in[i];
         out[index + index1] = (byte) value;
         value = value >> 8;
         out[index + index2] = (byte) value;
         value = value >> 8;
         out[index + index3] = (byte) value;
         value = value >> 8;
         out[index + index4] = (byte) value;
      }
   }

   public static int[] bytes2int(byte[] in, int index1, int index2, int index3) {
      int[] out = new int[in.length / 3];
      for (int i = 0; i < out.length; i++) {
         int index = i * 3;
         int b1 = (in[index + index1] & 0xff) << 16;
         int b2 = (in[index + index2] & 0xff) << 8;
         int b3 = in[index + index3] & 0xff;
         out[i] = b1 | b2 | b3;
      }
      return out;
   }

   public static int[] bytes2int(byte[] in, int index1, int index2, int index3, int index4) {
      int[] out = new int[in.length / 4];
      for (int i = 0; i < out.length; i++) {
         int index = i * 4;
         int b1 = (in[index + index1] & 0xff) << 24;
         int b2 = (in[index + index2] & 0xff) << 16;
         int b3 = (in[index + index3] & 0xff) << 8;
         int b4 = in[index + index4] & 0xff;
         out[i] = b1 | b2 | b3 | b4;
      }
      return out;
   }

   public static BufferedImage convert(BufferedImage src, int bufImgType) {
      BufferedImage img = new BufferedImage(src.getWidth(), src.getHeight(), bufImgType);
      Graphics2D g2d = img.createGraphics();
      g2d.drawImage(src, 0, 0, null);
      g2d.dispose();
      return img;
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy