001/* 002Copyright 2006 Jerry Huxtable 003 004Licensed under the Apache License, Version 2.0 (the "License"); 005you may not use this file except in compliance with the License. 006You may obtain a copy of the License at 007 008 http://www.apache.org/licenses/LICENSE-2.0 009 010Unless required by applicable law or agreed to in writing, software 011distributed under the License is distributed on an "AS IS" BASIS, 012WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013See the License for the specific language governing permissions and 014limitations under the License. 015*/ 016 017package com.jhlabs.image; 018 019import java.awt.*; 020import java.awt.image.*; 021import com.jhlabs.math.*; 022 023/** 024 * This filter applies a marbling effect to an image, displacing pixels by random amounts. 025 */ 026public class MarbleFilter extends TransformFilter { 027 028 private float[] sinTable, cosTable; 029 private float xScale = 4; 030 private float yScale = 4; 031 private float amount = 1; 032 private float turbulence = 1; 033 034 public MarbleFilter() { 035 setEdgeAction(CLAMP); 036 } 037 038 /** 039 * Set the X scale of the effect. 040 * @param xScale the scale. 041 * @see #getXScale 042 */ 043 public void setXScale(float xScale) { 044 this.xScale = xScale; 045 } 046 047 /** 048 * Get the X scale of the effect. 049 * @return the scale. 050 * @see #setXScale 051 */ 052 public float getXScale() { 053 return xScale; 054 } 055 056 /** 057 * Set the Y scale of the effect. 058 * @param yScale the scale. 059 * @see #getYScale 060 */ 061 public void setYScale(float yScale) { 062 this.yScale = yScale; 063 } 064 065 /** 066 * Get the Y scale of the effect. 067 * @return the scale. 068 * @see #setYScale 069 */ 070 public float getYScale() { 071 return yScale; 072 } 073 074 /** 075 * Set the amount of effect. 076 * @param amount the amount 077 * @min-value 0 078 * @max-value 1 079 * @see #getAmount 080 */ 081 public void setAmount(float amount) { 082 this.amount = amount; 083 } 084 085 /** 086 * Get the amount of effect. 087 * @return the amount 088 * @see #setAmount 089 */ 090 public float getAmount() { 091 return amount; 092 } 093 094 /** 095 * Specifies the turbulence of the effect. 096 * @param turbulence the turbulence of the effect. 097 * @min-value 0 098 * @max-value 1 099 * @see #getTurbulence 100 */ 101 public void setTurbulence(float turbulence) { 102 this.turbulence = turbulence; 103 } 104 105 /** 106 * Returns the turbulence of the effect. 107 * @return the turbulence of the effect. 108 * @see #setTurbulence 109 */ 110 public float getTurbulence() { 111 return turbulence; 112 } 113 114 private void initialize() { 115 sinTable = new float[256]; 116 cosTable = new float[256]; 117 for (int i = 0; i < 256; i++) { 118 float angle = ImageMath.TWO_PI*i/256f*turbulence; 119 sinTable[i] = (float)(-yScale*Math.sin(angle)); 120 cosTable[i] = (float)(yScale*Math.cos(angle)); 121 } 122 } 123 124 private int displacementMap(int x, int y) { 125 return PixelUtils.clamp((int)(127 * (1+Noise.noise2(x / xScale, y / xScale)))); 126 } 127 128 protected void transformInverse(int x, int y, float[] out) { 129 int displacement = displacementMap(x, y); 130 out[0] = x + sinTable[displacement]; 131 out[1] = y + cosTable[displacement]; 132 } 133 134 public BufferedImage filter( BufferedImage src, BufferedImage dst ) { 135 initialize(); 136 return super.filter( src, dst ); 137 } 138 139 public String toString() { 140 return "Distort/Marble..."; 141 } 142}