Ejemplo n.º 1
0
  /**
   * Color model filter
   *
   * @return
   */
  @Override

  // <editor-fold defaultstate="collapsed" desc=" UML Marker ">
  // #[regen=yes,id=DCE.07819BB3-27C8-FC3A-A682-6D76F6DFD44D]
  // </editor-fold>
  protected IndexColorModel filterColorModel(IndexColorModel model) {

    int n = model.getMapSize();
    byte[] red = new byte[n], gre = new byte[n], blu = new byte[n];
    model.getReds(red);
    model.getGreens(gre);
    model.getBlues(blu);
    int re, gr, bl;
    for (int i = 0; i < n; i++) {
      re = doOperation(red[i] & 0xff, redop, redarg);
      gr = doOperation(gre[i] & 0xff, greenop, greenarg);
      bl = doOperation(blu[i] & 0xff, blueop, bluearg);
      if (preventOverflow) {
        re = re > 255 ? 255 : re < 0 ? 0 : re;
        gr = gr > 255 ? 255 : gr < 0 ? 0 : gr;
        bl = bl > 255 ? 255 : bl < 0 ? 0 : bl;
      }
      red[i] = (byte) re;
      gre[i] = (byte) gr;
      blu[i] = (byte) bl;
    }
    return new IndexColorModel(8, n, red, gre, blu);
  }
Ejemplo n.º 2
0
  private void writePLTE() throws IOException {
    if (!(getColorModel() instanceof IndexColorModel)) return;

    IndexColorModel model = (IndexColorModel) getColorModel();
    byte[][] lut = new byte[3][256];
    model.getReds(lut[0]);
    model.getGreens(lut[1]);
    model.getBlues(lut[2]);

    out.writeInt(768);
    byte[] b = new byte[772];
    b[0] = 'P';
    b[1] = 'L';
    b[2] = 'T';
    b[3] = 'E';

    for (int i = 0; i < lut[0].length; i++) {
      for (int j = 0; j < lut.length; j++) {
        b[i * lut.length + j + 4] = lut[j][i];
      }
    }

    out.write(b);
    out.writeInt(crc(b));
  }
  public void run(ImageProcessor ip) {
    IndexColorModel icm = (IndexColorModel) ip.getColorModel();
    // IJ.write("Color Model=" + ip.getColorModel() + " " + ip.isColorLut());

    int pixBits = icm.getPixelSize();
    int mapSize = icm.getMapSize();

    // retrieve the current lookup tables (maps) for R,G,B
    byte[] Rmap = new byte[mapSize];
    icm.getReds(Rmap);
    byte[] Gmap = new byte[mapSize];
    icm.getGreens(Gmap);
    byte[] Bmap = new byte[mapSize];
    icm.getBlues(Bmap);

    // modify the lookup tables
    for (int idx = 0; idx < mapSize; idx++) {
      int r = 0xff & Rmap[idx]; // mask to treat as unsigned byte
      int g = 0xff & Gmap[idx];
      int b = 0xff & Bmap[idx];
      Rmap[idx] = (byte) Math.min(r + 10, 255);
      Gmap[idx] = (byte) Math.min(g + 10, 255);
      Bmap[idx] = (byte) Math.min(b + 10, 255);
    }
    // create a new color model and apply to the image
    IndexColorModel icm2 = new IndexColorModel(pixBits, mapSize, Rmap, Gmap, Bmap);
    ip.setColorModel(icm2);

    WindowManager.getCurrentImage().updateAndDraw();
  }
Ejemplo n.º 4
0
  /**
   * Convert index color mapped image content to a full 24-bit 16-million color RGB image.
   *
   * @param image the source image to convert.
   * @return a full RGB color image as RenderedOp.
   */
  public static RenderedImage convertIndexColorToRGBColor(RenderedImage image) {
    RenderedImage result = image;

    // If the source image is color mapped, convert it to 3-band RGB.
    // Note that GIF and PNG files fall into this category.
    if (image.getColorModel() instanceof IndexColorModel) {
      // Retrieve the IndexColorModel
      IndexColorModel icm = (IndexColorModel) image.getColorModel();

      // Cache the number of elements in each band of the colormap.
      int mapSize = icm.getMapSize();

      // Allocate an array for the lookup table data.
      byte[][] lutData = new byte[3][mapSize];

      // Load the lookup table data from the IndexColorModel.
      icm.getReds(lutData[0]);
      icm.getGreens(lutData[1]);
      icm.getBlues(lutData[2]);

      // Create the lookup table object.
      LookupTableJAI lut = new LookupTableJAI(lutData);

      // Replace the original image with the 3-band RGB image.
      result = JAI.create("lookup", image, lut); // $NON-NLS-1$
    }

    return result;
  }
 /**
  * The constructor of the class, which creates the arrays and instances needed to obtain the image
  * data and registers the class to listen to mouse motion events.
  *
  * @param image a RenderedImage for display
  */
 public DisplayJAIWhileStoringCoordinates(RenderedImage image) {
   super(image); // calls the constructor for DisplayJAI.
   readIterator = RandomIterFactory.create(image, null); // creates the iterator.
   // Get some data about the image
   width = image.getWidth();
   height = image.getHeight();
   int dataType = image.getSampleModel().getDataType(); // gets the data type
   switch (dataType) {
     case DataBuffer.TYPE_BYTE:
     case DataBuffer.TYPE_SHORT:
     case DataBuffer.TYPE_USHORT:
     case DataBuffer.TYPE_INT:
       isDoubleType = false;
       break;
     case DataBuffer.TYPE_FLOAT:
     case DataBuffer.TYPE_DOUBLE:
       isDoubleType = true;
       break;
   }
   // Depending on the image data type, allocate the double or the int array.
   if (isDoubleType) dpixel = new double[image.getSampleModel().getNumBands()];
   else ipixel = new int[image.getSampleModel().getNumBands()];
   // Is the image color model indexed ?
   isIndexed = (image.getColorModel() instanceof IndexColorModel);
   if (isIndexed) {
     // Retrieve the index color model of the image.
     IndexColorModel icm = (IndexColorModel) image.getColorModel();
     // Get the number of elements in each band of the colormap.
     int mapSize = icm.getMapSize();
     // Allocate an array for the lookup table data.
     byte[][] templutData = new byte[3][mapSize];
     // Load the lookup table data from the IndexColorModel.
     icm.getReds(templutData[0]);
     icm.getGreens(templutData[1]);
     icm.getBlues(templutData[2]);
     // Load the lookup table data into a short array to avoid negative numbers.
     lutData = new short[3][mapSize];
     for (int entry = 0; entry < mapSize; entry++) {
       lutData[0][entry] =
           templutData[0][entry] > 0
               ? templutData[0][entry]
               : (short) (templutData[0][entry] + 256);
       lutData[1][entry] =
           templutData[1][entry] > 0
               ? templutData[1][entry]
               : (short) (templutData[1][entry] + 256);
       lutData[2][entry] =
           templutData[2][entry] > 0
               ? templutData[2][entry]
               : (short) (templutData[2][entry] + 256);
     }
   } // end if indexed
   // Registers the mouse listener.
   addMouseListener(this);
   // Create the list of coordinates
   clicksInformation = new ArrayList();
 }
Ejemplo n.º 6
0
 static ImageData convertToSWT(BufferedImage bufferedImage) {
   if (bufferedImage.getColorModel() instanceof DirectColorModel) {
     DirectColorModel colorModel = (DirectColorModel) bufferedImage.getColorModel();
     PaletteData palette =
         new PaletteData(
             colorModel.getRedMask(), colorModel.getGreenMask(), colorModel.getBlueMask());
     ImageData data =
         new ImageData(
             bufferedImage.getWidth(),
             bufferedImage.getHeight(),
             colorModel.getPixelSize(),
             palette);
     WritableRaster raster = bufferedImage.getRaster();
     int[] pixelArray = new int[3];
     for (int y = 0; y < data.height; y++) {
       for (int x = 0; x < data.width; x++) {
         raster.getPixel(x, y, pixelArray);
         int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2]));
         data.setPixel(x, y, pixel);
       }
     }
     return data;
   } else if (bufferedImage.getColorModel() instanceof IndexColorModel) {
     IndexColorModel colorModel = (IndexColorModel) bufferedImage.getColorModel();
     int size = colorModel.getMapSize();
     byte[] reds = new byte[size];
     byte[] greens = new byte[size];
     byte[] blues = new byte[size];
     colorModel.getReds(reds);
     colorModel.getGreens(greens);
     colorModel.getBlues(blues);
     RGB[] rgbs = new RGB[size];
     for (int i = 0; i < rgbs.length; i++) {
       rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
     }
     PaletteData palette = new PaletteData(rgbs);
     ImageData data =
         new ImageData(
             bufferedImage.getWidth(),
             bufferedImage.getHeight(),
             colorModel.getPixelSize(),
             palette);
     data.transparentPixel = colorModel.getTransparentPixel();
     WritableRaster raster = bufferedImage.getRaster();
     int[] pixelArray = new int[1];
     for (int y = 0; y < data.height; y++) {
       for (int x = 0; x < data.width; x++) {
         raster.getPixel(x, y, pixelArray);
         data.setPixel(x, y, pixelArray[0]);
       }
     }
     return data;
   }
   return null;
 }
Ejemplo n.º 7
0
  /** Create a color table from the image ColorModel and SampleModel. */
  private static byte[] createColorTable(ColorModel colorModel, SampleModel sampleModel) {
    byte[] colorTable;
    if (colorModel instanceof IndexColorModel) {
      IndexColorModel icm = (IndexColorModel) colorModel;
      int mapSize = icm.getMapSize();

      /**
       * The GIF image format assumes that size of image palette is power of two. We will use
       * closest larger power of two as size of color table.
       */
      int ctSize = getGifPaletteSize(mapSize);

      byte[] reds = new byte[ctSize];
      byte[] greens = new byte[ctSize];
      byte[] blues = new byte[ctSize];
      icm.getReds(reds);
      icm.getGreens(greens);
      icm.getBlues(blues);

      /**
       * fill tail of color component arrays by replica of first color in order to avoid appearance
       * of extra colors in the color table
       */
      for (int i = mapSize; i < ctSize; i++) {
        reds[i] = reds[0];
        greens[i] = greens[0];
        blues[i] = blues[0];
      }

      colorTable = new byte[3 * ctSize];
      int idx = 0;
      for (int i = 0; i < ctSize; i++) {
        colorTable[idx++] = reds[i];
        colorTable[idx++] = greens[i];
        colorTable[idx++] = blues[i];
      }
    } else if (sampleModel.getNumBands() == 1) {
      // create gray-scaled color table for single-banded images
      int numBits = sampleModel.getSampleSize()[0];
      if (numBits > 8) {
        numBits = 8;
      }
      int colorTableLength = 3 * (1 << numBits);
      colorTable = new byte[colorTableLength];
      for (int i = 0; i < colorTableLength; i++) {
        colorTable[i] = (byte) (i / 3);
      }
    } else {
      // We do not have enough information here
      // to create well-fit color table for RGB image.
      colorTable = null;
    }

    return colorTable;
  }
 void makeCustomLut() {
   IndexColorModel cm = (IndexColorModel) LookUpTable.createGrayscaleColorModel(false);
   byte[] reds = new byte[256];
   byte[] greens = new byte[256];
   byte[] blues = new byte[256];
   cm.getReds(reds);
   cm.getGreens(greens);
   cm.getBlues(blues);
   reds[1] = (byte) 255;
   greens[1] = (byte) 0;
   blues[1] = (byte) 0;
   customLut = new IndexColorModel(8, 256, reds, greens, blues);
 }
Ejemplo n.º 9
0
    void setHistogram(ImagePlus imp, int j) {
      ImageProcessor ip = imp.getProcessor();
      ImageStatistics stats = ImageStatistics.getStatistics(ip, AREA + MODE, null);
      int maxCount2 = 0;
      histogram = stats.histogram;
      for (int i = 0; i < stats.nBins; i++)
        if ((histogram[i] > maxCount2) && (i != stats.mode)) maxCount2 = histogram[i];
      hmax = stats.maxCount;
      if ((hmax > (maxCount2 * 1.5)) && (maxCount2 != 0)) { // GL 1.5 was 2
        hmax = (int) (maxCount2 * 1.1); // GL 1.1 was 1.5
        histogram[stats.mode] = hmax;
      }
      os = null;
      ColorModel cm = ip.getColorModel();
      if (!(cm instanceof IndexColorModel)) return;
      IndexColorModel icm = (IndexColorModel) cm;
      int mapSize = icm.getMapSize();
      if (mapSize != 256) return;
      byte[] r = new byte[256];
      byte[] g = new byte[256];
      byte[] b = new byte[256];
      icm.getReds(r);
      icm.getGreens(g);
      icm.getBlues(b);
      hColors = new Color[256];

      if (isRGB) {
        if (j == 0) {
          for (int i = 0; i < 256; i++) hColors[i] = new Color(i & 255, 0 & 255, 0 & 255);
        } else if (j == 1) {
          for (int i = 0; i < 256; i++) hColors[i] = new Color(0 & 255, i & 255, 0 & 255);
        } else if (j == 2) {
          for (int i = 0; i < 256; i++) hColors[i] = new Color(0 & 255, 0 & 255, i & 255);
        }
      } else {
        if (j == 0) {
          for (int i = 0; i < 256; i++) hColors[i] = new Color(r[i] & 255, g[i] & 255, b[i] & 255);
        } else if (j == 1) {
          for (int i = 0; i < 256; i++)
            // hColors[i] = new Color(127-i/2&255, 127+i/2&255, 127-i/2&255);
            hColors[i] = new Color(192 - i / 4 & 255, 192 + i / 4 & 255, 192 - i / 4 & 255);
        } else if (j == 2) {
          for (int i = 0; i < 256; i++) hColors[i] = new Color(i & 255, i & 255, 0 & 255);
        }
      }
    }
Ejemplo n.º 10
0
 void write(ImageOutputStream ios, JPEGImageWriter writer) throws IOException {
   super.write(ios, writer); // width and height
   // Write the palette (must be 768 bytes)
   byte[] palette = new byte[768];
   IndexColorModel icm = (IndexColorModel) thumbnail.getColorModel();
   byte[] reds = new byte[256];
   byte[] greens = new byte[256];
   byte[] blues = new byte[256];
   icm.getReds(reds);
   icm.getGreens(greens);
   icm.getBlues(blues);
   for (int i = 0; i < 256; i++) {
     palette[i * 3] = reds[i];
     palette[i * 3 + 1] = greens[i];
     palette[i * 3 + 2] = blues[i];
   }
   ios.write(palette);
   writePixels(ios, writer);
 }
Ejemplo n.º 11
0
  private RenderedImage forceComponentColorModel(RenderedImage image) {
    final IndexColorModel icm = (IndexColorModel) image.getColorModel();
    final SampleModel sm = image.getSampleModel();
    final int datatype = sm.getDataType();
    final boolean alpha = icm.hasAlpha();
    // Definition of the lookup table
    final int numDestinationBands = 4;
    LookupTableJAI lut = null;

    final byte data[][] = new byte[numDestinationBands][icm.getMapSize()];
    icm.getReds(data[0]);
    icm.getGreens(data[1]);
    icm.getBlues(data[2]);
    icm.getAlphas(data[3]);

    lut = new LookupTableJAI(data);
    // Layout creation
    final ImageLayout layout = new ImageLayout(image);
    final RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout);

    int[] bits = new int[numDestinationBands];
    // bits per component
    for (int i = 0; i < numDestinationBands; i++) bits[i] = sm.getSampleSize(i);
    final ComponentColorModel destinationColorModel =
        new ComponentColorModel(
            ColorSpace.getInstance(ColorSpace.CS_sRGB),
            bits,
            alpha,
            image.getColorModel().isAlphaPremultiplied(),
            alpha ? Transparency.TRANSLUCENT : Transparency.OPAQUE,
            datatype);
    final SampleModel destinationSampleModel =
        destinationColorModel.createCompatibleSampleModel(image.getWidth(), image.getHeight());
    layout.setColorModel(destinationColorModel);
    layout.setSampleModel(destinationSampleModel);
    // Lookup Operations
    image =
        LookupDescriptor.create(image, new LookupTableWrapper(lut), 0, null, null, false, hints);

    return image;
  }
Ejemplo n.º 12
0
  /**
   * Returns a colour model suitable for use with GIF images. It has a selection of RGB colours and
   * one transparent colour.
   *
   * @return standard GIF indexed colour model
   */
  private static IndexColorModel getGifColorModel() {

    /* Acquire a standard general-purpose 256-entry indexed colour model. */
    IndexColorModel rgbModel =
        (IndexColorModel) new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_INDEXED).getColorModel();

    /* Get r/g/b entries from it. */
    byte[][] rgbs = new byte[3][256];
    rgbModel.getReds(rgbs[0]);
    rgbModel.getGreens(rgbs[1]);
    rgbModel.getBlues(rgbs[2]);

    /* Set one entry transparent. */
    int itrans = 254;
    rgbs[0][itrans] = (byte) 255;
    rgbs[1][itrans] = (byte) 255;
    rgbs[2][itrans] = (byte) 255;
    IndexColorModel gifModel = new IndexColorModel(8, 256, rgbs[0], rgbs[1], rgbs[2], itrans);

    /* Return the  model. */
    return gifModel;
  }
 private void makeTransparent() {
   ColorModel colorModel = bufferedImage.getColorModel();
   if (bufferedImage.getColorModel() instanceof IndexColorModel) {
     // vector image (IndexColorModel)
     IndexColorModel icm = (IndexColorModel) colorModel;
     WritableRaster raster = bufferedImage.getRaster();
     // pixel is offset in ICM's palette
     backgroundPixel = 1; // default Cadastre background sample
     int size = icm.getMapSize();
     byte[] reds = new byte[size];
     byte[] greens = new byte[size];
     byte[] blues = new byte[size];
     icm.getReds(reds);
     icm.getGreens(greens);
     icm.getBlues(blues);
     // The cadastre background has now an alpha to 0 (for invertGrey())
     cadastreBackground = 0x00ffffff;
     IndexColorModel icm2 =
         new IndexColorModel(
             colorModel.getPixelSize(), size, reds, greens, blues, backgroundPixel);
     bufferedImage = new BufferedImage(icm2, raster, bufferedImage.isAlphaPremultiplied(), null);
   }
   return;
 }
Ejemplo n.º 14
0
  public ImageData image(BufferedImage image) {
    if (image.getColorModel() instanceof DirectColorModel) {
      DirectColorModel cmodel = (DirectColorModel) image.getColorModel();
      PaletteData palette =
          new PaletteData(cmodel.getRedMask(), cmodel.getGreenMask(), cmodel.getBlueMask());
      ImageData data =
          new ImageData(image.getWidth(), image.getHeight(), cmodel.getPixelSize(), palette);
      for (int y = 0; y < data.height; y++) {
        for (int x = 0; x < data.width; x++) {
          int rgb = image.getRGB(x, y);
          int pixel = palette.getPixel(new RGB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF));
          data.setPixel(x, y, pixel);
          if (cmodel.hasAlpha()) data.setAlpha(x, y, (rgb >> 24) & 0xFF);
        }
      }
      return data;

    } else if (image.getColorModel() instanceof IndexColorModel) {
      IndexColorModel cmodel = (IndexColorModel) image.getColorModel();
      int size = cmodel.getMapSize();
      byte[] reds = new byte[size];
      byte[] greens = new byte[size];
      byte[] blues = new byte[size];
      cmodel.getReds(reds);
      cmodel.getGreens(greens);
      cmodel.getBlues(blues);
      RGB[] rgbs = new RGB[size];
      for (int ii = 0; ii < rgbs.length; ii++) {
        rgbs[ii] = new RGB(reds[ii] & 0xFF, greens[ii] & 0xFF, blues[ii] & 0xFF);
      }
      PaletteData palette = new PaletteData(rgbs);
      ImageData data =
          new ImageData(image.getWidth(), image.getHeight(), cmodel.getPixelSize(), palette);
      data.transparentPixel = cmodel.getTransparentPixel();
      WritableRaster raster = image.getRaster();
      int[] pixelArray = new int[1];
      for (int y = 0; y < data.height; y++) {
        for (int x = 0; x < data.width; x++) {
          raster.getPixel(x, y, pixelArray);
          data.setPixel(x, y, pixelArray[0]);
        }
      }
      return data;
    } else if (image.getColorModel() instanceof ComponentColorModel) {
      ComponentColorModel cmodel = (ComponentColorModel) image.getColorModel();
      PaletteData palette = new PaletteData(0x0000FF, 0x00FF00, 0xFF0000); // BGR
      ImageData data = new ImageData(image.getWidth(), image.getHeight(), 24, palette);
      if (cmodel.hasAlpha()) data.alphaData = new byte[image.getWidth() * image.getHeight()];
      WritableRaster raster = image.getRaster();
      int[] pixelArray = new int[4];
      for (int y = 0; y < data.height; y++) {
        for (int x = 0; x < data.width; x++) {
          raster.getPixel(x, y, pixelArray);
          data.setPixel(x, y, (pixelArray[2] << 16) | (pixelArray[1] << 8) | (pixelArray[0]));
          if (data.alphaData != null) data.alphaData[y * data.width + x] = (byte) pixelArray[3];
        }
      }
      return data;
    }
    return null;
  }
Ejemplo n.º 15
0
  protected RenderedImage convert(RenderedImage renderedImage) throws Exception {

    int height = renderedImage.getHeight();
    int width = renderedImage.getWidth();

    SampleModel sampleModel = renderedImage.getSampleModel();
    ColorModel colorModel = renderedImage.getColorModel();

    Raster raster = renderedImage.getData();

    DataBuffer dataBuffer = raster.getDataBuffer();

    if (colorModel instanceof IndexColorModel) {
      IndexColorModel indexColorModel = (IndexColorModel) colorModel;

      int mapSize = indexColorModel.getMapSize();

      byte[][] data = new byte[4][mapSize];

      indexColorModel.getReds(data[0]);
      indexColorModel.getGreens(data[1]);
      indexColorModel.getBlues(data[2]);
      indexColorModel.getAlphas(data[3]);

      LookupTableJAI lookupTableJAI = new LookupTableJAI(data);

      renderedImage = LookupDescriptor.create(renderedImage, lookupTableJAI, null);
    } else if (sampleModel.getNumBands() == 2) {
      List<Byte> bytesList = new ArrayList<Byte>(height * width * _NUM_OF_BANDS);

      List<Byte> tempBytesList = new ArrayList<Byte>(_NUM_OF_BANDS);

      for (int i = 0; i < dataBuffer.getSize(); i++) {
        int mod = (i + 1) % 2;

        int elemPos = i;

        if (mod == 0) {
          tempBytesList.add((byte) dataBuffer.getElem(elemPos - 1));
          tempBytesList.add((byte) dataBuffer.getElem(elemPos - 1));
        }

        tempBytesList.add((byte) dataBuffer.getElem(elemPos));

        if (mod == 0) {
          Collections.reverse(tempBytesList);

          bytesList.addAll(tempBytesList);

          tempBytesList.clear();
        }
      }

      byte[] data = ArrayUtil.toArray(bytesList.toArray(new Byte[bytesList.size()]));

      DataBuffer newDataBuffer = new DataBufferByte(data, data.length);

      renderedImage = createRenderedImage(renderedImage, height, width, newDataBuffer);
    } else if (colorModel.getTransparency() != Transparency.TRANSLUCENT) {
      List<Byte> bytesList = new ArrayList<Byte>(height * width * _NUM_OF_BANDS);

      List<Byte> tempBytesList = new ArrayList<Byte>(_NUM_OF_BANDS);

      for (int i = 0; i < dataBuffer.getSize(); i++) {
        int mod = (i + 1) % 3;

        int elemPos = i;

        tempBytesList.add((byte) dataBuffer.getElem(elemPos));

        if (mod == 0) {
          tempBytesList.add((byte) 255);

          Collections.reverse(tempBytesList);

          bytesList.addAll(tempBytesList);

          tempBytesList.clear();
        }
      }

      byte[] data = ArrayUtil.toArray(bytesList.toArray(new Byte[bytesList.size()]));

      DataBuffer newDataBuffer = new DataBufferByte(data, data.length);

      renderedImage = createRenderedImage(renderedImage, height, width, newDataBuffer);
    }

    return renderedImage;
  }
Ejemplo n.º 16
0
  public RenderedImage scale(RenderedImage renderedImage, int maxHeight, int maxWidth) {

    int imageHeight = renderedImage.getHeight();
    int imageWidth = renderedImage.getWidth();

    if (maxHeight == 0) {
      maxHeight = imageHeight;
    }

    if (maxWidth == 0) {
      maxWidth = imageWidth;
    }

    if ((imageHeight <= maxHeight) && (imageWidth <= maxWidth)) {
      return renderedImage;
    }

    double factor = Math.min((double) maxHeight / imageHeight, (double) maxWidth / imageWidth);

    int scaledHeight = Math.max(1, (int) (factor * imageHeight));
    int scaledWidth = Math.max(1, (int) (factor * imageWidth));

    BufferedImage bufferedImage = getBufferedImage(renderedImage);

    int type = bufferedImage.getType();

    if (type == 0) {
      type = BufferedImage.TYPE_INT_ARGB;
    }

    BufferedImage scaledBufferedImage = null;

    if ((type == BufferedImage.TYPE_BYTE_BINARY) || (type == BufferedImage.TYPE_BYTE_INDEXED)) {

      IndexColorModel indexColorModel = (IndexColorModel) bufferedImage.getColorModel();

      BufferedImage tempBufferedImage = new BufferedImage(1, 1, type, indexColorModel);

      int bits = indexColorModel.getPixelSize();
      int size = indexColorModel.getMapSize();

      byte[] reds = new byte[size];

      indexColorModel.getReds(reds);

      byte[] greens = new byte[size];

      indexColorModel.getGreens(greens);

      byte[] blues = new byte[size];

      indexColorModel.getBlues(blues);

      WritableRaster writableRaster = tempBufferedImage.getRaster();

      int pixel = writableRaster.getSample(0, 0, 0);

      IndexColorModel scaledIndexColorModel =
          new IndexColorModel(bits, size, reds, greens, blues, pixel);

      scaledBufferedImage =
          new BufferedImage(scaledWidth, scaledHeight, type, scaledIndexColorModel);
    } else {
      scaledBufferedImage = new BufferedImage(scaledWidth, scaledHeight, type);
    }

    Graphics graphics = scaledBufferedImage.getGraphics();

    Image scaledImage =
        bufferedImage.getScaledInstance(scaledWidth, scaledHeight, Image.SCALE_SMOOTH);

    graphics.drawImage(scaledImage, 0, 0, null);

    return scaledBufferedImage;
  }