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.geom.*; 021import java.awt.image.*; 022import com.jhlabs.composite.*; 023 024public class ShineFilter extends AbstractBufferedImageOp { 025 026 private float radius = 5; 027 private float angle = (float)Math.PI*7/4; 028 private float distance = 5; 029 private float bevel = 0.5f; 030 private boolean shadowOnly = false; 031 private int shineColor = 0xffffffff; 032 private float brightness = 0.2f; 033 private float softness = 0; 034 035 public ShineFilter() { 036 } 037 038 public void setAngle(float angle) { 039 this.angle = angle; 040 } 041 042 public float getAngle() { 043 return angle; 044 } 045 046 public void setDistance(float distance) { 047 this.distance = distance; 048 } 049 050 public float getDistance() { 051 return distance; 052 } 053 054 /** 055 * Set the radius of the kernel, and hence the amount of blur. The bigger the radius, the longer this filter will take. 056 * @param radius the radius of the blur in pixels. 057 */ 058 public void setRadius(float radius) { 059 this.radius = radius; 060 } 061 062 /** 063 * Get the radius of the kernel. 064 * @return the radius 065 */ 066 public float getRadius() { 067 return radius; 068 } 069 070 public void setBevel(float bevel) { 071 this.bevel = bevel; 072 } 073 074 public float getBevel() { 075 return bevel; 076 } 077 078 public void setShineColor(int shineColor) { 079 this.shineColor = shineColor; 080 } 081 082 public int getShineColor() { 083 return shineColor; 084 } 085 086 public void setShadowOnly(boolean shadowOnly) { 087 this.shadowOnly = shadowOnly; 088 } 089 090 public boolean getShadowOnly() { 091 return shadowOnly; 092 } 093 094 public void setBrightness(float brightness) { 095 this.brightness = brightness; 096 } 097 098 public float getBrightness() { 099 return brightness; 100 } 101 102 public void setSoftness(float softness) { 103 this.softness = softness; 104 } 105 106 public float getSoftness() { 107 return softness; 108 } 109 110 public BufferedImage filter( BufferedImage src, BufferedImage dst ) { 111 int width = src.getWidth(); 112 int height = src.getHeight(); 113 114 if ( dst == null ) 115 dst = createCompatibleDestImage( src, null ); 116 117 float xOffset = distance*(float)Math.cos(angle); 118 float yOffset = -distance*(float)Math.sin(angle); 119 120 BufferedImage matte = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 121 ErodeAlphaFilter s = new ErodeAlphaFilter( bevel * 10, 0.75f, 0.1f ); 122 matte = s.filter( src, null ); 123 124 BufferedImage shineLayer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 125 Graphics2D g = shineLayer.createGraphics(); 126 g.setColor( new Color( shineColor ) ); 127 g.fillRect( 0, 0, width, height ); 128 g.setComposite( AlphaComposite.DstIn ); 129 g.drawRenderedImage( matte, null ); 130 g.setComposite( AlphaComposite.DstOut ); 131 g.translate( xOffset, yOffset ); 132 g.drawRenderedImage( matte, null ); 133 g.dispose(); 134 shineLayer = new GaussianFilter( radius ).filter( shineLayer, null ); 135 shineLayer = new RescaleFilter( 3*brightness ).filter( shineLayer, shineLayer ); 136 137 g = dst.createGraphics(); 138 g.drawRenderedImage( src, null ); 139 g.setComposite( new AddComposite( 1.0f ) ); 140 g.drawRenderedImage( shineLayer, null ); 141 g.dispose(); 142 143 return dst; 144 } 145 146 public String toString() { 147 return "Stylize/Shine..."; 148 } 149}