Beispiel #1
0
  /**
   * Builds a new BufferedImage that is the difference between the two input images
   *
   * @param ref the reference bitmap
   * @param gen the newly generated bitmap
   * @return the diff bitmap
   */
  public static BufferedImage buildDiffImage(BufferedImage ref, BufferedImage gen) {
    BufferedImage diff =
        new BufferedImage(ref.getWidth(), ref.getHeight(), BufferedImage.TYPE_INT_ARGB);
    WritableRaster refWR = ref.getRaster();
    WritableRaster genWR = gen.getRaster();
    WritableRaster dstWR = diff.getRaster();

    boolean refPre = ref.isAlphaPremultiplied();
    if (!refPre) {
      ColorModel cm = ref.getColorModel();
      cm = GraphicsUtil.coerceData(refWR, cm, true);
      ref = new BufferedImage(cm, refWR, true, null);
    }
    boolean genPre = gen.isAlphaPremultiplied();
    if (!genPre) {
      ColorModel cm = gen.getColorModel();
      cm = GraphicsUtil.coerceData(genWR, cm, true);
      gen = new BufferedImage(cm, genWR, true, null);
    }

    int w = ref.getWidth();
    int h = ref.getHeight();

    int y, i, val;
    int[] refPix = null;
    int[] genPix = null;
    for (y = 0; y < h; y++) {
      refPix = refWR.getPixels(0, y, w, 1, refPix);
      genPix = genWR.getPixels(0, y, w, 1, genPix);
      for (i = 0; i < refPix.length; i++) {
        // val = ((genPix[i] - refPix[i]) * 5) + 128;
        val = ((refPix[i] - genPix[i]) * 10) + 128;
        if ((val & 0xFFFFFF00) != 0) {
          if ((val & 0x80000000) != 0) {
            val = 0;
          } else {
            val = 255;
          }
        }
        genPix[i] = val;
      }
      dstWR.setPixels(0, y, w, 1, genPix);
    }

    if (!genPre) {
      ColorModel cm = gen.getColorModel();
      cm = GraphicsUtil.coerceData(genWR, cm, false);
    }

    if (!refPre) {
      ColorModel cm = ref.getColorModel();
      cm = GraphicsUtil.coerceData(refWR, cm, false);
    }

    return diff;
  }
  /** Superclass getRaster... */
  public final Raster getRaster(int x, int y, int w, int h) {
    if (w == 0 || h == 0) {
      return null;
    }

    //
    // If working raster is big enough, reuse it. Otherwise,
    // build a large enough new one.
    //
    WritableRaster raster = saved;
    if (raster == null || raster.getWidth() < w || raster.getHeight() < h) {
      raster = getCachedRaster(dataModel, w, h);
      saved = raster;
    }

    // Access raster internal int array. Because we use a DirectColorModel,
    // we know the DataBuffer is of type DataBufferInt and the SampleModel
    // is SinglePixelPackedSampleModel.
    // Adjust for initial offset in DataBuffer and also for the scanline
    // stride.
    //
    DataBufferInt rasterDB = (DataBufferInt) raster.getDataBuffer();
    int[] pixels = rasterDB.getBankData()[0];
    int off = rasterDB.getOffset();
    int scanlineStride =
        ((SinglePixelPackedSampleModel) raster.getSampleModel()).getScanlineStride();
    int adjust = scanlineStride - w;

    fillRaster(pixels, off, adjust, x, y, w, h); // delegate to subclass.

    GraphicsUtil.coerceData(raster, dataModel, model.isAlphaPremultiplied());

    return raster;
  }
  public WritableRaster copyData(WritableRaster wr) {
    // Get my source.
    CachableRed src = (CachableRed) getSources().get(0);

    Rectangle r = wr.getBounds();
    r.x -= xinset;
    r.y -= yinset;
    r.width += 2 * xinset;
    r.height += 2 * yinset;

    // System.out.println("Gaussian GenR: " + wr);
    // System.out.println("SrcReq: " + r);

    ColorModel srcCM = src.getColorModel();

    WritableRaster tmpR1 = null, tmpR2 = null;

    tmpR1 = srcCM.createCompatibleWritableRaster(r.width, r.height);
    {
      WritableRaster fill;
      fill = tmpR1.createWritableTranslatedChild(r.x, r.y);
      src.copyData(fill);
    }
    if (srcCM.hasAlpha() && !srcCM.isAlphaPremultiplied())
      GraphicsUtil.coerceData(tmpR1, srcCM, true);

    // For the blur box approx we can use dest as our intermediate
    // otherwise we let it default to null which means we create a new
    // one...

    // this lets the Vertical conv know how much is junk, so it
    // doesn't bother to convolve the top and bottom edges
    int skipX;
    // long t1 = System.currentTimeMillis();
    if (xinset == 0) {
      skipX = 0;
    } else if (convOp[0] != null) {
      tmpR2 = getColorModel().createCompatibleWritableRaster(r.width, r.height);
      tmpR2 = convOp[0].filter(tmpR1, tmpR2);
      skipX = convOp[0].getKernel().getXOrigin();

      // Swap them...
      WritableRaster tmp = tmpR1;
      tmpR1 = tmpR2;
      tmpR2 = tmp;
    } else {
      if ((dX & 0x01) == 0) {
        tmpR1 = boxFilterH(tmpR1, tmpR1, 0, 0, dX, dX / 2);
        tmpR1 = boxFilterH(tmpR1, tmpR1, dX / 2, 0, dX, dX / 2 - 1);
        tmpR1 = boxFilterH(tmpR1, tmpR1, dX - 1, 0, dX + 1, dX / 2);
        skipX = dX - 1 + dX / 2;
      } else {
        tmpR1 = boxFilterH(tmpR1, tmpR1, 0, 0, dX, dX / 2);
        tmpR1 = boxFilterH(tmpR1, tmpR1, dX / 2, 0, dX, dX / 2);
        tmpR1 = boxFilterH(tmpR1, tmpR1, dX - 2, 0, dX, dX / 2);
        skipX = dX - 2 + dX / 2;
      }
    }

    if (yinset == 0) {
      tmpR2 = tmpR1;
    } else if (convOp[1] != null) {
      if (tmpR2 == null) {
        tmpR2 = getColorModel().createCompatibleWritableRaster(r.width, r.height);
      }
      tmpR2 = convOp[1].filter(tmpR1, tmpR2);
    } else {
      if ((dY & 0x01) == 0) {
        tmpR1 = boxFilterV(tmpR1, tmpR1, skipX, 0, dY, dY / 2);
        tmpR1 = boxFilterV(tmpR1, tmpR1, skipX, dY / 2, dY, dY / 2 - 1);
        tmpR1 = boxFilterV(tmpR1, tmpR1, skipX, dY - 1, dY + 1, dY / 2);
      } else {
        tmpR1 = boxFilterV(tmpR1, tmpR1, skipX, 0, dY, dY / 2);
        tmpR1 = boxFilterV(tmpR1, tmpR1, skipX, dY / 2, dY, dY / 2);
        tmpR1 = boxFilterV(tmpR1, tmpR1, skipX, dY - 2, dY, dY / 2);
      }
      tmpR2 = tmpR1;
    }
    // long t2 = System.currentTimeMillis();
    // System.out.println("Time: " + (t2-t1) +
    //                       (((convOp[0] != null) || (convOp[1] != null))?
    //                        " ConvOp":""));
    // System.out.println("Rasters  WR :" + wr.getBounds());
    // System.out.println("         tmp:" + tmpR2.getBounds());
    // System.out.println("      bounds:" + getBounds());
    // System.out.println("       skipX:" + skipX +
    //                    " dx:" + dX + " Dy: " + dY);
    tmpR2 = tmpR2.createWritableTranslatedChild(r.x, r.y);
    GraphicsUtil.copyData(tmpR2, wr);

    return wr;
  }
  public WritableRaster copyData(WritableRaster wr) {
    // Get my source.
    CachableRed src = (CachableRed) getSources().get(0);
    ColorModel srcCM = src.getColorModel();
    SampleModel srcSM = src.getSampleModel();

    // Fast case, SRGB source, INT Pack writable raster...
    if (srcIssRGB && Any2sRGBRed.is_INT_PACK_COMP(wr.getSampleModel())) {
      src.copyData(wr);
      if (srcCM.hasAlpha()) GraphicsUtil.coerceData(wr, srcCM, false);
      Any2sRGBRed.applyLut_INT(wr, sRGBToLsRGBLut);
      return wr;
    }

    if (srcCM == null) {
      // We don't really know much about this source, let's
      // guess based on the number of bands...

      float[][] matrix = null;
      switch (srcSM.getNumBands()) {
        case 1:
          matrix = new float[1][3];
          matrix[0][0] = 1; // Red
          matrix[0][1] = 1; // Grn
          matrix[0][2] = 1; // Blu
          break;
        case 2:
          matrix = new float[2][4];
          matrix[0][0] = 1; // Red
          matrix[0][1] = 1; // Grn
          matrix[0][2] = 1; // Blu
          matrix[1][3] = 1; // Alpha
          break;
        case 3:
          matrix = new float[3][3];
          matrix[0][0] = 1; // Red
          matrix[1][1] = 1; // Grn
          matrix[2][2] = 1; // Blu
          break;
        default:
          matrix = new float[srcSM.getNumBands()][4];
          matrix[0][0] = 1; // Red
          matrix[1][1] = 1; // Grn
          matrix[2][2] = 1; // Blu
          matrix[3][3] = 1; // Alpha
          break;
      }

      Raster srcRas = src.getData(wr.getBounds());
      BandCombineOp op = new BandCombineOp(matrix, null);
      op.filter(srcRas, wr);
    } else {
      ColorModel dstCM = getColorModel();
      BufferedImage dstBI;

      if (!dstCM.hasAlpha()) {
        // No alpha ao we don't have to work around the bug
        // in the color convert op.
        dstBI =
            new BufferedImage(
                dstCM, wr.createWritableTranslatedChild(0, 0), dstCM.isAlphaPremultiplied(), null);
      } else {
        // All this nonsense is to work around the fact that
        // the Color convert op doesn't properly copy the
        // Alpha from src to dst.
        SinglePixelPackedSampleModel dstSM;
        dstSM = (SinglePixelPackedSampleModel) wr.getSampleModel();
        int[] masks = dstSM.getBitMasks();
        SampleModel dstSMNoA =
            new SinglePixelPackedSampleModel(
                dstSM.getDataType(),
                dstSM.getWidth(),
                dstSM.getHeight(),
                dstSM.getScanlineStride(),
                new int[] {masks[0], masks[1], masks[2]});
        ColorModel dstCMNoA = GraphicsUtil.Linear_sRGB;

        WritableRaster dstWr;
        dstWr = Raster.createWritableRaster(dstSMNoA, wr.getDataBuffer(), new Point(0, 0));
        dstWr =
            dstWr.createWritableChild(
                wr.getMinX() - wr.getSampleModelTranslateX(),
                wr.getMinY() - wr.getSampleModelTranslateY(),
                wr.getWidth(),
                wr.getHeight(),
                0,
                0,
                null);

        dstBI = new BufferedImage(dstCMNoA, dstWr, false, null);
      }

      // Divide out alpha if we have it.  We need to do this since
      // the color convert may not be a linear operation which may
      // lead to out of range values.
      ColorModel srcBICM = srcCM;
      WritableRaster srcWr;
      if ((srcCM.hasAlpha() == true) && (srcCM.isAlphaPremultiplied() != false)) {
        Rectangle wrR = wr.getBounds();
        SampleModel sm = srcCM.createCompatibleSampleModel(wrR.width, wrR.height);

        srcWr = Raster.createWritableRaster(sm, new Point(wrR.x, wrR.y));
        src.copyData(srcWr);
        srcBICM = GraphicsUtil.coerceData(srcWr, srcCM, false);
      } else {
        Raster srcRas = src.getData(wr.getBounds());
        srcWr = GraphicsUtil.makeRasterWritable(srcRas);
      }

      BufferedImage srcBI;
      srcBI = new BufferedImage(srcBICM, srcWr.createWritableTranslatedChild(0, 0), false, null);

      /*
       * System.out.println("src: " + srcBI.getWidth() + "x" +
       *                    srcBI.getHeight());
       * System.out.println("dst: " + dstBI.getWidth() + "x" +
       *                    dstBI.getHeight());
       */

      ColorConvertOp op = new ColorConvertOp(null);
      op.filter(srcBI, dstBI);

      if (dstCM.hasAlpha())
        copyBand(
            srcWr, srcSM.getNumBands() - 1,
            wr, getSampleModel().getNumBands() - 1);
    }
    return wr;
  }
Beispiel #5
0
  public void genRect(WritableRaster wr) {
    if (me2src == null) return;

    Rectangle srcR = me2src.createTransformedShape(wr.getBounds()).getBounds();

    // System.out.println("Affine wrR: " + wr.getBounds());
    // System.out.println("Affine srcR: " + srcR);

    // Outset by two pixels so we get context for interpolation...
    srcR.setBounds(srcR.x - 1, srcR.y - 1, srcR.width + 2, srcR.height + 2);

    // Don't try and get data from src that it doesn't have...
    CachableRed src = (CachableRed) getSources().get(0);

    // Raster srcRas = src.getData(srcR);

    if (!srcR.intersects(src.getBounds())) return;
    Raster srcRas = src.getData(srcR.intersection(src.getBounds()));

    if (srcRas == null) return;

    // This works around the problem that the buffered ops
    // completely ignore the coords of the Rasters passed in.
    AffineTransform aff = (AffineTransform) src2me.clone();

    // Translate what is at 0,0 (which will be what our current
    // minX/Y is) to our current minX,minY.
    aff.concatenate(AffineTransform.getTranslateInstance(srcRas.getMinX(), srcRas.getMinY()));

    Point2D srcPt = new Point2D.Float(wr.getMinX(), wr.getMinY());
    srcPt = me2src.transform(srcPt, null);

    Point2D destPt =
        new Point2D.Double(srcPt.getX() - srcRas.getMinX(), srcPt.getY() - srcRas.getMinY());

    destPt = aff.transform(destPt, null);

    // Translate what will be at minX,minY to zero, zero
    // which where java2d will think the real minX,minY is.
    aff.preConcatenate(AffineTransform.getTranslateInstance(-destPt.getX(), -destPt.getY()));

    AffineTransformOp op = new AffineTransformOp(aff, hints);

    BufferedImage srcBI, myBI;
    ColorModel srcCM = src.getColorModel();
    ColorModel myCM = getColorModel();

    WritableRaster srcWR = (WritableRaster) srcRas;
    // If the output buffer is not premultiplied in certain cases
    // it fails to properly divide out the Alpha (it always does
    // the affine on premultiplied data). We help it out by
    // premultiplying for it.
    srcCM = GraphicsUtil.coerceData(srcWR, srcCM, true);
    srcBI =
        new BufferedImage(
            srcCM, srcWR.createWritableTranslatedChild(0, 0), srcCM.isAlphaPremultiplied(), null);

    myBI =
        new BufferedImage(
            myCM, wr.createWritableTranslatedChild(0, 0), myCM.isAlphaPremultiplied(), null);

    op.filter(srcBI, myBI);

    // if ((count % 40) == 0) {
    //     org.apache.batik.ImageDisplay.showImage("Src: " , srcBI);
    //     org.apache.batik.ImageDisplay.showImage("Dst: " , myBI);
    // }
    // count++;
  }