优化验证码的效果和干扰
This commit is contained in:
		
							
								
								
									
										158
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										158
									
								
								pom.xml
									
									
									
									
									
								
							@@ -20,12 +20,6 @@
 | 
				
			|||||||
        </license>
 | 
					        </license>
 | 
				
			||||||
    </licenses>
 | 
					    </licenses>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <parent>
 | 
					 | 
				
			||||||
        <groupId>org.sonatype.oss</groupId>
 | 
					 | 
				
			||||||
        <artifactId>oss-parent</artifactId>
 | 
					 | 
				
			||||||
        <version>7</version>
 | 
					 | 
				
			||||||
    </parent>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <dependencies>
 | 
					    <dependencies>
 | 
				
			||||||
        <!-- j2ee环境 -->
 | 
					        <!-- j2ee环境 -->
 | 
				
			||||||
        <dependency>
 | 
					        <dependency>
 | 
				
			||||||
@@ -50,88 +44,86 @@
 | 
				
			|||||||
                <configuration>
 | 
					                <configuration>
 | 
				
			||||||
                    <source>6</source>
 | 
					                    <source>6</source>
 | 
				
			||||||
                    <target>6</target>
 | 
					                    <target>6</target>
 | 
				
			||||||
 | 
					                    <encoding>UTF-8</encoding>
 | 
				
			||||||
                </configuration>
 | 
					                </configuration>
 | 
				
			||||||
            </plugin>
 | 
					            </plugin>
 | 
				
			||||||
        </plugins>
 | 
					        </plugins>
 | 
				
			||||||
    </build>
 | 
					    </build>
 | 
				
			||||||
 | 
					    <!--
 | 
				
			||||||
 | 
					        <scm>
 | 
				
			||||||
 | 
					            <url>https://github.com/whvcse/EasyCaptcha</url>
 | 
				
			||||||
 | 
					            <connection>https://github.com/whvcse/EasyCaptcha.git</connection>
 | 
				
			||||||
 | 
					            <developerConnection>https://github.com/whvcse/EasyCaptcha</developerConnection>
 | 
				
			||||||
 | 
					        </scm>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <scm>
 | 
					        <developers>
 | 
				
			||||||
        <url>https://github.com/whvcse/EasyCaptcha</url>
 | 
					            <developer>
 | 
				
			||||||
        <connection>scm:git:git@github.com:whvcse/EasyCaptcha</connection>
 | 
					                <name>whvcse</name>
 | 
				
			||||||
        <developerConnection>scm:git:git@github.com:whvcse/EasyCaptcha</developerConnection>
 | 
					                <email>whvcse@foxmail.com</email>
 | 
				
			||||||
        <tag>HEAD</tag>
 | 
					                <url>https://github.com/whvcse</url>
 | 
				
			||||||
    </scm>
 | 
					            </developer>
 | 
				
			||||||
 | 
					        </developers>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <developers>
 | 
					        <distributionManagement>
 | 
				
			||||||
        <developer>
 | 
					            <snapshotRepository>
 | 
				
			||||||
            <name>whvcse</name>
 | 
					                <id>ossrh</id>
 | 
				
			||||||
            <email>whvcse@foxmail.com</email>
 | 
					                <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
 | 
				
			||||||
            <url>https://github.com/whvcse</url>
 | 
					            </snapshotRepository>
 | 
				
			||||||
        </developer>
 | 
					            <repository>
 | 
				
			||||||
    </developers>
 | 
					                <id>ossrh</id>
 | 
				
			||||||
 | 
					                <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
 | 
				
			||||||
 | 
					            </repository>
 | 
				
			||||||
 | 
					        </distributionManagement>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <distributionManagement>
 | 
					        <profiles>
 | 
				
			||||||
        <snapshotRepository>
 | 
					            <profile>
 | 
				
			||||||
            <id>oss</id>
 | 
					                <id>release</id>
 | 
				
			||||||
            <name>OSS Snapshots Repository</name>
 | 
					                <build>
 | 
				
			||||||
            <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
 | 
					                    <plugins>
 | 
				
			||||||
        </snapshotRepository>
 | 
					                        <!– Source –>
 | 
				
			||||||
        <repository>
 | 
					                        <plugin>
 | 
				
			||||||
            <id>oss</id>
 | 
					                            <groupId>org.apache.maven.plugins</groupId>
 | 
				
			||||||
            <name>OSS Staging Repository</name>
 | 
					                            <artifactId>maven-source-plugin</artifactId>
 | 
				
			||||||
            <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
 | 
					                            <version>2.2.1</version>
 | 
				
			||||||
        </repository>
 | 
					                            <executions>
 | 
				
			||||||
    </distributionManagement>
 | 
					                                <execution>
 | 
				
			||||||
 | 
					                                    <id>attach-sources</id>
 | 
				
			||||||
    <profiles>
 | 
					                                    <goals>
 | 
				
			||||||
        <profile>
 | 
					                                        <goal>jar-no-fork</goal>
 | 
				
			||||||
            <id>release</id>
 | 
					                                    </goals>
 | 
				
			||||||
            <build>
 | 
					                                </execution>
 | 
				
			||||||
                <plugins>
 | 
					                            </executions>
 | 
				
			||||||
                    <!-- Source -->
 | 
					                        </plugin>
 | 
				
			||||||
                    <plugin>
 | 
					                        <!– Javadoc –>
 | 
				
			||||||
                        <groupId>org.apache.maven.plugins</groupId>
 | 
					                        <plugin>
 | 
				
			||||||
                        <artifactId>maven-source-plugin</artifactId>
 | 
					                            <groupId>org.apache.maven.plugins</groupId>
 | 
				
			||||||
                        <version>2.2.1</version>
 | 
					                            <artifactId>maven-javadoc-plugin</artifactId>
 | 
				
			||||||
                        <executions>
 | 
					                            <version>2.9.1</version>
 | 
				
			||||||
                            <execution>
 | 
					                            <executions>
 | 
				
			||||||
                                <phase>package</phase>
 | 
					                                <execution>
 | 
				
			||||||
                                <goals>
 | 
					                                    <id>attach-javadocs</id>
 | 
				
			||||||
                                    <goal>jar-no-fork</goal>
 | 
					                                    <goals>
 | 
				
			||||||
                                </goals>
 | 
					                                        <goal>jar</goal>
 | 
				
			||||||
                            </execution>
 | 
					                                    </goals>
 | 
				
			||||||
                        </executions>
 | 
					                                </execution>
 | 
				
			||||||
                    </plugin>
 | 
					                            </executions>
 | 
				
			||||||
                    <!-- Javadoc -->
 | 
					                        </plugin>
 | 
				
			||||||
                    <plugin>
 | 
					                        <plugin>
 | 
				
			||||||
                        <groupId>org.apache.maven.plugins</groupId>
 | 
					                            <groupId>org.apache.maven.plugins</groupId>
 | 
				
			||||||
                        <artifactId>maven-javadoc-plugin</artifactId>
 | 
					                            <artifactId>maven-gpg-plugin</artifactId>
 | 
				
			||||||
                        <version>2.9.1</version>
 | 
					                            <version>1.5</version>
 | 
				
			||||||
                        <executions>
 | 
					                            <executions>
 | 
				
			||||||
                            <execution>
 | 
					                                <execution>
 | 
				
			||||||
                                <phase>package</phase>
 | 
					                                    <id>sign-artifacts</id>
 | 
				
			||||||
                                <goals>
 | 
					                                    <phase>verify</phase>
 | 
				
			||||||
                                    <goal>jar</goal>
 | 
					                                    <goals>
 | 
				
			||||||
                                </goals>
 | 
					                                        <goal>sign</goal>
 | 
				
			||||||
                            </execution>
 | 
					                                    </goals>
 | 
				
			||||||
                        </executions>
 | 
					                                </execution>
 | 
				
			||||||
                    </plugin>
 | 
					                            </executions>
 | 
				
			||||||
                    <plugin>
 | 
					                        </plugin>
 | 
				
			||||||
                        <groupId>org.apache.maven.plugins</groupId>
 | 
					                    </plugins>
 | 
				
			||||||
                        <artifactId>maven-gpg-plugin</artifactId>
 | 
					                </build>
 | 
				
			||||||
                        <version>1.5</version>
 | 
					            </profile>
 | 
				
			||||||
                        <executions>
 | 
					        </profiles>-->
 | 
				
			||||||
                            <execution>
 | 
					 | 
				
			||||||
                                <id>sign-artifacts</id>
 | 
					 | 
				
			||||||
                                <phase>verify</phase>
 | 
					 | 
				
			||||||
                                <goals>
 | 
					 | 
				
			||||||
                                    <goal>sign</goal>
 | 
					 | 
				
			||||||
                                </goals>
 | 
					 | 
				
			||||||
                            </execution>
 | 
					 | 
				
			||||||
                        </executions>
 | 
					 | 
				
			||||||
                    </plugin>
 | 
					 | 
				
			||||||
                </plugins>
 | 
					 | 
				
			||||||
            </build>
 | 
					 | 
				
			||||||
        </profile>
 | 
					 | 
				
			||||||
    </profiles>
 | 
					 | 
				
			||||||
</project>
 | 
					</project>
 | 
				
			||||||
@@ -9,10 +9,10 @@ import java.io.OutputStream;
 | 
				
			|||||||
 * Created by 王帆 on 2018-07-27 上午 10:08.
 | 
					 * Created by 王帆 on 2018-07-27 上午 10:08.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public abstract class Captcha extends Randoms {
 | 
					public abstract class Captcha extends Randoms {
 | 
				
			||||||
    protected Font font = new Font("Verdana", Font.ITALIC | Font.BOLD, 28); // 字体
 | 
					    protected Font font = new Font("Verdana", Font.PLAIN, 32); // 字体
 | 
				
			||||||
    protected int len = 5; // 验证码随机字符长度
 | 
					    protected int len = 5; // 验证码随机字符长度
 | 
				
			||||||
    protected int width = 150; // 验证码显示宽度
 | 
					    protected int width = 130; // 验证码显示宽度
 | 
				
			||||||
    protected int height = 40; // 验证码显示高度
 | 
					    protected int height = 48; // 验证码显示高度
 | 
				
			||||||
    private String chars = null; // 当前验证码
 | 
					    private String chars = null; // 当前验证码
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -97,6 +97,13 @@ public class Encoder {
 | 
				
			|||||||
    byte[] accum = new byte[256];
 | 
					    byte[] accum = new byte[256];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //----------------------------------------------------------------------------
 | 
					    //----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param width       宽度
 | 
				
			||||||
 | 
					     * @param height      高度
 | 
				
			||||||
 | 
					     * @param pixels      像素
 | 
				
			||||||
 | 
					     * @param color_depth 颜色
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    Encoder(int width, int height, byte[] pixels, int color_depth) {
 | 
					    Encoder(int width, int height, byte[] pixels, int color_depth) {
 | 
				
			||||||
        imgW = width;
 | 
					        imgW = width;
 | 
				
			||||||
        imgH = height;
 | 
					        imgH = height;
 | 
				
			||||||
@@ -106,6 +113,12 @@ public class Encoder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // Add a character to the end of the current packet, and if it is 254
 | 
					    // Add a character to the end of the current packet, and if it is 254
 | 
				
			||||||
    // characters, flush the packet to disk.
 | 
					    // characters, flush the packet to disk.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param c    字节
 | 
				
			||||||
 | 
					     * @param outs 输出流
 | 
				
			||||||
 | 
					     * @throws IOException IO异常
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void char_out(byte c, OutputStream outs) throws IOException {
 | 
					    void char_out(byte c, OutputStream outs) throws IOException {
 | 
				
			||||||
        accum[a_count++] = c;
 | 
					        accum[a_count++] = c;
 | 
				
			||||||
        if (a_count >= 254)
 | 
					        if (a_count >= 254)
 | 
				
			||||||
@@ -115,6 +128,11 @@ public class Encoder {
 | 
				
			|||||||
    // Clear out the hash table
 | 
					    // Clear out the hash table
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // table clear for block compress
 | 
					    // table clear for block compress
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param outs 输出流
 | 
				
			||||||
 | 
					     * @throws IOException IO异常
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void cl_block(OutputStream outs) throws IOException {
 | 
					    void cl_block(OutputStream outs) throws IOException {
 | 
				
			||||||
        cl_hash(hsize);
 | 
					        cl_hash(hsize);
 | 
				
			||||||
        free_ent = ClearCode + 2;
 | 
					        free_ent = ClearCode + 2;
 | 
				
			||||||
@@ -124,11 +142,20 @@ public class Encoder {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // reset code table
 | 
					    // reset code table
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param hsize int
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void cl_hash(int hsize) {
 | 
					    void cl_hash(int hsize) {
 | 
				
			||||||
        for (int i = 0; i < hsize; ++i)
 | 
					        for (int i = 0; i < hsize; ++i)
 | 
				
			||||||
            htab[i] = -1;
 | 
					            htab[i] = -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param init_bits int
 | 
				
			||||||
 | 
					     * @param outs      输出流
 | 
				
			||||||
 | 
					     * @throws IOException IO异常
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void compress(int init_bits, OutputStream outs) throws IOException {
 | 
					    void compress(int init_bits, OutputStream outs) throws IOException {
 | 
				
			||||||
        int fcode;
 | 
					        int fcode;
 | 
				
			||||||
        int i /* = 0 */;
 | 
					        int i /* = 0 */;
 | 
				
			||||||
@@ -201,6 +228,11 @@ public class Encoder {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //----------------------------------------------------------------------------
 | 
					    //----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param os 输出流
 | 
				
			||||||
 | 
					     * @throws IOException IO异常
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void encode(OutputStream os) throws IOException {
 | 
					    void encode(OutputStream os) throws IOException {
 | 
				
			||||||
        os.write(initCodeSize); // write "initial code size" byte
 | 
					        os.write(initCodeSize); // write "initial code size" byte
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -213,6 +245,11 @@ public class Encoder {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Flush the packet to disk, and reset the accumulator
 | 
					    // Flush the packet to disk, and reset the accumulator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param outs 输出流
 | 
				
			||||||
 | 
					     * @throws IOException IO异常
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void flush_char(OutputStream outs) throws IOException {
 | 
					    void flush_char(OutputStream outs) throws IOException {
 | 
				
			||||||
        if (a_count > 0) {
 | 
					        if (a_count > 0) {
 | 
				
			||||||
            outs.write(a_count);
 | 
					            outs.write(a_count);
 | 
				
			||||||
@@ -221,6 +258,10 @@ public class Encoder {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param n_bits int
 | 
				
			||||||
 | 
					     * @return int
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    final int MAXCODE(int n_bits) {
 | 
					    final int MAXCODE(int n_bits) {
 | 
				
			||||||
        return (1 << n_bits) - 1;
 | 
					        return (1 << n_bits) - 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -228,6 +269,10 @@ public class Encoder {
 | 
				
			|||||||
    //----------------------------------------------------------------------------
 | 
					    //----------------------------------------------------------------------------
 | 
				
			||||||
    // Return the next pixel from the image
 | 
					    // Return the next pixel from the image
 | 
				
			||||||
    //----------------------------------------------------------------------------
 | 
					    //----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @return int
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    private int nextPixel() {
 | 
					    private int nextPixel() {
 | 
				
			||||||
        if (remaining == 0)
 | 
					        if (remaining == 0)
 | 
				
			||||||
            return EOF;
 | 
					            return EOF;
 | 
				
			||||||
@@ -239,6 +284,11 @@ public class Encoder {
 | 
				
			|||||||
        return pix & 0xff;
 | 
					        return pix & 0xff;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * @param code int
 | 
				
			||||||
 | 
					     * @param outs 输出流
 | 
				
			||||||
 | 
					     * @throws IOException IO异常
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    void output(int code, OutputStream outs) throws IOException {
 | 
					    void output(int code, OutputStream outs) throws IOException {
 | 
				
			||||||
        cur_accum &= masks[cur_bits];
 | 
					        cur_accum &= masks[cur_bits];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,6 @@
 | 
				
			|||||||
package com.wf.captcha;
 | 
					package com.wf.captcha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.awt.AlphaComposite;
 | 
					import java.awt.*;
 | 
				
			||||||
import java.awt.Color;
 | 
					 | 
				
			||||||
import java.awt.Font;
 | 
					 | 
				
			||||||
import java.awt.Graphics2D;
 | 
					 | 
				
			||||||
import java.awt.image.BufferedImage;
 | 
					import java.awt.image.BufferedImage;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.io.OutputStream;
 | 
					import java.io.OutputStream;
 | 
				
			||||||
@@ -82,12 +79,26 @@ public class GifCaptcha extends Captcha {
 | 
				
			|||||||
        int h = height - ((height - font.getSize()) >> 1);
 | 
					        int h = height - ((height - font.getSize()) >> 1);
 | 
				
			||||||
        int w = width / len;
 | 
					        int w = width / len;
 | 
				
			||||||
        g2d.setFont(font);
 | 
					        g2d.setFont(font);
 | 
				
			||||||
 | 
					        // 随机画干扰线
 | 
				
			||||||
 | 
					        for (int i = 0; i < 8; i++) {
 | 
				
			||||||
 | 
					            int x1 = num(-10, width - 10);
 | 
				
			||||||
 | 
					            int y1 = num(5, height - 5);
 | 
				
			||||||
 | 
					            int x2 = num(10, width + 10);
 | 
				
			||||||
 | 
					            int y2 = num(2, height - 2);
 | 
				
			||||||
 | 
					            g2d.setColor(color(150, 250));
 | 
				
			||||||
 | 
					            g2d.setStroke(new BasicStroke(1.3f));
 | 
				
			||||||
 | 
					            g2d.drawLine(x1, y1, x2, y2);
 | 
				
			||||||
 | 
					            // 画干扰圆圈
 | 
				
			||||||
 | 
					            g2d.setColor(color(100, 250));
 | 
				
			||||||
 | 
					            g2d.setStroke(new BasicStroke(1.0f));
 | 
				
			||||||
 | 
					            g2d.drawOval(num(width), num(height), 5 + num(10), 5 + num(10));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 画验证码
 | 
				
			||||||
        for (int i = 0; i < len; i++) {
 | 
					        for (int i = 0; i < len; i++) {
 | 
				
			||||||
            ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getAlpha(flag, i));
 | 
					            ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getAlpha(flag, i));
 | 
				
			||||||
            g2d.setComposite(ac3);
 | 
					            g2d.setComposite(ac3);
 | 
				
			||||||
            g2d.setColor(fontcolor[i]);
 | 
					            g2d.setColor(fontcolor[i]);
 | 
				
			||||||
            g2d.drawOval(num(width), num(height), 5 + num(10), 5 + num(10));
 | 
					            g2d.drawString(String.valueOf(strs[i]), (width - (len - i) * w) + (w - font.getSize()) + num(7, 11), h - num(2, 6));
 | 
				
			||||||
            g2d.drawString(String.valueOf(strs[i]), (width - (len - i) * w) + (w - font.getSize()) + 1, h - 4);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        g2d.dispose();
 | 
					        g2d.dispose();
 | 
				
			||||||
        return image;
 | 
					        return image;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -79,7 +79,6 @@ public class GifEncoder {
 | 
				
			|||||||
     * image is added.
 | 
					     * image is added.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param iter int number of iterations.
 | 
					     * @param iter int number of iterations.
 | 
				
			||||||
     * @return
 | 
					 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public void setRepeat(int iter) {
 | 
					    public void setRepeat(int iter) {
 | 
				
			||||||
        if (iter >= 0) {
 | 
					        if (iter >= 0) {
 | 
				
			||||||
@@ -168,6 +167,8 @@ public class GifEncoder {
 | 
				
			|||||||
     * Flushes any pending data and closes output file.
 | 
					     * Flushes any pending data and closes output file.
 | 
				
			||||||
     * If writing to an OutputStream, the stream is not
 | 
					     * If writing to an OutputStream, the stream is not
 | 
				
			||||||
     * closed.
 | 
					     * closed.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return boolean
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public boolean finish() {
 | 
					    public boolean finish() {
 | 
				
			||||||
        if (!started) return false;
 | 
					        if (!started) return false;
 | 
				
			||||||
@@ -219,7 +220,6 @@ public class GifEncoder {
 | 
				
			|||||||
     * than 20 do not yield significant improvements in speed.
 | 
					     * than 20 do not yield significant improvements in speed.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param quality int greater than 0.
 | 
					     * @param quality int greater than 0.
 | 
				
			||||||
     * @return
 | 
					 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public void setQuality(int quality) {
 | 
					    public void setQuality(int quality) {
 | 
				
			||||||
        if (quality < 1) quality = 1;
 | 
					        if (quality < 1) quality = 1;
 | 
				
			||||||
@@ -319,6 +319,9 @@ public class GifEncoder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns index of palette color closest to c
 | 
					     * Returns index of palette color closest to c
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param c color
 | 
				
			||||||
 | 
					     * @return int
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    protected int findClosest(Color c) {
 | 
					    protected int findClosest(Color c) {
 | 
				
			||||||
        if (colorTab == null) return -1;
 | 
					        if (colorTab == null) return -1;
 | 
				
			||||||
@@ -365,6 +368,8 @@ public class GifEncoder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Writes Graphic Control Extension
 | 
					     * Writes Graphic Control Extension
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws IOException IO异常
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    protected void writeGraphicCtrlExt() throws IOException {
 | 
					    protected void writeGraphicCtrlExt() throws IOException {
 | 
				
			||||||
        out.write(0x21); // extension introducer
 | 
					        out.write(0x21); // extension introducer
 | 
				
			||||||
@@ -396,6 +401,8 @@ public class GifEncoder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Writes Image Descriptor
 | 
					     * Writes Image Descriptor
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws IOException IO异常
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    protected void writeImageDesc() throws IOException {
 | 
					    protected void writeImageDesc() throws IOException {
 | 
				
			||||||
        out.write(0x2c); // image separator
 | 
					        out.write(0x2c); // image separator
 | 
				
			||||||
@@ -419,6 +426,8 @@ public class GifEncoder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Writes Logical Screen Descriptor
 | 
					     * Writes Logical Screen Descriptor
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws IOException IO异常
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    protected void writeLSD() throws IOException {
 | 
					    protected void writeLSD() throws IOException {
 | 
				
			||||||
        // logical screen size
 | 
					        // logical screen size
 | 
				
			||||||
@@ -437,6 +446,8 @@ public class GifEncoder {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Writes Netscape application extension to define
 | 
					     * Writes Netscape application extension to define
 | 
				
			||||||
     * repeat count.
 | 
					     * repeat count.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws IOException IO异常
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    protected void writeNetscapeExt() throws IOException {
 | 
					    protected void writeNetscapeExt() throws IOException {
 | 
				
			||||||
        out.write(0x21); // extension introducer
 | 
					        out.write(0x21); // extension introducer
 | 
				
			||||||
@@ -451,6 +462,8 @@ public class GifEncoder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Writes color table
 | 
					     * Writes color table
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws IOException IO异常
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    protected void writePalette() throws IOException {
 | 
					    protected void writePalette() throws IOException {
 | 
				
			||||||
        out.write(colorTab, 0, colorTab.length);
 | 
					        out.write(colorTab, 0, colorTab.length);
 | 
				
			||||||
@@ -462,6 +475,8 @@ public class GifEncoder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Encodes and writes pixel data
 | 
					     * Encodes and writes pixel data
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @throws IOException IO异常
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    protected void writePixels() throws IOException {
 | 
					    protected void writePixels() throws IOException {
 | 
				
			||||||
        Encoder encoder = new Encoder(width, height, indexedPixels, colorDepth);
 | 
					        Encoder encoder = new Encoder(width, height, indexedPixels, colorDepth);
 | 
				
			||||||
@@ -470,6 +485,9 @@ public class GifEncoder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Write 16-bit value to output stream, LSB first
 | 
					     * Write 16-bit value to output stream, LSB first
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param value int
 | 
				
			||||||
 | 
					     * @throws IOException IO异常
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    protected void writeShort(int value) throws IOException {
 | 
					    protected void writeShort(int value) throws IOException {
 | 
				
			||||||
        out.write(value & 0xff);
 | 
					        out.write(value & 0xff);
 | 
				
			||||||
@@ -478,6 +496,9 @@ public class GifEncoder {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Writes string to output stream
 | 
					     * Writes string to output stream
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param s string
 | 
				
			||||||
 | 
					     * @throws IOException IO异常
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    protected void writeString(String s) throws IOException {
 | 
					    protected void writeString(String s) throws IOException {
 | 
				
			||||||
        for (int i = 0; i < s.length(); i++) {
 | 
					        for (int i = 0; i < s.length(); i++) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,6 @@
 | 
				
			|||||||
package com.wf.captcha;
 | 
					package com.wf.captcha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.awt.AlphaComposite;
 | 
					import java.awt.*;
 | 
				
			||||||
import java.awt.Color;
 | 
					 | 
				
			||||||
import java.awt.Font;
 | 
					 | 
				
			||||||
import java.awt.Graphics2D;
 | 
					 | 
				
			||||||
import java.awt.image.BufferedImage;
 | 
					import java.awt.image.BufferedImage;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.io.OutputStream;
 | 
					import java.io.OutputStream;
 | 
				
			||||||
@@ -59,30 +56,31 @@ public class SpecCaptcha extends Captcha {
 | 
				
			|||||||
            BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
 | 
					            BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
 | 
				
			||||||
            Graphics2D g = (Graphics2D) bi.getGraphics();
 | 
					            Graphics2D g = (Graphics2D) bi.getGraphics();
 | 
				
			||||||
            AlphaComposite ac3;
 | 
					            AlphaComposite ac3;
 | 
				
			||||||
            Color color;
 | 
					 | 
				
			||||||
            int len = strs.length;
 | 
					            int len = strs.length;
 | 
				
			||||||
            g.setColor(Color.WHITE);
 | 
					            g.setColor(Color.WHITE);
 | 
				
			||||||
            g.fillRect(0, 0, width, height);
 | 
					            g.fillRect(0, 0, width, height);
 | 
				
			||||||
            // 随机画干扰的圆圈
 | 
					            // 随机画干扰线
 | 
				
			||||||
            for (int i = 0; i < 15; i++) {
 | 
					            for (int i = 0; i < 12; i++) {
 | 
				
			||||||
                color = color(150, 250);
 | 
					                int x1 = num(-10, width - 10);
 | 
				
			||||||
                g.setColor(color);
 | 
					                int y1 = num(5, height - 5);
 | 
				
			||||||
                g.drawOval(num(width), num(height), 5 + num(10), 5 + num(10));
 | 
					                int x2 = num(10, width + 10);
 | 
				
			||||||
                color = null;
 | 
					                int y2 = num(2, height - 2);
 | 
				
			||||||
 | 
					                g.setColor(color(150, 250));
 | 
				
			||||||
 | 
					                g.setStroke(new BasicStroke(1.3f));
 | 
				
			||||||
 | 
					                g.drawLine(x1, y1, x2, y2);
 | 
				
			||||||
 | 
					                // 画干扰圆圈
 | 
				
			||||||
 | 
					                g.setColor(color(100, 250));
 | 
				
			||||||
 | 
					                g.drawOval(num(width), num(height), 5 + num(25), 5 + num(25));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            g.setFont(font);
 | 
					            g.setFont(new Font(font.getFontName(), Font.ITALIC, font.getSize()));
 | 
				
			||||||
            int h = height - ((height - font.getSize()) >> 1);
 | 
					            int h = height - ((height - font.getSize()) >> 1);
 | 
				
			||||||
            int w = width / len;
 | 
					            int w = width / len;
 | 
				
			||||||
            int size = w - font.getSize() + 1;
 | 
					 | 
				
			||||||
            // 画字符串
 | 
					            // 画字符串
 | 
				
			||||||
            for (int i = 0; i < len; i++) {
 | 
					            for (int i = 0; i < len; i++) {
 | 
				
			||||||
                ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f);// 指定透明度
 | 
					                ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.75f);// 指定透明度
 | 
				
			||||||
                g.setComposite(ac3);
 | 
					                g.setComposite(ac3);
 | 
				
			||||||
                color = new Color(20 + num(110), 20 + num(110), 20 + num(110));// 对每个字符都用随机颜色
 | 
					                g.setColor(new Color(20 + num(110), 20 + num(110), 20 + num(110)));
 | 
				
			||||||
                g.setColor(color);
 | 
					                g.drawString(String.valueOf(strs[i]), (width - (len - i) * w) + (w - font.getSize()) + num(7, 11), h - num(2, 6));
 | 
				
			||||||
                g.drawString(String.valueOf(strs[i]), (width - (len - i) * w) + size, h - 4);
 | 
					 | 
				
			||||||
                color = null;
 | 
					 | 
				
			||||||
                ac3 = null;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            ImageIO.write(bi, "png", out);
 | 
					            ImageIO.write(bi, "png", out);
 | 
				
			||||||
            out.flush();
 | 
					            out.flush();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,10 @@ public class CaptchaUtil {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 验证验证码
 | 
					     * 验证验证码
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param code    用户输入的验证码
 | 
				
			||||||
 | 
					     * @param request HttpServletRequest
 | 
				
			||||||
 | 
					     * @return 是否正确
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static boolean ver(String code, HttpServletRequest request) {
 | 
					    public static boolean ver(String code, HttpServletRequest request) {
 | 
				
			||||||
        if (code != null && !code.trim().isEmpty()) {
 | 
					        if (code != null && !code.trim().isEmpty()) {
 | 
				
			||||||
@@ -29,26 +33,26 @@ public class CaptchaUtil {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 输出验证码
 | 
					     * 输出验证码
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param request
 | 
					     * @param request  HttpServletRequest
 | 
				
			||||||
     * @param response
 | 
					     * @param response HttpServletResponse
 | 
				
			||||||
     * @throws IOException
 | 
					     * @throws IOException IO异常
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static void out(HttpServletRequest request, HttpServletResponse response)
 | 
					    public static void out(HttpServletRequest request, HttpServletResponse response)
 | 
				
			||||||
            throws IOException {
 | 
					            throws IOException {
 | 
				
			||||||
        out(130, 38, 5, request, response);
 | 
					        out(5, request, response);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 输出验证码
 | 
					     * 输出验证码
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param len      长度
 | 
					     * @param len      长度
 | 
				
			||||||
     * @param request
 | 
					     * @param request  HttpServletRequest
 | 
				
			||||||
     * @param response
 | 
					     * @param response HttpServletResponse
 | 
				
			||||||
     * @throws IOException
 | 
					     * @throws IOException IO异常
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static void out(int len, HttpServletRequest request, HttpServletResponse response)
 | 
					    public static void out(int len, HttpServletRequest request, HttpServletResponse response)
 | 
				
			||||||
            throws IOException {
 | 
					            throws IOException {
 | 
				
			||||||
        out(130, 38, len, request, response);
 | 
					        out(130, 48, len, request, response);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -57,14 +61,14 @@ public class CaptchaUtil {
 | 
				
			|||||||
     * @param width    宽度
 | 
					     * @param width    宽度
 | 
				
			||||||
     * @param height   高度
 | 
					     * @param height   高度
 | 
				
			||||||
     * @param len      长度
 | 
					     * @param len      长度
 | 
				
			||||||
     * @param request
 | 
					     * @param request  HttpServletRequest
 | 
				
			||||||
     * @param response
 | 
					     * @param response HttpServletResponse
 | 
				
			||||||
     * @throws IOException
 | 
					     * @throws IOException IO异常
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static void out(int width, int height, int len, HttpServletRequest request, HttpServletResponse response)
 | 
					    public static void out(int width, int height, int len, HttpServletRequest request, HttpServletResponse response)
 | 
				
			||||||
            throws IOException {
 | 
					            throws IOException {
 | 
				
			||||||
        setHeader(response);
 | 
					        setHeader(response);
 | 
				
			||||||
        Captcha captcha = new GifCaptcha(130, 38, 5);
 | 
					        Captcha captcha = new GifCaptcha(width, height, len);
 | 
				
			||||||
        request.getSession().setAttribute(SESSION_KEY, captcha.text().toLowerCase());
 | 
					        request.getSession().setAttribute(SESSION_KEY, captcha.text().toLowerCase());
 | 
				
			||||||
        captcha.out(response.getOutputStream());
 | 
					        captcha.out(response.getOutputStream());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -72,7 +76,7 @@ public class CaptchaUtil {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 设置相应头
 | 
					     * 设置相应头
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param response
 | 
					     * @param response HttpServletResponse
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private static void setHeader(HttpServletResponse response) {
 | 
					    private static void setHeader(HttpServletResponse response) {
 | 
				
			||||||
        response.setContentType("image/gif");
 | 
					        response.setContentType("image/gif");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,14 +13,14 @@ public class CaptchaTest {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void test() throws Exception {
 | 
					    public void test() throws Exception {
 | 
				
			||||||
        SpecCaptcha specCaptcha = new SpecCaptcha(150, 40, 4);
 | 
					        SpecCaptcha specCaptcha = new SpecCaptcha();
 | 
				
			||||||
        System.out.println(specCaptcha.text());
 | 
					        System.out.println(specCaptcha.text());
 | 
				
			||||||
        specCaptcha.out(new FileOutputStream(new File("D:/a/aa.png")));
 | 
					        specCaptcha.out(new FileOutputStream(new File("D:/a/aa.png")));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void testGIf() throws Exception {
 | 
					    public void testGIf() throws Exception {
 | 
				
			||||||
        GifCaptcha specCaptcha = new GifCaptcha(150, 40, 4);
 | 
					        GifCaptcha specCaptcha = new GifCaptcha(130, 48, 5);
 | 
				
			||||||
        System.out.println(specCaptcha.text());
 | 
					        System.out.println(specCaptcha.text());
 | 
				
			||||||
        specCaptcha.out(new FileOutputStream(new File("D:/a/aa.gif")));
 | 
					        specCaptcha.out(new FileOutputStream(new File("D:/a/aa.gif")));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user