Package org.jwildfire.transform

Source Code of org.jwildfire.transform.ScaleTransformer$UnitEditor

/*
  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.PropertyMin;
import org.jwildfire.base.Tools;
import org.jwildfire.image.Pixel;
import org.jwildfire.image.SimpleImage;
import org.jwildfire.image.WFImage;
import org.jwildfire.swing.Buffer.BufferType;
import org.jwildfire.swing.ScaleAspectEditor;

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

public class ScaleTransformer extends Transformer {
  public enum Unit {
    PIXELS, PERCENT
  }

  @Property(description = "Scale unit", editorClass = UnitEditor.class)
  private Unit unit = Unit.PIXELS;

  @Property(description = "How to treat the aspect ratio of the original", editorClass = ScaleAspectEditor.class)
  private ScaleAspect aspect = ScaleAspect.KEEP_WIDTH;

  @Property(description = "Width of the scaled image")
  @PropertyMin(1)
  private int scaleWidth = 320;

  @Property(description = "Height of the scaled image")
  @PropertyMin(1)
  private int scaleHeight = 256;

  public static class UnitEditor extends ComboBoxPropertyEditor {
    public UnitEditor() {
      super();
      setAvailableValues(new Unit[] { Unit.PERCENT, Unit.PIXELS });
    }
  }

  public Unit getUnit() {
    return unit;
  }

  public void setUnit(Unit unit) {
    this.unit = unit;
  }

  public ScaleAspect getAspect() {
    return aspect;
  }

  public void setAspect(ScaleAspect aspect) {
    this.aspect = aspect;
  }

  public int getScaleWidth() {
    return scaleWidth;
  }

  public void setScaleWidth(int scaleWidth) {
    this.scaleWidth = scaleWidth;
  }

  public int getScaleHeight() {
    return scaleHeight;
  }

  public void setScaleHeight(int scaleHeight) {
    this.scaleHeight = scaleHeight;
  }

  @Override
  public boolean supports3DOutput() {
    return false;
  }

  @Override
  protected void performImageTransformation(WFImage pImg) {
    SimpleImage img = (SimpleImage) pImg;
    int srcWidth = pImg.getImageWidth();
    int srcHeight = pImg.getImageHeight();
    double width, height;
    if (unit == Unit.PIXELS) {
      width = (double) scaleWidth;
      height = (double) scaleHeight;
    }
    else {
      width = (double) scaleWidth / 100.0 * (double) srcWidth;
      height = (double) scaleHeight / 100.0 * (double) srcHeight;
    }
    if (aspect == ScaleAspect.KEEP_WIDTH) {
      double scl = width / (double) srcWidth;
      height = (double) srcHeight * scl;
    }
    else if (aspect == ScaleAspect.KEEP_HEIGHT) {
      double scl = height / (double) srcHeight;
      width = (double) srcWidth * scl;
    }
    int dstWidth = (int) (width + 0.5);
    if (dstWidth < 1)
      dstWidth = 1;
    int dstHeight = (int) (height + 0.5);
    if (dstHeight < 1)
      dstHeight = 1;
    SimpleImage srcImg = img.clone();
    img.resetImage(dstWidth, dstHeight);

    if ((dstWidth >= srcWidth) && (dstHeight >= srcHeight))
      scale_up_up(srcImg, img);
    else if ((dstWidth < srcWidth) && (dstHeight >= srcHeight))
      scale_down_up(srcImg, img);
    else if ((dstWidth >= srcWidth) && (dstHeight < srcHeight))
      scale_up_down(srcImg, img);
    else if ((dstWidth < srcWidth) && (dstHeight < srcHeight))
      scale_down_down(srcImg, img);
  }

  private void scale_up_up(SimpleImage srcImg, SimpleImage dstImg) {
    int swidth = srcImg.getImageWidth();
    int sheight = srcImg.getImageHeight();
    int width = dstImg.getImageWidth();
    int height = dstImg.getImageHeight();
    double sclX, sclY;
    if (width > 1) {
      sclX = (double) (swidth - 1) / (double) (width - 1);
    }
    else
      sclX = 1.0;
    if (height > 1) {
      sclY = (double) (sheight - 1) / (double) (height - 1);
    }
    else
      sclY = 1.0;
    double cxD = (double) (width - 1) * 0.5;
    double cyD = (double) (height - 1) * 0.5;
    double cxS = (double) (swidth - 1) * 0.5;
    double cyS = (double) (sheight - 1) * 0.5;
    Pixel pPixel = new Pixel();

    for (int i = 0; i < height; i++) {
      double y0 = (double) i - cyD;
      double y = y0 * sclY + cyS;
      for (int j = 0; j < width; j++) {
        // transform the point
        double x0 = (double) j - cxD;
        double x = x0 * sclX + cxS;

        // render it           
        if (((int) x < 0) || ((int) x >= swidth) || ((int) y < 0) || ((int) y >= sheight)) {
          pPixel.r = pPixel.g = pPixel.b = 0;
        }
        else {
          double xi = Tools.fmod33(x);
          double yi = Tools.fmod33(y);
          readSrcPixels(srcImg, x, y);
          pPixel.r = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.r) + xi * (srcQ.r)) + yi
              * ((1.0 - xi) * (srcR.r) + xi * (srcS.r))));
          pPixel.g = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.g) + xi * (srcQ.g)) + yi
              * ((1.0 - xi) * (srcR.g) + xi * (srcS.g))));
          pPixel.b = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.b) + xi * (srcQ.b)) + yi
              * ((1.0 - xi) * (srcR.b) + xi * (srcS.b))));
        }
        dstImg.setRGB(j, i, pPixel.r, pPixel.g, pPixel.b);
      }
    }
  }

  private void scale_down_up(SimpleImage srcImg, SimpleImage dstImg) {
    int swidth = srcImg.getImageWidth();
    int sheight = srcImg.getImageHeight();
    int width = dstImg.getImageWidth();
    int height = dstImg.getImageHeight();

    double sclX, sclY;
    if (width > 1) {
      sclX = (double) (swidth - 1) / (double) (width - 1);
    }
    else
      sclX = 1.0;
    if (height > 1) {
      sclY = (double) (sheight - 1) / (double) (height - 1);
    }
    else
      sclY = 1.0;
    double cxD = (double) (width - 1) * 0.5;
    double cyD = (double) (height - 1) * 0.5;
    double cxS = (double) (swidth - 1) * 0.5;
    double cyS = (double) (sheight - 1) * 0.5;
    Pixel pPixel = new Pixel();

    for (int i = 0; i < height; i++) {
      double y0 = (double) i - cyD;
      double y = y0 * sclY + cyS;
      for (int j = 0; j < width; j++) {
        // transform the point
        double x0 = (double) j - cxD;
        double x = x0 * sclX + cxS;
        double xn = (x0 + 1.0) * sclX + cxS;
        if (xn >= (swidth - 0.5))
          xn = swidth - 1.0;

        if (((int) x < 0) || ((int) x >= swidth) || ((int) y < 0) || ((int) y >= sheight)) {
          pPixel.r = pPixel.g = pPixel.b = 0;
        }
        else {
          double xi = Tools.fmod33(x);
          double yi = Tools.fmod33(y);
          readSrcPixels(srcImg, x, y);
          int cvalR = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.r) + xi * (srcQ.r)) + yi
              * ((1.0 - xi) * (srcR.r) + xi * (srcS.r))));
          int cvalG = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.g) + xi * (srcQ.g)) + yi
              * ((1.0 - xi) * (srcR.g) + xi * (srcS.g))));
          int cvalB = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.b) + xi * (srcQ.b)) + yi
              * ((1.0 - xi) * (srcR.b) + xi * (srcS.b))));

          x = x - xi + 1.0;
          int cnt = 1;
          while (x < xn) {
            readSrcPixels(srcImg, x, y);
            cvalR += (1.0 - yi) * srcP.r + yi * srcR.r;
            cvalG += (1.0 - yi) * srcP.g + yi * srcR.g;
            cvalB += (1.0 - yi) * srcP.b + yi * srcR.b;
            x += 1.0;
            cnt++;
          }
          pPixel.r = roundColor(cvalR / (double) cnt);
          pPixel.g = roundColor(cvalG / (double) cnt);
          pPixel.b = roundColor(cvalB / (double) cnt);
        }
        dstImg.setRGB(j, i, pPixel.r, pPixel.g, pPixel.b);
      }
    }
  }

  private void scale_up_down(SimpleImage srcImg, SimpleImage dstImg) {
    int swidth = srcImg.getImageWidth();
    int sheight = srcImg.getImageHeight();
    int width = dstImg.getImageWidth();
    int height = dstImg.getImageHeight();
    double sclX, sclY;
    if (width > 1) {
      sclX = (double) (swidth - 1) / (double) (width - 1);
    }
    else
      sclX = 1.0;
    if (height > 1) {
      sclY = (double) (sheight - 1) / (double) (height - 1);
    }
    else
      sclY = 1.0;
    double cxD = (double) (width - 1) * 0.5;
    double cyD = (double) (height - 1) * 0.5;
    double cxS = (double) (swidth - 1) * 0.5;
    double cyS = (double) (sheight - 1) * 0.5;
    Pixel pPixel = new Pixel();

    for (int i = 0; i < height; i++) {
      double y0 = (double) i - cyD;
      double yn = (y0 + 1.0) * sclY + cyS;
      if (yn >= (sheight - 0.5))
        yn = sheight - 1.0;
      for (int j = 0; j < width; j++) {
        // transform the point
        double x0 = (double) j - cxD;
        double x = x0 * sclX + cxS;
        double y = y0 * sclY + cyS;

        if (((int) x < 0) || ((int) x >= swidth) || ((int) y < 0) || ((int) y >= sheight)) {
          pPixel.r = pPixel.g = pPixel.b = 0;
        }
        else {
          double xi = Tools.fmod33(x);
          double yi = Tools.fmod33(y);
          readSrcPixels(srcImg, x, y);
          int cvalR = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.r) + xi * (srcQ.r)) + yi
              * ((1.0 - xi) * (srcR.r) + xi * (srcS.r))));
          int cvalG = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.g) + xi * (srcQ.g)) + yi
              * ((1.0 - xi) * (srcR.g) + xi * (srcS.g))));
          int cvalB = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.b) + xi * (srcQ.b)) + yi
              * ((1.0 - xi) * (srcR.b) + xi * (srcS.b))));
          y = y - yi + 1.0;
          int cnt = 1;
          while (y < yn) {
            readSrcPixels(srcImg, x, y);
            cvalR += (1.0 - xi) * srcP.r + xi * srcQ.r;
            cvalG += (1.0 - xi) * srcP.g + xi * srcQ.g;
            cvalB += (1.0 - xi) * srcP.b + xi * srcQ.b;
            y += 1.0;
            cnt++;
          }
          pPixel.r = roundColor(cvalR / (double) cnt);
          pPixel.g = roundColor(cvalG / (double) cnt);
          pPixel.b = roundColor(cvalB / (double) cnt);
        }
        dstImg.setRGB(j, i, pPixel.r, pPixel.g, pPixel.b);
      }
    }
  }

  private void scale_down_down(SimpleImage srcImg, SimpleImage dstImg) {
    int swidth = srcImg.getImageWidth();
    int sheight = srcImg.getImageHeight();
    int width = dstImg.getImageWidth();
    int height = dstImg.getImageHeight();
    double sclX, sclY;
    if (width > 1) {
      sclX = (double) (swidth - 1) / (double) (width - 1);
    }
    else
      sclX = 1.0;
    if (height > 1) {
      sclY = (double) (sheight - 1) / (double) (height - 1);
    }
    else
      sclY = 1.0;
    double cxD = (double) (width - 1) * 0.5;
    double cyD = (double) (height - 1) * 0.5;
    double cxS = (double) (swidth - 1) * 0.5;
    double cyS = (double) (sheight - 1) * 0.5;
    Pixel pPixel = new Pixel();

    for (int i = 0; i < height; i++) {
      double y0 = (double) i - cyD;
      for (int j = 0; j < width; j++) {
        // transform the point
        double x0 = (double) j - cxD;
        double x = x0 * sclX + cxS;
        double xn = (x0 + 1.0) * sclX + cxS;
        if (xn >= (swidth - 0.5))
          xn = swidth - 1.0;
        double y = y0 * sclY + cyS;
        double yn = (y0 + 1.0) * sclY + cyS;
        if (yn >= (sheight - 0.5))
          yn = sheight - 1.0;

        // render it
        if (((int) x < 0) || ((int) x >= swidth) || ((int) y < 0) || ((int) y >= sheight)) {
          pPixel.r = pPixel.g = pPixel.b = 0;
        }
        else {
          double xi = Tools.fmod33(x);
          double yi = Tools.fmod33(y);
          readSrcPixels(srcImg, x, y);
          // 1st line
          readSrcPixels(srcImg, x, y);
          int cvalR = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.r) + xi * (srcQ.r)) + yi
              * ((1.0 - xi) * (srcR.r) + xi * (srcS.r))));
          int cvalG = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.g) + xi * (srcQ.g)) + yi
              * ((1.0 - xi) * (srcR.g) + xi * (srcS.g))));
          int cvalB = roundColor(((1.0 - yi) * ((1.0 - xi) * (srcP.b) + xi * (srcQ.b)) + yi
              * ((1.0 - xi) * (srcR.b) + xi * (srcS.b))));
          double xc = x - xi + 1.0;
          int cnt = 1;
          while (xc < xn) {
            readSrcPixels(srcImg, x, y);
            cvalR += (1.0 - yi) * srcP.r + yi * srcR.r;
            cvalG += (1.0 - yi) * srcP.g + yi * srcR.g;
            cvalB += (1.0 - yi) * srcP.b + yi * srcR.b;
            xc += 1.0;
            cnt++;
          }
          // remaining lines
          y = y - yi + 1.0;
          while (y < yn) {
            // 1st point
            readSrcPixels(srcImg, x, y);
            cvalR += (1.0 - xi) * srcP.r + xi * srcQ.r;
            cvalG += (1.0 - xi) * srcP.g + xi * srcQ.g;
            cvalB += (1.0 - xi) * srcP.b + xi * srcQ.b;
            // remaining points
            xc = x - xi + 1.0;
            cnt++;
            while (xc < xn) {
              readSrcPixels(srcImg, x, y);
              cvalR += srcP.r;
              cvalG += srcP.g;
              cvalB += srcP.b;
              xc += 1.0;
              cnt++;
            }
            y += 1.0;
          }
          pPixel.r = roundColor(cvalR / (double) cnt);
          pPixel.g = roundColor(cvalG / (double) cnt);
          pPixel.b = roundColor(cvalB / (double) cnt);
        }
        dstImg.setRGB(j, i, pPixel.r, pPixel.g, pPixel.b);
      }
    }
  }

  double fmod33(double arg) {
    return (arg - (double) ((int) arg));
  }

  @Override
  public void initDefaultParams(WFImage pImg) {
    unit = Unit.PIXELS;
    aspect = ScaleAspect.KEEP_WIDTH;
    scaleWidth = 320;
    scaleHeight = 256;
  }

  public boolean acceptsInputBufferType(BufferType pBufferType) {
    return (pBufferType == BufferType.IMAGE);
  }

  protected Pixel srcP = new Pixel();
  protected Pixel srcQ = new Pixel();
  protected Pixel srcR = new Pixel();
  protected Pixel srcS = new Pixel();

  protected void readSrcPixels(SimpleImage srcImg, double pX, double pY) {
    int x = (int) (pX + 0.5);
    int y = (int) (pY + 0.5);
    int w = srcImg.getImageWidth();
    int h = srcImg.getImageHeight();
    if ((x < 0) || (x >= w) || (y < 0) || (y >= h)) {
      srcP.clear();
      srcQ.clear();
      srcR.clear();
      srcS.clear();
    }
    else {
      srcP.setARGBValue(srcImg.getBufferedImg().getRGB(x, y));
      if (x < w - 1)
        srcQ.setARGBValue(srcImg.getBufferedImg().getRGB(x + 1, y));
      else
        srcQ.assign(srcP);
      if (y < h - 1) {
        srcR.setARGBValue(srcImg.getBufferedImg().getRGB(x, y + 1));
        if (x < w - 1)
          srcS.setARGBValue(srcImg.getBufferedImg().getRGB(x + 1, y + 1));
        else
          srcS.assign(srcQ);
      }
      else {
        srcR.assign(srcP);
        srcS.assign(srcQ);
      }
    }
  }

  @Override
  protected boolean allowShowStats() {
    return false;
  }

}
TOP

Related Classes of org.jwildfire.transform.ScaleTransformer$UnitEditor

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.