示例#1
0
 // returns a value specifying some kind of average brightness in the image.
 protected int getAverageBrightness(BufferedImage img) {
   Raster r = img.getData();
   int total = 0;
   for (int y = 0; y < r.getHeight(); y++) {
     for (int x = 0; x < r.getWidth(); x++) {
       total += r.getSample(r.getMinX() + x, r.getMinY() + y, 0);
     }
   }
   return (int) (total / ((r.getWidth() / factorD) * (r.getHeight() / factorD)));
 }
示例#2
0
 // If defaultNewIsNull is true, then newIsNull is ignored and it should behave as
 // if newIsNull were false.
 private void runTest(
     WritableRaster source,
     double sourceNoData,
     double newValue,
     boolean defaultNewIsNull,
     boolean newIsNull) {
   ColorModel cm1 = RasterUtils.createColorModel(source);
   java.util.Hashtable<String, Object> arg1Properties = new java.util.Hashtable<String, Object>();
   arg1Properties.put(OpImageUtils.NODATA_PROPERTY, sourceNoData);
   BufferedImage s1 = new BufferedImage(cm1, source, false, arg1Properties);
   RenderedOp op = null;
   if (defaultNewIsNull) {
     op = ReplaceNullDescriptor.create(s1, newValue, null);
   } else {
     op = ReplaceNullDescriptor.create(s1, newValue, newIsNull, null);
   }
   Raster r = op.getData();
   if (!defaultNewIsNull && newIsNull) {
     Assert.assertEquals(newValue, OpImageUtils.getNoData(op, Double.NaN), EPSILON);
   } else {
     Assert.assertTrue(Double.isNaN(OpImageUtils.getNoData(op, Double.NaN)));
   }
   Assert.assertEquals(width, r.getWidth());
   Assert.assertEquals(height, r.getHeight());
   for (int x = 0; x < width; x++) {
     for (int y = 0; y < height; y++) {
       double v = r.getSampleDouble(x, y, 0);
       int pixelId = getPixelId(x, y, width);
       Assert.assertEquals(pixelId, v, EPSILON);
     }
   }
 }
  private Raster clipRowToRect(
      final Raster raster, final Rectangle rect, final int[] bands, final int xSub) {
    if (rect.contains(raster.getMinX(), 0, raster.getWidth(), 1)
        && xSub == 1
        && bands == null /* TODO: Compare bands with that of raster */) {
      return raster;
    }

    return raster.createChild(rect.x / xSub, 0, rect.width / xSub, 1, 0, 0, bands);
  }
  public final Rectangle2D getBounds2D(Raster src) {
    // We position source raster to (0,0) even if it is translated child
    // raster.
    // This means that we need only width and height of the src
    int width = src.getWidth();
    int height = src.getHeight();

    float[] corners = {0, 0, width, 0, width, height, 0, height};

    at.transform(corners, 0, corners, 0, 4);

    Rectangle2D.Float bounds = new Rectangle2D.Float(corners[0], corners[1], 0, 0);
    bounds.add(corners[2], corners[3]);
    bounds.add(corners[4], corners[5]);
    bounds.add(corners[6], corners[7]);

    return bounds;
  }
示例#5
0
  public static BufferedImage toGrayScale(BufferedImage image) {
    BufferedImage result =
        new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
    Raster raster = image.getData();
    WritableRaster grayRaster = result.getRaster();
    int height = raster.getHeight();
    int sample = 0;

    for (int x = 0; x < raster.getWidth(); ++x) {
      for (int y = 0; y < height; ++y) {

        sample = raster.getSample(x, y, 0) + raster.getSample(x, y, 1) + raster.getSample(x, y, 2);

        grayRaster.setSample(x, y, 0, (int) ((float) sample / 3.0));
      }
    }
    return result;
  }
示例#6
0
  /**
   * Paint the image onto a Graphics object. The painting is performed tile-by-tile, and includes a
   * grey region covering the unused portion of image tiles as well as the general background. At
   * this point the image must be byte data.
   */
  public synchronized void paintComponent(Graphics g) {

    Graphics2D g2D = null;
    if (g instanceof Graphics2D) {
      g2D = (Graphics2D) g;
    } else {
      return;
    }

    // if source is null, it's just a component
    if (source == null) {
      g2D.setColor(getBackground());
      g2D.fillRect(0, 0, componentWidth, componentHeight);
      return;
    }

    int transX = -originX;
    int transY = -originY;

    // Get the clipping rectangle and translate it into image coordinates.
    Rectangle clipBounds = g.getClipBounds();

    if (clipBounds == null) {
      clipBounds = new Rectangle(0, 0, componentWidth, componentHeight);
    }

    // clear the background (clip it) [minimal optimization here]
    if (transX > 0
        || transY > 0
        || transX < (componentWidth - source.getWidth())
        || transY < (componentHeight - source.getHeight())) {
      g2D.setColor(getBackground());
      g2D.fillRect(0, 0, componentWidth, componentHeight);
    }

    clipBounds.translate(-transX, -transY);

    // Determine the extent of the clipping region in tile coordinates.
    int txmin, txmax, tymin, tymax;
    int ti, tj;

    txmin = XtoTileX(clipBounds.x);
    txmin = Math.max(txmin, minTileX);
    txmin = Math.min(txmin, maxTileX);

    txmax = XtoTileX(clipBounds.x + clipBounds.width - 1);
    txmax = Math.max(txmax, minTileX);
    txmax = Math.min(txmax, maxTileX);

    tymin = YtoTileY(clipBounds.y);
    tymin = Math.max(tymin, minTileY);
    tymin = Math.min(tymin, maxTileY);

    tymax = YtoTileY(clipBounds.y + clipBounds.height - 1);
    tymax = Math.max(tymax, minTileY);
    tymax = Math.min(tymax, maxTileY);
    Insets insets = getInsets();

    // Loop over tiles within the clipping region
    for (tj = tymin; tj <= tymax; tj++) {
      for (ti = txmin; ti <= txmax; ti++) {
        int tx = TileXtoX(ti);
        int ty = TileYtoY(tj);

        Raster tile = source.getTile(ti, tj);
        if (tile != null) {
          DataBuffer dataBuffer = tile.getDataBuffer();

          WritableRaster wr = tile.createWritableRaster(sampleModel, dataBuffer, null);

          BufferedImage bi =
              new BufferedImage(colorModel, wr, colorModel.isAlphaPremultiplied(), null);

          // correctly handles band offsets
          if (brightnessEnabled == true) {
            SampleModel sm =
                sampleModel.createCompatibleSampleModel(tile.getWidth(), tile.getHeight());

            WritableRaster raster = RasterFactory.createWritableRaster(sm, null);

            BufferedImage bimg =
                new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), null);

            // don't move this code
            ByteLookupTable lutTable = new ByteLookupTable(0, lutData);
            LookupOp lookup = new LookupOp(lutTable, null);
            lookup.filter(bi, bimg);

            g2D.drawImage(bimg, biop, tx + transX + insets.left, ty + transY + insets.top);
          } else {
            AffineTransform transform;

            transform =
                AffineTransform.getTranslateInstance(
                    tx + transX + insets.left, ty + transY + insets.top);

            g2D.drawRenderedImage(bi, transform);
          }
        }
      }
    }
  }
  /**
   * Ipp filter.
   *
   * @param src the src.
   * @param dst the dst.
   * @param imageType the image type.
   * @return the int.
   */
  @SuppressWarnings("unused")
  private int ippFilter(Raster src, WritableRaster dst, int imageType) {
    int srcStride, dstStride;
    boolean skipChannel = false;
    int channels;
    int offsets[] = null;

    switch (imageType) {
      case BufferedImage.TYPE_INT_RGB:
      case BufferedImage.TYPE_INT_BGR:
        {
          channels = 4;
          srcStride = src.getWidth() * 4;
          dstStride = dst.getWidth() * 4;
          skipChannel = true;
          break;
        }

      case BufferedImage.TYPE_INT_ARGB:
      case BufferedImage.TYPE_INT_ARGB_PRE:
      case BufferedImage.TYPE_4BYTE_ABGR:
      case BufferedImage.TYPE_4BYTE_ABGR_PRE:
        {
          channels = 4;
          srcStride = src.getWidth() * 4;
          dstStride = dst.getWidth() * 4;
          break;
        }

      case BufferedImage.TYPE_BYTE_GRAY:
      case BufferedImage.TYPE_BYTE_INDEXED:
        {
          channels = 1;
          srcStride = src.getWidth();
          dstStride = dst.getWidth();
          break;
        }

      case BufferedImage.TYPE_3BYTE_BGR:
        {
          channels = 3;
          srcStride = src.getWidth() * 3;
          dstStride = dst.getWidth() * 3;
          break;
        }

      case BufferedImage.TYPE_USHORT_GRAY: // TODO - could be done in
        // native code?
      case BufferedImage.TYPE_USHORT_565_RGB:
      case BufferedImage.TYPE_USHORT_555_RGB:
      case BufferedImage.TYPE_BYTE_BINARY:
        {
          return slowFilter(src, dst);
        }

      default:
        {
          SampleModel srcSM = src.getSampleModel();
          SampleModel dstSM = dst.getSampleModel();

          if (srcSM instanceof PixelInterleavedSampleModel
              && dstSM instanceof PixelInterleavedSampleModel) {
            // Check PixelInterleavedSampleModel
            if (srcSM.getDataType() != DataBuffer.TYPE_BYTE
                || dstSM.getDataType() != DataBuffer.TYPE_BYTE) {
              return slowFilter(src, dst);
            }

            channels = srcSM.getNumBands(); // Have IPP functions for 1,
            // 3 and 4 channels
            if (channels != 1 && channels != 3 && channels != 4) {
              return slowFilter(src, dst);
            }

            int dataTypeSize = DataBuffer.getDataTypeSize(srcSM.getDataType()) / 8;

            srcStride = ((ComponentSampleModel) srcSM).getScanlineStride() * dataTypeSize;
            dstStride = ((ComponentSampleModel) dstSM).getScanlineStride() * dataTypeSize;
          } else if (srcSM instanceof SinglePixelPackedSampleModel
              && dstSM instanceof SinglePixelPackedSampleModel) {
            // Check SinglePixelPackedSampleModel
            SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) srcSM;
            SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel) dstSM;

            // No IPP function for this type
            if (sppsm1.getDataType() == DataBuffer.TYPE_USHORT) {
              return slowFilter(src, dst);
            }

            channels = sppsm1.getNumBands();
            // Have IPP functions for 1, 3 and 4 channels
            if (channels != 1 && channels != 3 && channels != 4) {
              return slowFilter(src, dst);
            }

            // Check compatibility of sample models
            if (sppsm1.getDataType() != sppsm2.getDataType()
                || !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets())
                || !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())) {
              return slowFilter(src, dst);
            }

            for (int i = 0; i < channels; i++) {
              if (sppsm1.getSampleSize(i) != 8) {
                return slowFilter(src, dst);
              }
            }

            if (channels == 3) {
              channels = 4;
            }

            int dataTypeSize = DataBuffer.getDataTypeSize(sppsm1.getDataType()) / 8;

            srcStride = sppsm1.getScanlineStride() * dataTypeSize;
            dstStride = sppsm2.getScanlineStride() * dataTypeSize;
          } else {
            return slowFilter(src, dst);
          }

          // Fill offsets if there's a child raster
          if (src.getParent() != null || dst.getParent() != null) {
            if (src.getSampleModelTranslateX() != 0
                || src.getSampleModelTranslateY() != 0
                || dst.getSampleModelTranslateX() != 0
                || dst.getSampleModelTranslateY() != 0) {
              offsets = new int[4];
              offsets[0] = -src.getSampleModelTranslateX() + src.getMinX();
              offsets[1] = -src.getSampleModelTranslateY() + src.getMinY();
              offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX();
              offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY();
            }
          }
        }
    }

    double m00 = at.getScaleX();
    double m01 = at.getShearX();
    double m02 = at.getTranslateX();
    double m10 = at.getShearY();
    double m11 = at.getScaleY();
    double m12 = at.getTranslateY();

    Object srcData, dstData;
    AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance();
    try {
      srcData = dbAccess.getData(src.getDataBuffer());
      dstData = dbAccess.getData(dst.getDataBuffer());
    } catch (IllegalArgumentException e) {
      return -1; // Unknown data buffer type
    }

    return ippAffineTransform(
        m00,
        m01,
        m02,
        m10,
        m11,
        m12,
        srcData,
        src.getWidth(),
        src.getHeight(),
        srcStride,
        dstData,
        dst.getWidth(),
        dst.getHeight(),
        dstStride,
        iType,
        channels,
        skipChannel,
        offsets);
  }
  @Override
  public BufferedImage read(final int imageIndex, final ImageReadParam param) throws IOException {
    Iterator<ImageTypeSpecifier> imageTypes = getImageTypes(imageIndex);
    ImageTypeSpecifier rawType = getRawImageType(imageIndex);

    if (header.getPaletteInfo() != PCX.PALETTEINFO_COLOR
        && header.getPaletteInfo() != PCX.PALETTEINFO_GRAY) {
      processWarningOccurred(
          String.format(
              "Unsupported color mode: %d, colors may look incorrect", header.getPaletteInfo()));
    }

    int width = getWidth(imageIndex);
    int height = getHeight(imageIndex);

    BufferedImage destination = getDestination(param, imageTypes, width, height);

    Rectangle srcRegion = new Rectangle();
    Rectangle destRegion = new Rectangle();
    computeRegions(param, width, height, destination, srcRegion, destRegion);

    WritableRaster destRaster =
        clipToRect(
            destination.getRaster(),
            destRegion,
            param != null ? param.getDestinationBands() : null);
    checkReadParamBandSettings(param, rawType.getNumBands(), destRaster.getNumBands());

    int compression = header.getCompression();

    // Wrap input (COMPRESSION_RLE is really the only value allowed)
    DataInput input =
        compression == PCX.COMPRESSION_RLE
            ? new DataInputStream(
                new DecoderStream(IIOUtil.createStreamAdapter(imageInput), new RLEDecoder()))
            : imageInput;

    int xSub = param != null ? param.getSourceXSubsampling() : 1;
    int ySub = param != null ? param.getSourceYSubsampling() : 1;

    processImageStarted(imageIndex);

    if (rawType.getColorModel() instanceof IndexColorModel && header.getChannels() > 1) {
      // Bit planes!
      // Create raster from a default 8 bit layout
      WritableRaster rowRaster = GRAYSCALE.createBufferedImage(header.getWidth(), 1).getRaster();

      // Clip to source region
      Raster clippedRow =
          clipRowToRect(
              rowRaster,
              srcRegion,
              param != null ? param.getSourceBands() : null,
              param != null ? param.getSourceXSubsampling() : 1);

      int planeWidth = header.getBytesPerLine();
      byte[] planeData = new byte[planeWidth * 8];

      byte[] rowDataByte = ((DataBufferByte) rowRaster.getDataBuffer()).getData();

      for (int y = 0; y < height; y++) {
        switch (header.getBitsPerPixel()) {
          case 1:
            readRowByte(
                input,
                srcRegion,
                xSub,
                ySub,
                planeData,
                0,
                planeWidth * header.getChannels(),
                destRaster,
                clippedRow,
                y);
            break;
          default:
            throw new AssertionError();
        }

        int pixelPos = 0;
        for (int planePos = 0; planePos < planeWidth; planePos++) {
          BitRotator.bitRotateCW(planeData, planePos, planeWidth, rowDataByte, pixelPos, 1);
          pixelPos += 8;
        }

        processImageProgress(100f * y / height);

        if (y >= srcRegion.y + srcRegion.height) {
          break;
        }

        if (abortRequested()) {
          processReadAborted();
          break;
        }
      }
    } else if (header.getBitsPerPixel() == 24 || header.getBitsPerPixel() == 32) {
      // Can't use width here, as we need to take bytesPerLine into account, and re-create a width
      // based on this
      int rowWidth = (header.getBytesPerLine() * 8) / header.getBitsPerPixel();
      WritableRaster rowRaster = rawType.createBufferedImage(rowWidth, 1).getRaster();

      // Clip to source region
      Raster clippedRow =
          clipRowToRect(
              rowRaster,
              srcRegion,
              param != null ? param.getSourceBands() : null,
              param != null ? param.getSourceXSubsampling() : 1);

      for (int y = 0; y < height; y++) {
        byte[] rowDataByte = ((DataBufferByte) rowRaster.getDataBuffer()).getData();
        readRowByte(
            input,
            srcRegion,
            xSub,
            ySub,
            rowDataByte,
            0,
            rowDataByte.length,
            destRaster,
            clippedRow,
            y);

        processImageProgress(100f * y / height);

        if (y >= srcRegion.y + srcRegion.height) {
          break;
        }

        if (abortRequested()) {
          processReadAborted();
          break;
        }
      }
    } else {
      // Can't use width here, as we need to take bytesPerLine into account, and re-create a width
      // based on this
      int rowWidth = (header.getBytesPerLine() * 8) / header.getBitsPerPixel();
      WritableRaster rowRaster = rawType.createBufferedImage(rowWidth, 1).getRaster();

      // Clip to source region
      Raster clippedRow =
          clipRowToRect(
              rowRaster,
              srcRegion,
              param != null ? param.getSourceBands() : null,
              param != null ? param.getSourceXSubsampling() : 1);

      for (int y = 0; y < height; y++) {
        for (int c = 0; c < header.getChannels(); c++) {
          WritableRaster destChannel =
              destRaster.createWritableChild(
                  destRaster.getMinX(),
                  destRaster.getMinY(),
                  destRaster.getWidth(),
                  destRaster.getHeight(),
                  0,
                  0,
                  new int[] {c});
          Raster srcChannel =
              clippedRow.createChild(
                  clippedRow.getMinX(), 0, clippedRow.getWidth(), 1, 0, 0, new int[] {c});

          switch (header.getBitsPerPixel()) {
            case 1:
            case 2:
            case 4:
            case 8:
              byte[] rowDataByte = ((DataBufferByte) rowRaster.getDataBuffer()).getData(c);
              readRowByte(
                  input,
                  srcRegion,
                  xSub,
                  ySub,
                  rowDataByte,
                  0,
                  rowDataByte.length,
                  destChannel,
                  srcChannel,
                  y);
              break;
            default:
              throw new AssertionError();
          }

          if (abortRequested()) {
            break;
          }
        }

        processImageProgress(100f * y / height);

        if (y >= srcRegion.y + srcRegion.height) {
          break;
        }

        if (abortRequested()) {
          processReadAborted();
          break;
        }
      }
    }

    processImageComplete();

    return destination;
  }