captcha

Ketan Jetty
enthusiasm for technology

captcha

getCaptcha.cfm and how to use it with image tag
<!--- How to use the captcha code.
<img src="getCaptcha.cfm" />
--->

<!--- getCaptcha.cfm 
- store this page as getCaptcha.cfm
- this page will stream the captcha image as a stream --->
<cfsetting showdebugoutput="false">

<cfset captchaObj = CreateObject("java", "CaptchaAPI")>
<cfset captchaObj.setImageSize(180, 60)>
<cfset captchaObj.setBgColor(255, 255, 255)>	<!--- white --->
<cfset captchaObj.setFgColor(51, 51, 51)>		<!--- grey20 --->
<cfset captchaData = captchaObj.getRandomText()>
<cfset session.captchaData = trim(captchaData)>
<cfset blnTxtRipple = true>
<cfset blnBgLines = false>
<cfset blnBgRipple = false> 

<!--- getCaptcha(session.captchaData) is an overloaded method --->
<cfset img = captchaObj.getByteArray(captchaObj.getCaptcha(session.captchaData, blnTxtRipple, blnBgLines, blnBgRipple))>

<!--- stream the pic as JPEG --->
<cfscript>
    context = getPageContext();
    context.setFlushOutput(false);
    response = context.getResponse().getResponse();
    out = response.getOutputStream();
    response.setContentType("image/jpeg");
    response.setContentLength(arrayLen(img));
    out.write(img);
    out.flush();
    out.close();
</cfscript>

Captcha code in Java (can be used in coldfusion as a JAR)
/**
 * Author:	Ketan Jetty
 *  
 * NOTE: Part of the code is used from:
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * destributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.ByteArrayOutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
import com.jhlabs.image.RippleFilter;

public class CaptchaAPI {
	private Random random;
	private int width;
	private int height;
	private Color fgColor;
	private Color bgColor;
	private boolean blnTxtRipple;
	private boolean blnBgLines;
	private boolean blnBgRipple;
	private RippleFilter rippleFilter;
	
	public CaptchaAPI() {
		random = new Random(System.currentTimeMillis());
		width = 180;
		height = 60;
		fgColor = new Color(0, 0, 0);			// BLACK
		bgColor = new Color(255, 255, 255);		// WHITE
		blnTxtRipple = true;
		blnBgLines = false;
		blnBgRipple = false;
		rippleFilter = new RippleFilter();
	}

	public static void main(String[] args) {
		Timer t = new Timer();
		t.start();
		/*** CODE START ***/
		
		try {
			CaptchaAPI c2 = new CaptchaAPI();
			
			c2.setImageSize(180, 60);
			c2.setBgColor(240, 230, 140);
			c2.setFgColor(205, 92, 92);
			String txtRandom = c2.getRandomText();
			BufferedImage bufferredImage = c2.getCaptcha(txtRandom, true, true, true);
			
			c2.writeImageToJPG(bufferredImage);
			c2.getByteArray(bufferredImage);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		/*** CODE END ***/
		t.end();
		System.out.println("\n" + t.duration());
	}
	
	public void setImageSize(int width, int height) {
		this.width = width;
		this.height = height;
	}

	public void setBgColor(int r, int g, int b) {
		try {
			bgColor = new Color(r, g, b);
		} catch (Exception e) {
			e.printStackTrace();
			
			// default set the color to WHITE
			bgColor = new Color(255, 255, 255);
		}
	}

	public void setFgColor(int r, int g, int b) {	
		try {
			fgColor = new Color(r, g, b);
		} catch (Exception e) {
			e.printStackTrace();
			
			// default set the color to BLACK
			fgColor = new Color(0, 0, 0);
		}
	}

	public void writeImageToJPG(BufferedImage bufferredImage) {	
		try { 			
			ImageIO.write(bufferredImage, "jpeg", new File("c:\\temp\\testImg.jpg") );
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public byte[] getByteArray(BufferedImage bufferredImage) {	
		byte[] bytesOut = null;
			
		try { 	
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			ImageIO.write(bufferredImage, "jpeg", baos);
			bytesOut = baos.toByteArray();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return bytesOut;
	}
	
	public String getRandomText() {
		int len = (int) (4 + (Math.random() * 4));
		byte[] buf = new byte[len * 2];
		char[] text = new char[len];
		int i = 0;
		
		while (i < text.length) {
			random.nextBytes(buf);
			byte b = buf[i];
	
			if ((b >= 'a' && b <= 'y' || (b >= 'A' && b <= 'Y') || (b >= '3' && b <= '7'))
					&& b != 'B'	&& b != '8' && b != 'b'	&& b != '6'	&& b != 'i'	&& b != 'I' && b != 'l' 
					&& b != 'L'	&& b != 'O'	&& b != 'o'	&& b != 'Q'	&& b != 'q' && b != 'S' 
					&& b != 's' && b != '5') {
				text[i++] = (char) b;
	
				if (i >= text.length)
					break;
			}
		}
	
		String retVal = new String(text).toLowerCase().trim();
	
		return retVal;
	}

	public BufferedImage getCaptcha(String txtRandom) {
		BufferedImage captchaImage = null;
		
		try {
			captchaImage = createBgImage();
			Graphics2D g2d = captchaImage.createGraphics();
			g2d.drawImage(createTextImage(txtRandom), 0, 0, null);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return captchaImage;
	}
	
	public BufferedImage getCaptcha(String txtRandom, boolean blnTxtRipple) {
		BufferedImage captchaImage = null;
		
		try {
			this.blnTxtRipple = blnTxtRipple;
			captchaImage = getCaptcha(txtRandom);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return captchaImage;
	}
	
	public BufferedImage getCaptcha(String txtRandom, boolean blnTxtRipple, boolean blnBgLines) {
		BufferedImage captchaImage = null;
		
		try {
			this.blnTxtRipple = blnTxtRipple;
			this.blnBgLines = blnBgLines;
			captchaImage = getCaptcha(txtRandom);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return captchaImage;
	}
	
	public BufferedImage getCaptcha(String txtRandom, boolean blnTxtRipple, boolean blnBgLines, boolean blnBgRipple) {
		BufferedImage captchaImage = null;
		
		try {
			this.blnTxtRipple = blnTxtRipple;
			this.blnBgLines = blnBgLines;
			this.blnBgRipple = blnBgRipple;
			captchaImage = getCaptcha(txtRandom);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return captchaImage;
	}
		
	private BufferedImage createBgImage( ) {
		BufferedImage bgImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		Graphics2D g2d = bgImage.createGraphics();
		g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
		
		// set the background color
		g2d.setColor(bgColor);
		g2d.fillRect(0, 0, width, height);
		
		// draw vertical and horizontal lines
		if (this.blnBgLines) {
			drawRandomLines(g2d, fgColor);
		}
		
		//ripple the image
		if (this.blnBgRipple) {
			rippleImage(bgImage);
		}
		
		return bgImage;
	}

	private BufferedImage createTextImage(String  randomText) {	
		BufferedImage textImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
		Graphics2D g2d = textImage.createGraphics();
		Font font = new Font("serif", Font.BOLD, 30);
		g2d.setFont(font);
		g2d.setColor(fgColor);
		Rectangle2D textBounds = font.getStringBounds(randomText, g2d.getFontRenderContext());
		
		//write text to the image
		g2d.drawString(randomText,
				(int) ((width / 2) - (textBounds.getWidth() / 2)),
				(int) (((height / 2) + (textBounds.getHeight() / 2))
						- g2d.getFontMetrics().getDescent() - 5));
		
		//ripple the text image
		if (this.blnTxtRipple) {
			rippleImage(textImage);
		}
		
		return textImage;	
	}

	private void drawRandomLines(Graphics2D g2d, Color color) {
		g2d.setColor(color);
		int i = 0;
		do {
			i += (int) (Math.random() * 30);
			g2d.drawLine(0, i, width, i);
		} while (i < height);
		// Draw vertical lines
		i = 0;
		do {
			i += (int) (Math.random() * 30);
			g2d.drawLine(i, 0, i, height);
		} while (i < width);
	}

	private void rippleImage(BufferedImage image) {
		rippleFilter.setWaveType(RippleFilter.SINE);
		float xAmplitude = 5f + (float) (Math.random() * 5f);
		float xWavelength = 5f + (float) (Math.random() * 5f);
		float yAmplitude = 10f + (float) (Math.random() * 5f);
		float yWavelength = 20f + (float) (Math.random() * 5f);
	
		if (xAmplitude > xWavelength) {
			float tmp = xAmplitude;
			xAmplitude = xWavelength;
			xWavelength = tmp;
		}
		if (yAmplitude > yWavelength) {
			float tmp = yAmplitude;
			yAmplitude = yWavelength;
			yWavelength = tmp;
		}
	
		rippleFilter.setXAmplitude(xAmplitude);
		rippleFilter.setXWavelength(xWavelength);
		rippleFilter.setYAmplitude(yAmplitude);
		rippleFilter.setYWavelength(yWavelength);
		rippleFilter.setEdgeAction(RippleFilter.WRAP);
		rippleFilter.filter(image, image);
	}
}



public class Timer
{
	private long start;
	private long end;

	public Timer() {
		reset();
	}

	public void start() {
		System.gc();
		start = System.currentTimeMillis();
	}

	public void end() {
		System.gc();
		end = System.currentTimeMillis();
	}

	public long duration() {
		return (end - start);
	}

	public void reset() {
		start = 0;
		end = 0;
	}

	public static void main(String s[]) {
		// simple example
		// Timer t = new Timer();
		// t.start();
		// for (int i=0; i < 80; i++){ System.out.print(".");}
		// t.end();
		// System.out.println("\n" + t.duration());
	}
}

coldfusion


CF Quick Reference


Ginger CMS
the future of cms, a simple, easy and intutive content management system ... more


CFTurbine
cf prototyping engine, generates boilerplate code and ... more


Jrun monitor
monitor and timely auto-restart to avoid Jrun hang ... more


Inheritance Config.
uses OOPs inheritance to create configuration file ... more


Real Estate App.
complete real estate application using data from MLS ... more


Search Engine Lite
create your own search engine for your web site ... more