java生成动态gif格式与png格式的验证码(代码2)
来源:互联网 发布:hash算法的实现原理 编辑:程序博客网 时间:2024/05/01 20:33
- import java.awt.AlphaComposite;
- import java.awt.Color;
- import java.awt.Font;
- import java.awt.Graphics2D;
- import java.awt.image.BufferedImage;
- import java.io.OutputStream;
- import java.util.Random;
- /**
- * Gif验证码类
- * @author wzztestin
- *
- */
- public class GifCaptcha extends Captcha {
- public GifCaptcha() {
- }
- public GifCaptcha(int width, int height) {
- this.width = width;
- this.height = height;
- }
- public GifCaptcha(int width, int height, int alpha) {
- this(width, height);
- }
- public GifCaptcha(int width, int height, int alpha, Font font) {
- this(width, height, alpha);
- this.font = font;
- }
- @Override
- public void out(OutputStream os) {
- try {
- //是一个用来生成 GIF 图片格式的 Java 图形处理类库
- GifEncoder gifEncoder = new GifEncoder();
- //生成字符
- gifEncoder.start(os);
- //品质
- gifEncoder.setQuality(180);
- //推迟
- gifEncoder.setDelay(200);
- //重复
- gifEncoder.setRepeat(0);
- BufferedImage frame;
- char[] rands = this.getYanzhenmastr().toCharArray();
- Color fontcolor[] = new Color[rands.length];
- for (int i = 0; i < rands.length; i++) {
- fontcolor[i] = new Color(20 + Randoms.num(110),
- 20 + Randoms.num(110), 20 + Randoms.num(110));
- }
- int start = 8;
- for (int i = 0; i < rands.length; i++) {
- frame = graphicsImage(fontcolor, rands, i,start);
- //添加帧图
- gifEncoder.addFrame(frame);
- start = start + 8;
- //输出
- frame.flush();
- }
- gifEncoder.finish();
- } finally {
- Streams.close(os);
- }
- }
- /**
- * 画随机码图
- *
- * @param fontcolor
- * 随机字体颜色
- * @param strs
- * 字符数组
- * @param flag
- * 透明度使用
- * @return BufferedImage
- */
- private BufferedImage graphicsImage(Color[] fontcolor, char[] strs, int flag,int start) {
- BufferedImage image = new BufferedImage(width, height,
- BufferedImage.TYPE_INT_RGB);
- Random r = new Random();
- // 或得图形上下文
- // Graphics2D g2d=image.createGraphics();
- Graphics2D g2d = (Graphics2D) image.getGraphics();
- // 利用指定颜色填充背景
- g2d.setColor(Color.WHITE);
- g2d.fillRect(0, 0, width, height);
- g2d.setColor(getRandColor(120, 200));
- for (int i = 0; i < 200; i++) {
- int x = r.nextInt(width - 1);
- int y = r.nextInt(height - 1);
- int xl = r.nextInt(6) + 1;
- int yl = r.nextInt(12) + 1;
- g2d.drawLine(x, y, x + xl, y + yl);
- }
- for (int i = 0; i < 100; i++) {
- int x = r.nextInt(width - 1);
- int y = r.nextInt(height - 1);
- int xl = r.nextInt(12) + 1;
- int yl = r.nextInt(6) + 1;
- g2d.drawLine(x, y, x - xl, y - yl);
- }
- int degree = r.nextInt(20);//旋转度数 最好小于45度
- if (flag % 2 == 1){
- degree = degree * (-1);
- }
- g2d.rotate(Math.toRadians(degree), start, 21);
- //类实现一些基本的 alpha 合成规则,将源色与目标色组合,在图形和图像中实现混合和透明效果。
- AlphaComposite ac3;
- //得到写入所需的宽和高
- int h = height - ((height - font.getSize()) >> 1);
- int w = width / strs.length;
- //设置字体
- g2d.setFont(font);
- //画圈和字符
- for (int i = 0; i < strs.length; i++) {
- ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
- getAlpha(flag, i));
- g2d.setComposite(ac3);
- g2d.setColor(fontcolor[i]);
- //画圈
- g2d.drawOval(Randoms.num(width), Randoms.num(height),
- 5 + Randoms.num(10), 5 + Randoms.num(10));
- //画字
- g2d.drawString(strs[i] + "",
- (width - (strs.length - i) * w) + (w - font.getSize()) + 1, h - 4);
- }
- g2d.rotate(-Math.toRadians(degree), start, 21);//旋转之后,必须旋转回来
- g2d.dispose();
- return image;
- }
- /**
- * 获取透明度,从0到1,自动计算步长
- *
- * @return float 透明度
- */
- private float getAlpha(int i, int j) {
- int num = i + j;
- float r = (float) 1 / alpha, s = (alpha + 1) * r;
- float value = num > 5 ? (num * r - s) : num * r;
- if(value > 1.0f){
- value = 1.0f;
- }
- return value;
- }
- }
- import java.awt.AlphaComposite;
- import java.awt.Color;
- import java.awt.Dimension;
- import java.awt.Graphics2D;
- import java.awt.Rectangle;
- import java.awt.image.BufferedImage;
- import java.awt.image.DataBufferInt;
- import java.io.BufferedInputStream;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.URL;
- import java.util.ArrayList;
- /**
- *
- * @author wzztestin
- *
- */
- public class GifDecoder {
- /**
- * File read status: No errors.
- */
- public static final int STATUS_OK = 0;
- /**
- * File read status: Error decoding file (may be partially decoded)
- */
- public static final int STATUS_FORMAT_ERROR = 1;
- /**
- * File read status: Unable to open source.
- */
- public static final int STATUS_OPEN_ERROR = 2;
- protected BufferedInputStream in;
- protected int status;
- protected int width; // full image width
- protected int height; // full image height
- protected boolean gctFlag; // global color table used
- protected int gctSize; // size of global color table
- protected int loopCount = 1; // iterations; 0 = repeat forever
- protected int[] gct; // global color table
- protected int[] lct; // local color table
- protected int[] act; // active color table
- protected int bgIndex; // background color index
- protected int bgColor; // background color
- protected int lastBgColor; // previous bg color
- protected int pixelAspect; // pixel aspect ratio
- protected boolean lctFlag; // local color table flag
- protected boolean interlace; // interlace flag
- protected int lctSize; // local color table size
- protected int ix, iy, iw, ih; // current image rectangle
- protected Rectangle lastRect; // last image rect
- protected BufferedImage image; // current frame
- protected BufferedImage lastImage; // previous frame
- protected byte[] block = new byte[256]; // current data block
- protected int blockSize = 0; // block size
- // last graphic control extension info
- protected int dispose = 0;
- // 0=no action; 1=leave in place; 2=restore to bg; 3=restore to prev
- protected int lastDispose = 0;
- protected boolean transparency = false; // use transparent color
- protected int delay = 0; // delay in milliseconds
- protected int transIndex; // transparent color index
- protected static final int MaxStackSize = 4096;
- // max decoder pixel stack size
- // LZW decoder working arrays
- protected short[] prefix;
- protected byte[] suffix;
- protected byte[] pixelStack;
- protected byte[] pixels;
- protected ArrayList<GifFrame> frames; // frames read from current file
- protected int frameCount;
- static class GifFrame {
- public GifFrame(BufferedImage im, int del) {
- image = im;
- delay = del;
- }
- public BufferedImage image;
- public int delay;
- }
- /**
- * Gets display duration for specified frame.
- *
- * @param n
- * int index of frame
- * @return delay in milliseconds
- */
- public int getDelay(int n) {
- //
- delay = -1;
- if ((n >= 0) && (n < frameCount)) {
- delay = (frames.get(n)).delay;
- }
- return delay;
- }
- /**
- * Gets the number of frames read from file.
- *
- * @return frame count
- */
- public int getFrameCount() {
- return frameCount;
- }
- /**
- * Gets the first (or only) image read.
- *
- * @return BufferedImage containing first frame, or null if none.
- */
- public BufferedImage getImage() {
- return getFrame(0);
- }
- /**
- * Gets the "Netscape" iteration count, if any. A count of 0 means repeat
- * indefinitiely.
- *
- * @return iteration count if one was specified, else 1.
- */
- public int getLoopCount() {
- return loopCount;
- }
- /**
- * Creates new frame image from current data (and previous frames as
- * specified by their disposition codes).
- */
- protected void setPixels() {
- // expose destination image's pixels as int array
- int[] dest = ((DataBufferInt) image.getRaster().getDataBuffer())
- .getData();
- // fill in starting image contents based on last image's dispose code
- if (lastDispose > 0) {
- if (lastDispose == 3) {
- // use image before last
- int n = frameCount - 2;
- if (n > 0) {
- lastImage = getFrame(n - 1);
- } else {
- lastImage = null;
- }
- }
- if (lastImage != null) {
- int[] prev = ((DataBufferInt) lastImage.getRaster()
- .getDataBuffer()).getData();
- System.arraycopy(prev, 0, dest, 0, width * height);
- // copy pixels
- if (lastDispose == 2) {
- // fill last image rect area with background color
- Graphics2D g = image.createGraphics();
- Color c = null;
- if (transparency) {
- c = new Color(0, 0, 0, 0); // assume background is
- // transparent
- } else {
- c = new Color(lastBgColor); // use given background
- // color
- }
- g.setColor(c);
- g.setComposite(AlphaComposite.Src); // replace area
- g.fill(lastRect);
- g.dispose();
- }
- }
- }
- // copy each source line to the appropriate place in the destination
- int pass = 1;
- int inc = 8;
- int iline = 0;
- for (int i = 0; i < ih; i++) {
- int line = i;
- if (interlace) {
- if (iline >= ih) {
- pass++;
- switch (pass) {
- case 2:
- iline = 4;
- break;
- case 3:
- iline = 2;
- inc = 4;
- break;
- case 4:
- iline = 1;
- inc = 2;
- }
- }
- line = iline;
- iline += inc;
- }
- line += iy;
- if (line < height) {
- int k = line * width;
- int dx = k + ix; // start of line in dest
- int dlim = dx + iw; // end of dest line
- if ((k + width) < dlim) {
- dlim = k + width; // past dest edge
- }
- int sx = i * iw; // start of line in source
- while (dx < dlim) {
- // map color and insert in destination
- int index = ((int) pixels[sx++]) & 0xff;
- int c = act[index];
- if (c != 0) {
- dest[dx] = c;
- }
- dx++;
- }
- }
- }
- }
- /**
- * Gets the image contents of frame n.
- *
- * @return BufferedImage representation of frame, or null if n is invalid.
- */
- public BufferedImage getFrame(int n) {
- BufferedImage im = null;
- if ((n >= 0) && (n < frameCount)) {
- im = (frames.get(n)).image;
- }
- return im;
- }
- /**
- * Gets image size.
- *
- * @return GIF image dimensions
- */
- public Dimension getFrameSize() {
- return new Dimension(width, height);
- }
- /**
- * Reads GIF image from stream
- *
- * @param is
- * BufferedInputStream containing GIF file.
- * @return read status code (0 = no errors)
- */
- public int read(BufferedInputStream is) {
- init();
- try {
- if (is != null) {
- in = is;
- readHeader();
- if (!err()) {
- readContents();
- if (frameCount < 0) {
- status = STATUS_FORMAT_ERROR;
- }
- }
- } else {
- status = STATUS_OPEN_ERROR;
- }
- } finally {
- Streams.close(is);
- }
- return status;
- }
- /**
- * Reads GIF image from stream
- *
- * @param is
- * InputStream containing GIF file.
- * @return read status code (0 = no errors)
- */
- public int read(InputStream is) {
- init();
- try {
- if (is != null) {
- if (!(is instanceof BufferedInputStream))
- is = new BufferedInputStream(is);
- in = (BufferedInputStream) is;
- readHeader();
- if (!err()) {
- readContents();
- if (frameCount < 0) {
- status = STATUS_FORMAT_ERROR;
- }
- }
- } else {
- status = STATUS_OPEN_ERROR;
- }
- } finally {
- Streams.close(is);
- }
- return status;
- }
- /**
- * Reads GIF file from specified file/URL source (URL assumed if name
- * contains ":/" or "file:")
- *
- * @param name
- * String containing source
- * @return read status code (0 = no errors)
- */
- public int read(String name) {
- status = STATUS_OK;
- try {
- name = name.trim().toLowerCase();
- if ((name.contains("file:")) || (name.indexOf(":/") > 0)) {
- URL url = new URL(name);
- in = new BufferedInputStream(url.openStream());
- } else {
- in = new BufferedInputStream(new FileInputStream(name));
- }
- status = read(in);
- } catch (IOException e) {
- status = STATUS_OPEN_ERROR;
- }
- return status;
- }
- /**
- * Decodes LZW image data into pixel array. Adapted from John Cristy's
- * ImageMagick.
- */
- protected void decodeImageData() {
- int NullCode = -1;
- int npix = iw * ih;
- int available, clear, code_mask, code_size, end_of_information, in_code, old_code, bits, code, count, i, datum, data_size, first, top, bi, pi;
- if ((pixels == null) || (pixels.length < npix)) {
- pixels = new byte[npix]; // allocate new pixel array
- }
- if (prefix == null)
- prefix = new short[MaxStackSize];
- if (suffix == null)
- suffix = new byte[MaxStackSize];
- if (pixelStack == null)
- pixelStack = new byte[MaxStackSize + 1];
- // Initialize GIF data stream decoder.
- data_size = read();
- clear = 1 << data_size;
- end_of_information = clear + 1;
- available = clear + 2;
- old_code = NullCode;
- code_size = data_size + 1;
- code_mask = (1 << code_size) - 1;
- for (code = 0; code < clear; code++) {
- prefix[code] = 0;
- suffix[code] = (byte) code;
- }
- // Decode GIF pixel stream.
- datum = bits = count = first = top = pi = bi = 0;
- for (i = 0; i < npix;) {
- if (top == 0) {
- if (bits < code_size) {
- // Load bytes until there are enough bits for a code.
- if (count == 0) {
- // Read a new data block.
- count = readBlock();
- if (count <= 0)
- break;
- bi = 0;
- }
- datum += (((int) block[bi]) & 0xff) << bits;
- bits += 8;
- bi++;
- count--;
- continue;
- }
- // Get the next code.
- code = datum & code_mask;
- datum >>= code_size;
- bits -= code_size;
- // Interpret the code
- if ((code > available) || (code == end_of_information))
- break;
- if (code == clear) {
- // Reset decoder.
- code_size = data_size + 1;
- code_mask = (1 << code_size) - 1;
- available = clear + 2;
- old_code = NullCode;
- continue;
- }
- if (old_code == NullCode) {
- pixelStack[top++] = suffix[code];
- old_code = code;
- first = code;
- continue;
- }
- in_code = code;
- if (code == available) {
- pixelStack[top++] = (byte) first;
- code = old_code;
- }
- while (code > clear) {
- pixelStack[top++] = suffix[code];
- code = prefix[code];
- }
- first = ((int) suffix[code]) & 0xff;
- // Add a new string to the string table,
- if (available >= MaxStackSize)
- break;
- pixelStack[top++] = (byte) first;
- prefix[available] = (short) old_code;
- suffix[available] = (byte) first;
- available++;
- if (((available & code_mask) == 0)
- && (available < MaxStackSize)) {
- code_size++;
- code_mask += available;
- }
- old_code = in_code;
- }
- // Pop a pixel off the pixel stack.
- top--;
- pixels[pi++] = pixelStack[top];
- i++;
- }
- for (i = pi; i < npix; i++) {
- pixels[i] = 0; // clear missing pixels
- }
- }
- /**
- * Returns true if an error was encountered during reading/decoding
- */
- protected boolean err() {
- return status != STATUS_OK;
- }
- /**
- * Initializes or re-initializes reader
- */
- protected void init() {
- status = STATUS_OK;
- frameCount = 0;
- frames = new ArrayList<GifFrame>();
- gct = null;
- lct = null;
- }
- /**
- * Reads a single byte from the input stream.
- */
- protected int read() {
- int curByte = 0;
- try {
- curByte = in.read();
- } catch (IOException e) {
- status = STATUS_FORMAT_ERROR;
- }
- return curByte;
- }
- /**
- * Reads next variable length block from input.
- *
- * @return number of bytes stored in "buffer"
- */
- protected int readBlock() {
- blockSize = read();
- int n = 0;
- if (blockSize > 0) {
- try {
- int count = 0;
- while (n < blockSize) {
- count = in.read(block, n, blockSize - n);
- if (count == -1)
- break;
- n += count;
- }
- } catch (IOException ignored) {
- }
- if (n < blockSize) {
- status = STATUS_FORMAT_ERROR;
- }
- }
- return n;
- }
- /**
- * Reads color table as 256 RGB integer values
- *
- * @param ncolors
- * int number of colors to read
- * @return int array containing 256 colors (packed ARGB with full alpha)
- */
- protected int[] readColorTable(int ncolors) {
- int nbytes = 3 * ncolors;
- int[] tab = null;
- byte[] c = new byte[nbytes];
- int n = 0;
- try {
- n = in.read(c);
- } catch (IOException ignored) {
- }
- if (n < nbytes) {
- status = STATUS_FORMAT_ERROR;
- } else {
- tab = new int[256]; // max size to avoid bounds checks
- int i = 0;
- int j = 0;
- while (i < ncolors) {
- int r = ((int) c[j++]) & 0xff;
- int g = ((int) c[j++]) & 0xff;
- int b = ((int) c[j++]) & 0xff;
- tab[i++] = 0xff000000 | (r << 16) | (g << 8) | b;
- }
- }
- return tab;
- }
- /**
- * Main file parser. Reads GIF content blocks.
- */
- protected void readContents() {
- // read GIF file content blocks
- boolean done = false;
- while (!(done || err())) {
- int code = read();
- switch (code) {
- case 0x2C: // image separator
- readImage();
- break;
- case 0x21: // extension
- code = read();
- switch (code) {
- case 0xf9: // graphics control extension
- readGraphicControlExt();
- break;
- case 0xff: // application extension
- readBlock();
- String app = "";
- for (int i = 0; i < 11; i++) {
- app += (char) block[i];
- }
- if (app.equals("NETSCAPE2.0")) {
- readNetscapeExt();
- } else
- skip(); // don't care
- break;
- default: // uninteresting extension
- skip();
- }
- break;
- case 0x3b: // terminator
- done = true;
- break;
- case 0x00: // bad byte, but keep going and see what happens
- break;
- default:
- status = STATUS_FORMAT_ERROR;
- }
- }
- }
- /**
- * Reads Graphics Control Extension values
- */
- protected void readGraphicControlExt() {
- read(); // block size
- int packed = read(); // packed fields
- dispose = (packed & 0x1c) >> 2; // disposal method
- if (dispose == 0) {
- dispose = 1; // elect to keep old image if discretionary
- }
- transparency = (packed & 1) != 0;
- delay = readShort() * 10; // delay in milliseconds
- transIndex = read(); // transparent color index
- read(); // block terminator
- }
- /**
- * Reads GIF file header information.
- */
- protected void readHeader() {
- String id = "";
- for (int i = 0; i < 6; i++) {
- id += (char) read();
- }
- if (!id.startsWith("GIF")) {
- status = STATUS_FORMAT_ERROR;
- return;
- }
- readLSD();
- if (gctFlag && !err()) {
- gct = readColorTable(gctSize);
- bgColor = gct[bgIndex];
- }
- }
- /**
- * Reads next frame image
- */
- protected void readImage() {
- ix = readShort(); // (sub)image position & size
- iy = readShort();
- iw = readShort();
- ih = readShort();
- int packed = read();
- lctFlag = (packed & 0x80) != 0; // 1 - local color table flag
- interlace = (packed & 0x40) != 0; // 2 - interlace flag
- // 3 - sort flag
- // 4-5 - reserved
- lctSize = 2 << (packed & 7); // 6-8 - local color table size
- if (lctFlag) {
- lct = readColorTable(lctSize); // read table
- act = lct; // make local table active
- } else {
- act = gct; // make global table active
- if (bgIndex == transIndex)
- bgColor = 0;
- }
- int save = 0;
- if (transparency) {
- save = act[transIndex];
- act[transIndex] = 0; // set transparent color if specified
- }
- if (act == null) {
- status = STATUS_FORMAT_ERROR; // no color table defined
- }
- if (err())
- return;
- decodeImageData(); // decode pixel data
- skip();
- if (err())
- return;
- frameCount++;
- // create new image to receive frame data
- image = new BufferedImage(width, height,
- BufferedImage.TYPE_INT_ARGB_PRE);
- setPixels(); // transfer pixel data to image
- frames.add(new GifFrame(image, delay)); // add image to frame list
- if (transparency) {
- act[transIndex] = save;
- }
- resetFrame();
- }
- /**
- * Reads Logical Screen Descriptor
- */
- protected void readLSD() {
- // logical screen size
- width = readShort();
- height = readShort();
- // packed fields
- int packed = read();
- gctFlag = (packed & 0x80) != 0; // 1 : global color table flag
- // 2-4 : color resolution
- // 5 : gct sort flag
- gctSize = 2 << (packed & 7); // 6-8 : gct size
- bgIndex = read(); // background color index
- pixelAspect = read(); // pixel aspect ratio
- }
- /**
- * Reads Netscape extenstion to obtain iteration count
- */
- protected void readNetscapeExt() {
- do {
- readBlock();
- if (block[0] == 1) {
- // loop count sub-block
- int b1 = ((int) block[1]) & 0xff;
- int b2 = ((int) block[2]) & 0xff;
- loopCount = (b2 << 8) | b1;
- }
- } while ((blockSize > 0) && !err());
- }
- /**
- * Reads next 16-bit value, LSB first
- */
- protected int readShort() {
- // read 16-bit value, LSB first
- return read() | (read() << 8);
- }
- /**
- * Resets frame state for reading next image.
- */
- @SuppressWarnings("unused")
- protected void resetFrame() {
- lastDispose = dispose;
- lastRect = new Rectangle(ix, iy, iw, ih);
- lastImage = image;
- lastBgColor = bgColor;
- int dispose = 0;
- boolean transparency = false;
- int delay = 0;
- lct = null;
- }
- /**
- * Skips variable length blocks up to and including next zero length block.
- */
- protected void skip() {
- do {
- readBlock();
- } while ((blockSize > 0) && !err());
- }
- }
0 0
- java生成动态gif格式与png格式的验证码(代码2)
- java生成动态gif格式与png格式的验证码(代码5)
- java生成动态gif格式与png格式的验证码(代码4)
- java生成动态gif格式与png格式的验证码(代码3)
- java生成动态gif格式与png格式的验证码(代码1)
- 无组件生成验证码-GIF格式
- ASP验证码-GIF格式
- ASP实现无组件生成验证码-GIF格式
- 动态生成gif格式的图像要注意?
- js验证上传的文件是否为JPEG,PNG,JPG,GIF格式
- js验证上传的文件是否为JPEG,PNG,JPG,GIF格式
- png格式分析的代码
- ASP生成验证码-BMP图片原理,GIF格式,无组件生成验证码
- 【代码】PHP 生成GIF动画实现动态图片验证码
- GNU/Linux jpg、png、gif 与 eps 格式的相互转换
- Linux下图片 jpg、png、gif 与 eps 格式的相互转换
- Java 转换png jpg gif格式图片的相互转换的实现
- PNG格式图片(验证码..)不能显示的解决办法
- English sentenses
- 连连看 深搜带方向
- struts2拦截器的实现原理及源码剖析
- 从0开始学习 GitHub 系列之「05.Git 进阶」
- Batch_size问题
- java生成动态gif格式与png格式的验证码(代码2)
- 用两个栈实现队列
- 关于结构体以及内部指针的一道面试题
- linu下编程70条经验总结
- 学习Django(一)
- java线程相关面试题
- java生成动态gif格式与png格式的验证码(代码1)
- 博客现在更新要慢了
- 软件的版本命名管理