/**
   * Draw and resizes (transparent) image. Calls writeImage(...).
   *
   * @param image image to be drawn
   * @param dx1 destination image bounds
   * @param dy1 destination image bounds
   * @param dx2 destination image bounds
   * @param dy2 destination image bounds
   * @param sx1 source image bounds
   * @param sy1 source image bounds
   * @param sx2 source image bounds
   * @param sy2 source image bounds
   * @param bgColor background color
   * @param observer for updates if image still incomplete
   * @return true if successful
   */
  public boolean drawImage(
      Image image,
      int dx1,
      int dy1,
      int dx2,
      int dy2,
      int sx1,
      int sy1,
      int sx2,
      int sy2,
      Color bgColor,
      ImageObserver observer) {
    try {
      int srcX = Math.min(sx1, sx2);
      int srcY = Math.min(sy1, sy2);
      int srcWidth = Math.abs(sx2 - sx1);
      int srcHeight = Math.abs(sy2 - sy1);
      int width = Math.abs(dx2 - dx1);
      int height = Math.abs(dy2 - dy1);

      if ((srcX != 0)
          || (srcY != 0)
          || (srcWidth != image.getWidth(observer))
          || (srcHeight != image.getHeight(observer))) {
        // crop the source image
        ImageFilter crop = new CropImageFilter(srcX, srcY, srcWidth, srcHeight);
        image =
            Toolkit.getDefaultToolkit()
                .createImage(new FilteredImageSource(image.getSource(), crop));
        MediaTracker mediaTracker = new MediaTracker(new Panel());
        mediaTracker.addImage(image, 0);
        try {
          mediaTracker.waitForAll();
        } catch (InterruptedException e) {
          handleException(e);
        }
      }

      boolean flipHorizontal = (dx2 < dx1) ^ (sx2 < sx1); // src flipped
      // and not dest
      // flipped or
      // vice versa
      boolean flipVertical = (dy2 < dy1) ^ (sy2 < sy1); // <=> source
      // flipped XOR
      // dest flipped

      double tx = (flipHorizontal) ? (double) dx2 : (double) dx1;
      double ty = (flipVertical) ? (double) dy2 : (double) dy1;

      double sx = (double) width / srcWidth;
      sx = flipHorizontal ? -1 * sx : sx;
      double sy = (double) height / srcHeight;
      sy = flipVertical ? -1 * sy : sy;

      writeImage(
          ImageUtilities.createRenderedImage(image, observer, bgColor),
          new AffineTransform(sx, 0, 0, sy, tx, ty),
          bgColor);
      return true;
    } catch (IOException e) {
      handleException(e);
      return false;
    }
  }
 public boolean drawImage(Image image, AffineTransform xform, ImageObserver observer) {
   drawRenderedImage(ImageUtilities.createRenderedImage(image, observer, null), xform);
   return true;
 }