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.image.*; 020import java.util.*; 021 022public class SparkleFilter extends PointFilter { 023 024 private int rays = 50; 025 private int radius = 25; 026 private int amount = 50; 027 private int color = 0xffffffff; 028 private int randomness = 25; 029 private int width, height; 030 private int centreX, centreY; 031 private long seed = 371; 032 private float[] rayLengths; 033 private Random randomNumbers = new Random(); 034 035 public SparkleFilter() { 036 } 037 038 public void setColor(int color) { 039 this.color = color; 040 } 041 042 public int getColor() { 043 return color; 044 } 045 046 public void setRandomness(int randomness) { 047 this.randomness = randomness; 048 } 049 050 public int getRandomness() { 051 return randomness; 052 } 053 054 /** 055 * Set the amount of sparkle. 056 * @param amount the amount 057 * @min-value 0 058 * @max-value 1 059 * @see #getAmount 060 */ 061 public void setAmount(int amount) { 062 this.amount = amount; 063 } 064 065 /** 066 * Get the amount of sparkle. 067 * @return the amount 068 * @see #setAmount 069 */ 070 public int getAmount() { 071 return amount; 072 } 073 074 public void setRays(int rays) { 075 this.rays = rays; 076 } 077 078 public int getRays() { 079 return rays; 080 } 081 082 /** 083 * Set the radius of the effect. 084 * @param radius the radius 085 * @min-value 0 086 * @see #getRadius 087 */ 088 public void setRadius(int radius) { 089 this.radius = radius; 090 } 091 092 /** 093 * Get the radius of the effect. 094 * @return the radius 095 * @see #setRadius 096 */ 097 public int getRadius() { 098 return radius; 099 } 100 101 public void setDimensions(int width, int height) { 102 this.width = width; 103 this.height = height; 104 centreX = width/2; 105 centreY = height/2; 106 super.setDimensions(width, height); 107 randomNumbers.setSeed(seed); 108 rayLengths = new float[rays]; 109 for (int i = 0; i < rays; i++) 110 rayLengths[i] = radius + randomness / 100.0f * radius * (float)randomNumbers.nextGaussian(); 111 } 112 113 public int filterRGB(int x, int y, int rgb) { 114 float dx = x-centreX; 115 float dy = y-centreY; 116 float distance = dx*dx+dy*dy; 117 float angle = (float)Math.atan2(dy, dx); 118 float d = (angle+ImageMath.PI) / (ImageMath.TWO_PI) * rays; 119 int i = (int)d; 120 float f = d - i; 121 122 if (radius != 0) { 123 float length = ImageMath.lerp(f, rayLengths[i % rays], rayLengths[(i+1) % rays]); 124 float g = length*length / (distance+0.0001f); 125 g = (float)Math.pow(g, (100-amount) / 50.0); 126 f -= 0.5f; 127// f *= amount/50.0f; 128 f = 1 - f*f; 129 f *= g; 130 } 131 f = ImageMath.clamp(f, 0, 1); 132 return ImageMath.mixColors(f, rgb, color); 133 } 134 135 public String toString() { 136 return "Stylize/Sparkle..."; 137 } 138}