Package org.jwildfire.transform

Source Code of org.jwildfire.transform.WindTransformer$DirectionEditor

/*
  JWildfire - an image and animation processor written in Java
  Copyright (C) 1995-2011 Andreas Maschke

  This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser
  General Public License as published by the Free Software Foundation; either version 2.1 of the
  License, or (at your option) any later version.
  This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public License along with this software;
  if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jwildfire.transform;

import org.jwildfire.base.Property;
import org.jwildfire.base.PropertyMax;
import org.jwildfire.base.PropertyMin;
import org.jwildfire.base.Tools;
import org.jwildfire.image.Pixel;
import org.jwildfire.image.SimpleImage;
import org.jwildfire.image.WFImage;

import com.l2fprod.common.beans.editor.ComboBoxPropertyEditor;

public class WindTransformer extends Mesh2DTransformer {
  public enum Direction {
    LEFT, RIGHT
  }

  @Property(description = "Probability of the effect")
  @PropertyMin(0)
  @PropertyMax(100)
  private int probability = 20;

  @Property(description = "Seed for the random number generator")
  @PropertyMin(0)
  private int seed = 123;

  @Property(description = "Intensity of the effect")
  private int intensity = 40;

  @Property(description = "Wind direction", editorClass = DirectionEditor.class)
  private Direction direction = Direction.RIGHT;

  @Override
  protected void performPixelTransformation(WFImage pImg) {
    SimpleImage img = (SimpleImage) pImg;
    int width = pImg.getImageWidth();
    int height = pImg.getImageHeight();
    int contrast = 0;
    short smask[][] = new short[height][width];
    int rs = 2990;
    int gs = 5880;
    int bs = 1130;
    rs = (rs * Tools.VPREC) / 10000;
    gs = (gs * Tools.VPREC) / 10000;
    bs = (bs * Tools.VPREC) / 10000;
    Pixel p0 = new Pixel();
    Pixel p1 = new Pixel();
    Tools.srand123(this.seed);

    /* flip the image */
    if (direction == Direction.LEFT) {
      srcImg = srcImg.clone();
      FlipTransformer ft = new FlipTransformer();
      ft.setAxis(FlipTransformer.Axis.X);
      ft.transformImage(srcImg);
      ft.setAxis(FlipTransformer.Axis.X);
      ft.transformImage(img);
    }

    /** 1st line **/
    for (int i = 0; i < width; i++)
      smask[0][i] = 1;
    /** lines 2...(height-2) **/
    for (int i = 1; i < (height - 1); i++) {
      /* 1st pixel */
      smask[i][0] = 1;
      /* process pixels 2..width-1 */
      for (int j = 1; j < (width - 1); j++) {
        int dd = 0, int1;
        p1.setARGBValue(srcImg.getARGBValue(j - 1, i - 1));
        int1 = (rs * p1.r + gs * p1.g + bs * p1.b) >> Tools.SPREC;
        dd += int1;

        p1.setARGBValue(srcImg.getARGBValue(j + 1, i - 1));
        int1 = (rs * p1.r + gs * p1.g + bs * p1.b) >> Tools.SPREC;
        dd -= int1;

        p1.setARGBValue(srcImg.getARGBValue(j - 1, i));
        int1 = (rs * p1.r + gs * p1.g + bs * p1.b) >> Tools.SPREC;
        dd += int1;

        p1.setARGBValue(srcImg.getARGBValue(j + 1, i));
        int1 = (rs * p1.r + gs * p1.g + bs * p1.b) >> Tools.SPREC;
        dd -= int1;

        p1.setARGBValue(srcImg.getARGBValue(j - 1, i + 1));
        int1 = (rs * p1.r + gs * p1.g + bs * p1.b) >> Tools.SPREC;
        dd += int1;

        p1.setARGBValue(srcImg.getARGBValue(j + 1, i + 1));
        int1 = (rs * p1.r + gs * p1.g + bs * p1.b) >> Tools.SPREC;
        dd -= int1;

        if (dd < contrast) {
          smask[i][j] = 1;
        }
      }
      /* last pixel */
      smask[i][width - 1] = 1;
    }
    /** last line **/
    for (int i = 0; i < width; i++)
      smask[height - 1][i] = 1;

    /** accept only "thick" lines **/
    for (int i = 1; i < (height - 1); i++) {
      for (int j = 1; j < (width - 1); j++) {
        if (smask[i][j] == 0) {
          if (smask[i][j + 1] != 0)
            smask[i][j] = 1;
        }
      }
    }

    /** create "thin" lines **/
    for (int i = 1; i < (height - 1); i++) {
      nextLine: for (int j = (width - 2); j >= 1; j--) {
        if (smask[i][j] == 0) {
          int k = j - 1;
          while (smask[i][k] == 0) {
            smask[i][k] = 1;
            k--;
            if (k < 1)
              continue nextLine;
          }
        }
      }
    }

    /** remove isolated pixels **/
    for (int i = 1; i < (height - 1); i++) {
      for (int j = 1; j < (width - 1); j++) {
        if (smask[i][j] == 0) {
          int dd = 0;
          dd += smask[i][j - 1];
          dd += smask[i][j + 1];
          dd += smask[i - 1][j];
          dd += smask[i + 1][j];
          dd += smask[i + 1][j - 1];
          dd += smask[i + 1][j + 1];
          dd += smask[i - 1][j - 1];
          dd += smask[i - 1][j + 1];
          if (dd == 8)
            smask[i][j] = 1;
        }
      }
    }

    /** apply the changes **/
    int intensity0 = this.intensity;
    int intensity1 = intensity0 / 2;

    {
      double rprob = (double) ((double) 1.0 - (double) this.probability / (double) 100.0);
      for (int i = 0; i < height; i++) {
        cont: for (int j = (width - 1); j >= 0; j--) {
          if ((smask[i][j] == 0) && (Tools.drand() >= rprob)) {
            if (j < 1) {
              continue cont;
            }
            int intensity = intensity0 + (int) (Tools.drand() * intensity1 + 0.5);
            double dm = 100.0 / (double) (intensity - 1);
            int kmax = intensity;
            if ((j + kmax) >= width)
              kmax = width - j;
            for (int k = 0; k < kmax; k++) {
              int mix = (int) (100.0 - (double) k * dm + 0.5);
              int m1 = 100 - mix;
              int m2 = mix;
              p0.setARGBValue(srcImg.getARGBValue(j, i));
              p1.setARGBValue(srcImg.getARGBValue(j + k, i));
              int rv = ((int) ((int) p1.r * m1) + (int) p0.r * m2) / (int) 100;
              int gv = ((int) ((int) p1.g * m1) + (int) p0.g * m2) / (int) 100;
              int bv = ((int) ((int) p1.b * m1) + (int) p0.b * m2) / (int) 100;
              img.setRGB(j + k, i, rv, gv, bv);
            }
          }
        }
      }
    }

    /* flip the image */
    if (direction == Direction.LEFT) {
      FlipTransformer ft = new FlipTransformer();
      ft.setAxis(FlipTransformer.Axis.X);
      ft.transformImage(img);
    }
  }

  @Override
  public void initDefaultParams(WFImage pImg) {
    direction = Direction.RIGHT;
    intensity = 40;
    probability = 20;
    seed = 123;
  }

  public static class DirectionEditor extends ComboBoxPropertyEditor {
    public DirectionEditor() {
      super();
      setAvailableValues(new Direction[] { Direction.LEFT, Direction.RIGHT });
    }
  }

  public int getProbability() {
    return probability;
  }

  public void setProbability(int probability) {
    this.probability = probability;
  }

  public int getSeed() {
    return seed;
  }

  public void setSeed(int seed) {
    this.seed = seed;
  }

  public int getIntensity() {
    return intensity;
  }

  public void setIntensity(int intensity) {
    this.intensity = intensity;
  }

  public Direction getDirection() {
    return direction;
  }

  public void setDirection(Direction direction) {
    this.direction = direction;
  }

}
TOP

Related Classes of org.jwildfire.transform.WindTransformer$DirectionEditor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.