public void transform(
      FlameTransformationContext pContext,
      XForm pXForm,
      XYZPoint pAffineTP,
      XYZPoint pVarTP,
      double pAmount,
      double pInputX,
      double pInputY) {
    double x = (pInputX - (offsetX + 0.5) + 1.0) / scaleX * (double) (imgWidth - 1);
    double y = (pInputY - (offsetY + 0.5) + 1.0) / scaleY * (double) (imgHeight - 1);
    int ix = Tools.FTOI(x);
    int iy = Tools.FTOI(y);
    if (this.tileX == 1) {
      if (ix < 0) {
        int nx = ix / imgWidth - 1;
        ix -= nx * imgWidth;
      } else if (ix >= imgWidth) {
        int nx = ix / imgWidth;
        ix -= nx * imgWidth;
      }
    }
    if (this.tileY == 1) {
      if (iy < 0) {
        int ny = iy / imgHeight - 1;
        iy -= ny * imgHeight;
      } else if (iy >= imgHeight) {
        int ny = iy / imgHeight;
        iy -= ny * imgHeight;
      }
    }

    double r, g, b;
    if (ix >= 0 && ix < imgWidth && iy >= 0 && iy < imgHeight) {
      if (colorMap instanceof SimpleImage) {
        toolPixel.setARGBValue(((SimpleImage) colorMap).getARGBValue(ix, iy));
        r = (double) toolPixel.r / 255.0;
        g = (double) toolPixel.g / 255.0;
        b = (double) toolPixel.b / 255.0;
      } else {
        ((SimpleHDRImage) colorMap).getRGBValues(rgbArray, ix, iy);
        r = rgbArray[0];
        g = rgbArray[0];
        b = rgbArray[0];
      }
    } else {
      return;
    }

    switch (mode) {
      case MODE_TRANSLATE:
        {
          double amountX = (r - 0.5) * pAmount;
          double amountY = (g - 0.5) * pAmount;
          pVarTP.x += amountX;
          pVarTP.y += amountY;
        }
        break;
      case MODE_SCALE:
        {
          double intensity = calcIntensity(r, g, b) - bias;
          if (intensity > 0.0) {
            double scl = 1.0 + (intensity - 0.5) * pAmount;
            pVarTP.x *= scl;
            pVarTP.y *= scl;
          }
        }
        break;
      case MODE_SCISSOR:
        {
          double amountX = (r - 0.5) * pAmount;
          double amountY = (g - 0.5) * pAmount;
          double newx = pVarTP.x * amountX * amountY + pVarTP.y * amountY;
          double newy = pVarTP.x * amountY - pVarTP.y * amountX * amountY;
          pVarTP.x = newx;
          pVarTP.y = newy;
        }
        break;
      case MODE_ROTATE:
      default:
        {
          double intensity = calcIntensity(r, g, b) - bias;
          if (intensity > 0.0) {
            double angle = intensity * M_2PI * pAmount;
            double sina = sin(angle);
            double cosa = cos(angle);
            double xnew = pVarTP.x * cosa - pVarTP.y * sina;
            double ynew = pVarTP.x * sina + pVarTP.y * cosa;
            pVarTP.x = xnew;
            pVarTP.y = ynew;
          }
        }
    }

    switch (colorMode) {
      case COLOR_MODE_INHERIT:
        {
          pVarTP.rgbColor = true;
          pVarTP.redColor = r;
          pVarTP.greenColor = g;
          pVarTP.blueColor = b;
          pVarTP.color = getColorIdx(r, g, b);
        }
        break;
    }
  }
Example #2
0
  @Override
  protected void fillImage(SimpleImage res) {
    int width = res.getImageWidth();
    int height = res.getImageHeight();
    Random rnd = new Random();
    rnd.setSeed(this.seed);
    double cover = 1.0 - this.cover;
    double aspect = (double) width / (double) height;
    int frequency = this.initialFrequency;
    int frequencyX = (int) (frequency * aspect + 0.5);
    int frequencyY = (int) (frequency * aspect + 0.5);
    double alphaInt = 1.0f;
    BufferedImage mainImage = res.getBufferedImg();
    Graphics2D mainGr = mainImage.createGraphics();

    for (int i = 0; i < this.octaves; i++) {
      // create a small random image
      BufferedImage rndMap = new BufferedImage(frequencyX, frequencyY, BufferedImage.TYPE_INT_ARGB);
      {
        Graphics2D g = rndMap.createGraphics();
        try {
          switch (colorMode) {
            case COLOR:
              for (int x = 0; x < frequencyX; x++) {
                for (int y = 0; y < frequencyY; y++) {
                  int rVal = rnd.nextInt(255);
                  int gVal = rnd.nextInt(255);
                  int bVal = rnd.nextInt(255);
                  g.setColor(new Color(rVal, gVal, bVal, (int) (255.0 * alphaInt + 0.5)));
                  g.fillRect(x, y, 1, 1);
                }
              }
              break;
            case GREY:
              for (int x = 0; x < frequencyX; x++) {
                for (int y = 0; y < frequencyY; y++) {
                  int val = rnd.nextInt(255);
                  g.setColor(new Color(val, val, val, (int) (255.0 * alphaInt + 0.5)));
                  g.fillRect(x, y, 1, 1);
                }
              }
              break;
            case BASE_COLOR:
              int rBase = this.cloudColor.getRed();
              int gBase = this.cloudColor.getGreen();
              int bBase = this.cloudColor.getBlue();
              for (int x = 0; x < frequencyX; x++) {
                for (int y = 0; y < frequencyY; y++) {
                  int val = rnd.nextInt(255);
                  int rVal = (rBase * val) / 255;
                  int gVal = (gBase * val) / 255;
                  int bVal = (bBase * val) / 255;
                  g.setColor(new Color(rVal, gVal, bVal, (int) (255.0 * alphaInt + 0.5)));
                  g.fillRect(x, y, 1, 1);
                }
              }
              break;
          }
        } finally {
          g.dispose();
        }
      }
      // scale up the image using Java-built-in interpolation
      {
        BufferedImage scaledRndMap = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = scaledRndMap.createGraphics();
        try {
          g.setRenderingHint(
              RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
          g.drawImage(rndMap, 0, 0, width, height, 0, 0, frequencyX, frequencyY, null);
        } finally {
          g.dispose();
        }
        mainGr.drawImage(scaledRndMap, null, 0, 0);
      }
      alphaInt *= this.persistence;
      frequency += frequency;
      frequencyX = (int) (frequency * aspect + 0.5);
      frequencyY = (int) (frequency * aspect + 0.5);
    }
    // apply an exponential filter to let the noise more look like clouds
    if (mode == Mode.CLOUDS) {
      final double rWeight = 0.2990;
      final double gWeight = 0.5880;
      final double bWeight = 0.1130;
      SimpleImage bgImg = (this.backgroundImg != null) ? backgroundImg.getImage() : null;
      Pixel pixel = new Pixel();
      Pixel bgPixel = new Pixel();
      for (int i = 0; i < mainImage.getWidth(); i++) {
        for (int j = 0; j < mainImage.getHeight(); j++) {
          pixel.setARGBValue(res.getARGBValue(i, j));
          double lum = pixel.r * rWeight + pixel.g * gWeight + pixel.b * bWeight;
          double c = lum - (cover * 255);
          if (c < 0) c = 0;
          int iVal = Tools.roundColor(255.0 - (Math.pow(this.sharpness, c) * 255.0));
          int bgRed = 0, bgGreen = 0, bgBlue = 0;
          switch (bgMode) {
            case IMAGE:
              if (bgImg != null) {
                bgPixel.setARGBValue(bgImg.getARGBValueIgnoreBounds(i, j));
                bgRed = bgPixel.r;
                bgGreen = bgPixel.g;
                bgBlue = bgPixel.b;
              }
              break;
            case COLOR:
              bgRed = this.bgColor.getRed();
              bgGreen = this.bgColor.getGreen();
              bgBlue = this.bgColor.getBlue();
              break;
          }
          switch (colorMode) {
            case GREY:
              pixel.r = expose(iVal + 1.5 * bgRed);
              pixel.g = expose(iVal + 1.5 * bgGreen);
              pixel.b = expose(iVal + 1.5 * bgBlue);
              break;
            default:
              pixel.r = expose((iVal * pixel.r) / 255 + 1.5 * bgRed);
              pixel.g = expose((iVal * pixel.g) / 255 + 1.5 * bgGreen);
              pixel.b = expose((iVal * pixel.b) / 255 + 1.5 * bgBlue);
              break;
          }
          res.setRGB(i, j, pixel);
        }
      }
    }
  }