C# 百度富文本框框发送GIF动态图片

&无意中在国外论坛发现一个gif动画类,我使用它来制作了一个动态验证码 ;
一:首先新建一个类库&
  1:新建AnimatedGifEncoder类
using System.Collections.G
using System.D
using System.IO;
using System.L
using System.T
namespace Common.Gif
#region Java
* Class AnimatedGifEncoder - Encodes a GIF file consisting of one or
* more frames.
* Example:
AnimatedGifEncoder e = new AnimatedGifEncoder();
e.start(outputFileName);
e.setDelay(1000);
// 1 frame per sec
e.addFrame(image1);
e.addFrame(image2);
e.finish();
* No copyright asserted on the source code of this class.
May be used
* for any purpose, however, refer to the Unisys LZW patent for restrictions
* on use of the associated LZWEncoder class.
Please forward any corrections
* @author Kevin Weiner, FM Software
* @version 1.03 November 2003
#endregion
public class AnimatedGifEncoder
// image size
protected Color transparent = Color.E // transparent color if given
protected int transI // transparent index in color table
protected int repeat = -1; // no repeat
protected int delay = 0; // frame delay (hundredths)
protected bool started = // ready to output frames
// protected BinaryW
//protected FileS
protected S
protected I // current frame
protected byte[] // BGR byte array from frame
protected byte[] indexedP // converted frame indexed to palette
protected int colorD // number of bit planes
protected byte[] colorT // RGB palette
protected bool[] usedEntry = new bool[256]; // active palette entries
protected int palSize = 7; // color table size (bits-1)
protected int dispose = -1; // disposal code (-1 = use default)
protected bool closeStream = // close stream when finished
protected bool firstFrame =
protected bool sizeSet = // if false, get size from first frame
protected int sample = 10; // default sample interval for quantizer
* Sets the delay time between each frame, or changes it
* for subsequent frames (applies to last frame added).
* @param ms int delay time in milliseconds
public void SetDelay(int ms)
delay = (int)Math.Round(ms / 10.0f);
* Sets the GIF frame disposal code for the last added frame
* and any subsequent frames.
Default is 0 if no transparent
* color has been set, otherwise 2.
* @param code int disposal code.
public void SetDispose(int code)
if (code &= 0)
* Sets the number of times the set of GIF frames
* should be played.
Default is 1; 0 means play
* indefinitely.
Must be invoked before the first
* image is added.
* @param iter int number of iterations.
public void SetRepeat(int iter)
if (iter &= 0)
* Sets the transparent color for the last added frame
* and any subsequent frames.
* Since all colors are subject to modification
* in the quantization process, the color in the final
* palette for each frame closest to the given color
* becomes the transparent color for that frame.
* May be set to null to indicate no transparent color.
* @param c Color to be treated as transparent on display.
public void SetTransparent(Color c)
transparent =
* Adds next GIF frame.
The frame is not written immediately, but is
* actually deferred until the next frame is received so that timing
* data can be inserted.
Invoking &code&finish()&/code& flushes all
If &code&setSize&/code& was not invoked, the size of the
* first image is used for all subsequent frames.
* @param im BufferedImage containing frame to write.
* @return true if successful.
public bool AddFrame(Image im)
if ((im == null) || !started)
if (!sizeSet)
// use first frame's size
SetSize(im.Width, im.Height);
GetImagePixels(); // convert to correct format if necessary
AnalyzePixels(); // build color table & map pixels
if (firstFrame)
WriteLSD(); // logical screen descriptior
WritePalette(); // global color table
if (repeat &= 0)
// use NS app extension to indicate reps
WriteNetscapeExt();
WriteGraphicCtrlExt(); // write graphic control extension
WriteImageDesc(); // image descriptor
if (!firstFrame)
WritePalette(); // local color table
WritePixels(); // encode and write pixel data
firstFrame =
catch (IOException e)
* Flushes any pending data and closes output file.
* If writing to an OutputStream, the stream is not
public bool Finish()
if (!started)
fs.WriteByte(0x3b); // gif trailer
fs.Flush();
if (closeStream)
fs.Close();
catch (IOException e)
// reset for subsequent use
transIndex = 0;
indexedPixels =
colorTab =
closeStream =
firstFrame =
* Sets frame rate in frames per second.
Equivalent to
* &code&setDelay(1000/fps)&/code&.
* @param fps float frame rate (frames per second)
public void SetFrameRate(float fps)
if (fps != 0f)
delay = (int)Math.Round(100f / fps);
* Sets quality of color quantization (conversion of images
* to the maximum 256 colors allowed by the GIF specification).
* Lower values (minimum = 1) produce better colors, but slow
* processing significantly.
10 is the default, and produces
* good color mapping at reasonable speeds.
Values greater
* than 20 do not yield significant improvements in speed.
* @param quality int greater than 0.
public void SetQuality(int quality)
if (quality & 1) quality = 1;
* Sets the GIF frame size.
The default size is the
* size of the first frame added if this method is
* not invoked.
* @param w int frame width.
* @param h int frame width.
public void SetSize(int w, int h)
if (started && !firstFrame)
if (width & 1) width = 320;
if (height & 1) height = 240;
* Initiates GIF file creation on the given stream.
The stream
* is not closed automatically.
* @param os OutputStream on which GIF images are written.
* @return false if initial write failed.
public bool Start(Stream os)
if (os == null)
closeStream =
WriteString("GIF89a"); // header
catch (IOException e)
return started =
* Initiates writing of a GIF file with the specified name.
* @param file String containing output file name.
* @return false if open or initial write failed.
public bool Start(String file)
bw = new BinaryWriter( new FileStream( file, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None ) );
fs = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
ok = Start(fs);
closeStream =
catch (IOException e)
return started =
* Analyzes image colors and creates color map.
protected void AnalyzePixels()
int len = pixels.L
int nPix = len / 3;
indexedPixels = new byte[nPix];
NeuQuant nq = new NeuQuant(pixels, len, sample);
// initialize quantizer
colorTab = nq.Process(); // create reduced palette
// convert map from BGR to RGB
for (int i = 0; i & colorTab.L i += 3)
byte temp = colorTab[i];
colorTab[i] = colorTab[i + 2];
colorTab[i + 2] =
usedEntry[i / 3] =
// map image pixels to new palette
int k = 0;
for (int i = 0; i & nP i++)
int index =
nq.Map(pixels[k++] & 0xff,
pixels[k++] & 0xff,
pixels[k++] & 0xff);
usedEntry[index] =
indexedPixels[i] = (byte)
colorDepth = 8;
palSize = 7;
// get closest match to transparent color if specified
if (transparent != Color.Empty)
transIndex = FindClosest(transparent);
* Returns index of palette color closest to c
protected int FindClosest(Color c)
if (colorTab == null) return -1;
int r = c.R;
int g = c.G;
int b = c.B;
int minpos = 0;
int dmin = 256 * 256 * 256;
int len = colorTab.L
for (int i = 0; i & )
int dr = r - (colorTab[i++] & 0xff);
int dg = g - (colorTab[i++] & 0xff);
int db = b - (colorTab[i] & 0xff);
int d = dr * dr + dg * dg + db *
int index = i / 3;
if (usedEntry[index] && (d & dmin))
* Extracts image pixels into byte array "pixels"
protected void GetImagePixels()
int w = image.W
int h = image.H
int type = image.GetType().;
if ((w != width)
|| (h != height)
// create new image with right size/format
Image temp =
new Bitmap(width, height);
Graphics g = Graphics.FromImage(temp);
g.DrawImage(image, 0, 0);
g.Dispose();
improve performance: use unsafe code
pixels = new Byte[3 * image.Width * image.Height];
int count = 0;
Bitmap tempBitmap = new Bitmap(image);
for (int th = 0; th & image.H th++)
for (int tw = 0; tw & image.W tw++)
Color color = tempBitmap.GetPixel(tw, th);
pixels[count] = color.R;
pixels[count] = color.G;
pixels[count] = color.B;
pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
* Writes Graphic Control Extension
protected void WriteGraphicCtrlExt()
fs.WriteByte(0x21); // extension introducer
fs.WriteByte(0xf9); // GCE label
fs.WriteByte(4); // data block size
int transp,
if (transparent == Color.Empty)
transp = 0;
disp = 0; // dispose = no action
transp = 1;
disp = 2; // force clear if using transparent color
if (dispose &= 0)
disp = dispose & 7; // user override
disp &&= 2;
// packed fields
fs.WriteByte(Convert.ToByte(0 | // 1:3 reserved
disp | // 4:6 disposal
user input - 0 = none
transp)); // 8
transparency flag
WriteShort(delay); // delay x 1/100 sec
fs.WriteByte(Convert.ToByte(transIndex)); // transparent color index
fs.WriteByte(0); // block terminator
* Writes Image Descriptor
protected void WriteImageDesc()
fs.WriteByte(0x2c); // image separator
WriteShort(0); // image position x,y = 0,0
WriteShort(0);
WriteShort(width); // image size
WriteShort(height);
// packed fields
if (firstFrame)
- GCT is used for first (or only) frame
fs.WriteByte(0);
// specify normal LCT
fs.WriteByte(Convert.ToByte(0x80 | // 1 local color table
0 | // 2 interlace - 0=no
0 | // 3 sorted - 0=no
0 | // 4-5 reserved
palSize)); // 6-8 size of color table
* Writes Logical Screen Descriptor
protected void WriteLSD()
// logical screen size
WriteShort(width);
WriteShort(height);
// packed fields
fs.WriteByte(Convert.ToByte(0x80 | // 1
: global color table flag = 1 (gct used)
0x70 | // 2-4 : color resolution = 7
0x00 | // 5
: gct sort flag = 0
palSize)); // 6-8 : gct size
fs.WriteByte(0); // background color index
fs.WriteByte(0); // pixel aspect ratio - assume 1:1
* Writes Netscape application extension to define
* repeat count.
protected void WriteNetscapeExt()
fs.WriteByte(0x21); // extension introducer
fs.WriteByte(0xff); // app extension label
fs.WriteByte(11); // block size
WriteString("NETSCAPE" + "2.0"); // app id + auth code
fs.WriteByte(3); // sub-block size
fs.WriteByte(1); // loop sub-block id
WriteShort(repeat); // loop count (extra iterations, 0=repeat forever)
fs.WriteByte(0); // block terminator
* Writes color table
protected void WritePalette()
fs.Write(colorTab, 0, colorTab.Length);
int n = (3 * 256) - colorTab.L
for (int i = 0; i & i++)
fs.WriteByte(0);
* Encodes and writes pixel data
protected void WritePixels()
LZWEncoder encoder =
new LZWEncoder(width, height, indexedPixels, colorDepth);
encoder.Encode(fs);
Write 16-bit value to output stream, LSB first
protected void WriteShort(int value)
fs.WriteByte(Convert.ToByte(value & 0xff));
fs.WriteByte(Convert.ToByte((value && 8) & 0xff));
* Writes string to output stream
protected void WriteString(String s)
char[] chars = s.ToCharArray();
for (int i = 0; i & chars.L i++)
fs.WriteByte((byte)chars[i]);
  2:新建GifDecoder类
#region .NET Disclaimer/Info
//===============================================================================
// gOODiDEA,
//===============================================================================
// $Header :
// $Author :
// $Revision:
// $History:
//===============================================================================
#endregion
#region Java
* Class GifDecoder - Decodes a GIF file into one or more frames.
* &br&&pre&
* Example:
GifDecoder d = new GifDecoder();
d.read("sample.gif");
int n = d.getFrameCount();
for (int i = 0; i & i++) {
BufferedImage frame = d.getFrame(i);
// frame i
int t = d.getDelay(i);
// display duration of frame in milliseconds
// do something with frame
* No copyright asserted on the source code of this class.
May be used for
* any purpose, however, refer to the Unisys LZW patent for any additional
* restrictions.
Please forward any corrections to .
* @author Kevin Weiner, FM S LZW decoder adapted from John Cristy's ImageMagick.
* @version 1.03 November 2003
#endregion
using System.C
using System.D
using System.Drawing.I
using System.IO;
namespace Common.Gif
public class GifDecoder
* File read status: No errors.
public static readonly int STATUS_OK = 0;
* File read status: Error decoding file (may be partially decoded)
public static readonly int STATUS_FORMAT_ERROR = 1;
* File read status: Unable to open source.
public static readonly int STATUS_OPEN_ERROR = 2;
protected Stream inS
// full image width
// full image height
protected bool gctF // global color table used
protected int gctS // size of global color table
protected int loopCount = 1; // 0 = repeat forever
protected int[] // global color table
protected int[] // local color table
protected int[] // active color table
protected int bgI // background color index
protected int bgC // background color
protected int lastBgC // previous bg color
protected int pixelA // pixel aspect ratio
protected bool lctF // local color table flag
prot // interlace flag
protected int lctS // local color table size
protected int ix, iy, iw, // current image rectangle
protected Rectangle lastR // last image rect
protected I // current frame
protected B
protected Image lastI // 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= 1= 2= 3=restore to prev
protected int lastDispose = 0;
protected bool transparency = // use transparent color
protected int delay = 0; // delay in milliseconds
protected int transI // transparent color index
protected static readonly int MaxStackSize = 4096;
// max decoder pixel stack size
// LZW decoder working arrays
protected short[]
protected byte[]
protected byte[] pixelS
protected byte[]
protected ArrayL // frames read from current file
protected int frameC
public class GifFrame
public GifFrame( Image im, int del)
* 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 = ((GifFrame) frames[n]).
* Gets the number of frames read from file.
* @return frame count
public int GetFrameCount()
return frameC
* Gets the first (or only) image read.
* @return BufferedImage containing first frame, or null if none.
public Image 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 loopC
* Creates new frame image from current data (and previous
* frames as specified by their disposition codes).
int [] GetPixels( Bitmap bitmap )
int [] pixels = new int [ 3 * image.Width * image.Height ];
int count = 0;
for (int th = 0; th & image.H th++)
for (int tw = 0; tw & image.W tw++)
Color color = bitmap.GetPixel(tw, th);
pixels[count] = color.R;
pixels[count] = color.G;
pixels[count] = color.B;
void SetPixels( int [] pixels )
int count = 0;
for (int th = 0; th & image.H th++)
for (int tw = 0; tw & image.W tw++)
Color color = Color.FromArgb( pixels[count++] );
bitmap.SetPixel( tw, th, color );
protected void SetPixels()
// expose destination image's pixels as int array
int[] dest =
(( int ) image.getRaster().getDataBuffer()).getData();
int[] dest = GetPixels( bitmap );
// 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);
lastImage =
if (lastImage != null)
int[] prev =
((DataBufferInt) lastImage.getRaster().getDataBuffer()).getData();
int[] prev = GetPixels( new Bitmap( lastImage ) );
Array.Copy(prev, 0, dest, 0, width * height);
// copy pixels
if (lastDispose == 2)
// fill last image rect area with background color
Graphics g = Graphics.FromImage( image );
Color c = Color.E
if (transparency)
c = Color.FromArgb( 0, 0, 0, 0 );
// assume background is transparent
c = Color.FromArgb( lastBgColor ) ;
c = new Color(lastBgColor); // use given background color
Brush brush = new SolidBrush( c );
g.FillRectangle( brush, lastRect );
brush.Dispose();
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 & i++)
int line =
if (interlace)
if (iline &= ih)
switch (pass)
iline = 4;
iline = 2;
iline = 1;
if (line & height)
int k = line *
int dx = k + // start of line in dest
int dlim = dx + // end of dest line
if ((k + width) & dlim)
dlim = k + // past dest edge
int sx = i * // start of line in source
while (dx & dlim)
// map color and insert in destination
int index = ((int) pixels[sx++]) & 0
int c = act[index];
if (c != 0)
dest[dx] =
SetPixels( dest );
* Gets the image contents of frame n.
* @return BufferedImage representation of frame, or null if n is invalid.
public Image GetFrame(int n)
Image im =
if ((n &= 0) && (n & frameCount))
im = ((GifFrame) frames[n] ).
* Gets image size.
* @return GIF image dimensions
public Size GetFrameSize()
return new Size(width, height);
* Reads GIF image from stream
* @param BufferedInputStream containing GIF file.
* @return read status code (0 = no errors)
public int Read( Stream inStream )
if ( inStream != null)
this.inStream = inS
ReadHeader();
if (!Error())
ReadContents();
if (frameCount & 0)
status = STATUS_FORMAT_ERROR;
inStream.Close();
status = STATUS_OPEN_ERROR;
* 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;
name = name.Trim().ToLower();
status = Read( new FileInfo( name ).OpenRead() );
catch (IOException e)
status = STATUS_OPEN_ERROR;
* Decodes LZW image data into pixel array.
* Adapted from John Cristy's ImageMagick.
protected void DecodeImageData()
int NullCode = -1;
int npix = iw *
int available,
code_mask,
code_size,
end_of_information,
data_size,
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_
end_of_information = clear + 1;
available = clear + 2;
old_code = NullC
code_size = data_size + 1;
code_mask = (1 && code_size) - 1;
for (code = 0; code & code++)
prefix[code] = 0;
suffix[code] = (byte)
Decode GIF pixel stream.
datum = bits = count = first = top = pi = bi = 0;
for (i = 0; i &)
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)
datum += (((int) block[bi]) & 0xff) &&
bits += 8;
Get the next code.
code = datum & code_
datum &&= code_
bits -= code_
Interpret the code
if ((code & available) || (code == end_of_information))
if (code == clear)
Reset decoder.
code_size = data_size + 1;
code_mask = (1 && code_size) - 1;
available = clear + 2;
old_code = NullC
if (old_code == NullCode)
pixelStack[top++] = suffix[code];
old_code =
if (code == available)
pixelStack[top++] = (byte)
code = old_
while (code & clear)
pixelStack[top++] = suffix[code];
code = prefix[code];
first = ((int) suffix[code]) & 0
Add a new string to the string table,
if (available &= MaxStackSize)
pixelStack[top++] = (byte)
prefix[available] = (short) old_
suffix[available] = (byte)
available++;
if (((available & code_mask) == 0)
&& (available & MaxStackSize))
code_size++;
code_mask +=
old_code = in_
Pop a pixel off the pixel stack.
pixels[pi++] = pixelStack[top];
for (i = i & i++)
pixels[i] = 0; // clear missing pixels
* Returns true if an error was encountered during reading/decoding
protected bool Error()
return status != STATUS_OK;
* Initializes or re-initializes reader
protected void Init()
status = STATUS_OK;
frameCount = 0;
frames = new ArrayList();
* Reads a single byte from the input stream.
protected int Read()
int curByte = 0;
curByte = inStream.ReadByte();
catch (IOException e)
status = STATUS_FORMAT_ERROR;
return curB
* 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)
int count = 0;
while (n & blockSize)
count = inStream.Read(block, n, blockSize - n);
if (count == -1)
catch (IOException e)
if (n & blockSize)
status = STATUS_FORMAT_ERROR;
* 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 *
int[] tab =
byte[] c = new byte[nbytes];
int n = 0;
n = inStream.Read(c, 0, c.Length );
catch (IOException e)
if (n & nbytes)
status = STATUS_FORMAT_ERROR;
tab = new int[256]; // max size to avoid bounds checks
int i = 0;
int j = 0;
while (i & ncolors)
int r = ((int) c[j++]) & 0
int g = ((int) c[j++]) & 0
int b = ((int) c[j++]) & 0
tab[i++] = ( int ) ( 0xff000000 | (r && 16) | (g && 8) | b );
* Main file parser.
Reads GIF content blocks.
protected void ReadContents()
// read GIF file content blocks
bool done =
while (!(done || Error()))
int code = Read();
switch (code)
case 0x2C : // image separator
ReadImage();
case 0x21 : // extension
code = Read();
switch (code)
case 0xf9 : // graphics control extension
ReadGraphicControlExt();
case 0xff : // application extension
ReadBlock();
String app = "";
for (int i = 0; i & 11; i++)
app += (char) block[i];
if (app.Equals("NETSCAPE2.0"))
ReadNetscapeExt();
Skip(); // don't care
default : // uninteresting extension
case 0x3b : // terminator
case 0x00 : // bad byte, but keep going and see what happens
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;
ReadLSD();
if (gctFlag && !Error())
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 = // make local table active
act = // 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 (Error())
DecodeImageData(); // decode pixel data
if (Error())
frameCount++;
// create new image to receive frame data
new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
bitmap = new Bitmap( width, height );
SetPixels(); // transfer pixel data to image
frames.Add(new GifFrame(bitmap, delay)); // add image to frame list
if (transparency)
act[transIndex] =
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
: 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()
ReadBlock();
if (block[0] == 1)
// loop count sub-block
int b1 = ((int) block[1]) & 0
int b2 = ((int) block[2]) & 0
loopCount = (b2 && 8) | b1;
} while ((blockSize & 0) && !Error());
* 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.
protected void ResetFrame()
lastDispose =
lastRect = new Rectangle(ix, iy, iw, ih);
lastImage =
lastBgColor = bgC
int dispose = 0;
bool transparency =
int delay = 0;
* Skips variable length blocks up to and including
* next zero length block.
protected void Skip()
ReadBlock();
} while ((blockSize & 0) && !Error());
  3:新建LZWEncoder类
#region .NET Disclaimer/Info
//===============================================================================
// gOODiDEA,
//===============================================================================
// $Header :
// $Author :
// $Revision:
// $History:
//===============================================================================
#endregion
#region Java
//==============================================================================
Adapted from Jef Poskanzer's Java port by way of J. M. G. Elliott.
K Weiner 12/00
#endregion
using System.IO;
namespace Common.Gif
public class LZWEncoder
private static readonly int EOF = -1;
private int imgW, imgH;
private byte[] pixA
private int initCodeS
private int curP
// GIFCOMPR.C
- GIF Image compression routines
// Lempel-Ziv compression based on 'compress'.
GIF modifications by
// David Rowley (mgardi@watdcsu.waterloo.edu)
// General DEFINEs
static readonly int BITS = 12;
static readonly int HSIZE = 5003; // 80% occupancy
// GIF Image compression - modified 'compress'
// Based on: compress.c - File compression ala IEEE Computer, June 1984.
// By Authors:
Spencer W. Thomas
(decvax!harpo!utah-cs!utah-gr!thomas)
(decvax!mcvax!jim)
Steve Davies
(decvax!vax135!petsd!peora!srd)
Ken Turkowski
(decvax!decwrl!turtlevax!ken)
James A. Woods
(decvax!ihnp4!ames!jaw)
(decvax!vax135!petsd!joe)
int n_ // number of bits/code
int maxbits = BITS; // user settable max # bits/code
// maximum code, given n_bits
int maxmaxcode = 1 && BITS; // should NEVER generate this code
int[] htab = new int[HSIZE];
int[] codetab = new int[HSIZE];
int hsize = HSIZE; // for dynamic table sizing
int free_ent = 0; // first unused entry
// block compression parameters -- after all codes are used up,
// and compression rate changes, start over.
bool clear_flg =
// Algorithm:
use open addressing double hashing (no chaining) on the
// prefix code / next character combination.
We do a variant of Knuth's
// algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
// secondary probe.
Here, the modular division first probe is gives way
// to a faster exclusive-or manipulation.
Also do block compression with
// an adaptive reset, whereby the code table is cleared when the compression
// ratio decreases, but after the table fills.
The variable-length output
// codes are re-sized at this point, and a special CLEAR code is generated
// for the decompressor.
Late addition:
construct the table according to
// file size for noticeable speed improvement on small files.
Please direct
// questions about this implementation to ames!jaw.
int g_init_
int ClearC
// Output the given code.
// Inputs:
A n_bits-bit integer.
If == -1, then EOF.
This assumes
that n_bits =& wordsize - 1.
// Outputs:
Outputs code to the file.
// Assumptions:
Chars are 8 bits long.
// Algorithm:
Maintain a BITS character long buffer (so that 8 codes will
// fit in it exactly).
Use the VAX insv instruction to insert each
// code in turn.
When the buffer fills up empty it and start over.
int cur_accum = 0;
int cur_bits = 0;
int [] masks =
// Number of characters so far in this 'packet'
// Define the storage for the packet accumulator
byte[] accum = new byte[256];
//----------------------------------------------------------------------------
public LZWEncoder(int width, int height, byte[] pixels, int color_depth)
initCodeSize = Math.Max(2, color_depth);
// Add a character to the end of the current packet, and if it is 254
// characters, flush the packet to disk.
void Add(byte c, Stream outs)
accum[a_count++] =
if (a_count &= 254)
Flush(outs);
// Clear out the hash table
// table clear for block compress
void ClearTable(Stream outs)
ResetCodeTable(hsize);
free_ent = ClearCode + 2;
clear_flg =
Output(ClearCode, outs);
// reset code table
void ResetCodeTable(int hsize)
for (int i = 0; i & ++i)
htab[i] = -1;
void Compress(int init_bits, Stream outs)
int i /* = 0 */;
int hsize_
// Set up the globals:
g_init_bits - initial number of bits
g_init_bits = init_
// Set up the necessary values
clear_flg =
n_bits = g_init_
maxcode = MaxCode(n_bits);
ClearCode = 1 && (init_bits - 1);
EOFCode = ClearCode + 1;
free_ent = ClearCode + 2;
a_count = 0; // clear packet
ent = NextPixel();
hshift = 0;
for (fcode = fcode & 65536; fcode *= 2)
hshift = 8 - // set hash code range bound
hsize_reg =
ResetCodeTable(hsize_reg); // clear hash table
Output(ClearCode, outs);
outer_loop : while ((c = NextPixel()) != EOF)
fcode = (c && maxbits) +
i = (c && hshift) ^ // xor hashing
if (htab[i] == fcode)
ent = codetab[i];
else if (htab[i] &= 0) // non-empty slot
disp = hsize_reg - // secondary hash (after G. Knott)
if (i == 0)
if ((i -= disp) & 0)
i += hsize_
if (htab[i] == fcode)
ent = codetab[i];
goto outer_
} while (htab[i] &= 0);
Output(ent, outs);
if (free_ent & maxmaxcode)
codetab[i] = free_ent++; // code -& hashtable
ClearTable(outs);
// Put out the final code.
Output(ent, outs);
Output(EOFCode, outs);
//----------------------------------------------------------------------------
public void Encode( Stream os)
os.WriteByte( Convert.ToByte( initCodeSize) ); // write "initial code size" byte
remaining = imgW * imgH; // reset navigation variables
curPixel = 0;
Compress(initCodeSize + 1, os); // compress and write the pixel data
os.WriteByte(0); // write block terminator
// Flush the packet to disk, and reset the accumulator
void Flush(Stream outs)
if (a_count & 0)
outs.WriteByte( Convert.ToByte( a_count ));
outs.Write(accum, 0, a_count);
a_count = 0;
int MaxCode(int n_bits)
return (1 && n_bits) - 1;
//----------------------------------------------------------------------------
// Return the next pixel from the image
//----------------------------------------------------------------------------
private int NextPixel()
if (remaining == 0)
return EOF;
int temp = curPixel + 1;
if ( temp & pixAry.GetUpperBound( 0 ))
byte pix = pixAry[curPixel++];
return pix & 0
void Output(int code, Stream outs)
cur_accum &= masks[cur_bits];
if (cur_bits & 0)
cur_accum |= (code && cur_bits);
cur_accum =
cur_bits += n_
while (cur_bits &= 8)
Add((byte) (cur_accum & 0xff), outs);
cur_accum &&= 8;
cur_bits -= 8;
// If the next entry is going to be too big for the code size,
// then increase it, if possible.
if (free_ent & maxcode || clear_flg)
if (clear_flg)
maxcode = MaxCode(n_bits = g_init_bits);
clear_flg =
if (n_bits == maxbits)
maxcode = MaxCode(n_bits);
if (code == EOFCode)
// At EOF, write the rest of the buffer.
while (cur_bits & 0)
Add((byte) (cur_accum & 0xff), outs);
cur_accum &&= 8;
cur_bits -= 8;
Flush(outs);
  4:最后新建一个NeuQuant类 (这样gif类库完成)
#region .NET Disclaimer/Info
//===============================================================================
// gOODiDEA,
//===============================================================================
// $Header :
// $Author :
// $Revision:
// $History:
//===============================================================================
#endregion
#region Java
/* NeuQuant Neural-Net Quantization Algorithm
* ------------------------------------------
* Copyright (c) 1994 Anthony Dekker
* NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
* See "Kohonen neural networks for optimal colour quantization"
* in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
* for a discussion of the algorithm.
* Any party obtaining a copy of these files from the author, directly or
* indirectly, is granted, free of charge, a full and unrestricted irrevocable,
* world-wide, paid up, royalty-free, nonexclusive right and license to deal
* in this software and documentation files (the "Software"), including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons who receive
* copies from any such party to do so, with the only requirement being
* that this copyright notice remain intact.
// Ported to Java 12/00 K Weiner
#endregion
namespace Common.Gif
public class NeuQuant
protected static readonly int netsize = 256; /* number of colours used */
/* four primes near 500 - assume no image has a length so large */
/* that it is divisible by all four primes */
protected static readonly int prime1 = 499;
protected static readonly int prime2 = 491;
protected static readonly int prime3 = 487;
protected static readonly int prime4 = 503;
protected static readonly int minpicturebytes = ( 3 * prime4 );
/* minimum size for input image */
/* Program Skeleton
----------------
[select samplefac in range 1..30]
[read image from input file]
pic = (unsigned char*) malloc(3*width*height);
initnet(pic,3*width*height,samplefac);
unbiasnet();
[write output image header, using writecolourmap(f)]
inxbuild();
write output image using inxsearch(b,g,r)
/* Network Definitions
------------------- */
protected static readonly int maxnetpos = (netsize - 1);
protected static readonly int netbiasshift = 4; /* bias for colour values */
protected static readonly int ncycles = 100; /* no. of learning cycles */
/* defs for freq and bias */
protected static readonly int intbiasshift = 16; /* bias for fractions */
protected static readonly int intbias = (((int) 1) && intbiasshift);
protected static readonly int gammashift = 10; /* gamma = 1024 */
protected static readonly int gamma = (((int) 1) && gammashift);
protected static readonly int betashift = 10;
protected static readonly int beta = (intbias && betashift); /* beta = 1/1024 */
protected static readonly int betagamma =
(intbias && (gammashift - betashift));
/* defs for decreasing radius factor */
protected static readonly int initrad = (netsize && 3); /* for 256 cols, radius starts */
protected static readonly int radiusbiasshift = 6; /* at 32.0 biased by 6 bits */
protected static readonly int radiusbias = (((int) 1) && radiusbiasshift);
protected static readonly int initradius = (initrad * radiusbias); /* and decreases by a */
protected static readonly int radiusdec = 30; /* factor of 1/30 each cycle */
/* defs for decreasing alpha factor */
protected static readonly int alphabiasshift = 10; /* alpha starts at 1.0 */
protected static readonly int initalpha = (((int) 1) && alphabiasshift);
pr /* biased by 10 bits */
/* radbias and alpharadbias used for radpower calculation */
protected static readonly int radbiasshift = 8;
protected static readonly int radbias = (((int) 1) && radbiasshift);
protected static readonly int alpharadbshift = (alphabiasshift + radbiasshift);
protected static readonly int alpharadbias = (((int) 1) && alpharadbshift);
/* Types and Global Variables
-------------------------- */
protected byte[] /* the input image itself */
prote /* lengthcount = H*W*3 */
pro /* sampling factor 1..30 */
typedef int pixel[4];
/* BGRc */
protected int[][] /* the network itself - [netsize][4] */
protected int[] netindex = new int[256];
/* for network lookup - really 256 */
protected int[] bias = new int[netsize];
/* bias and freq arrays for learning */
protected int[] freq = new int[netsize];
protected int[] radpower = new int[initrad];
/* radpower for precomputation */
/* Initialise network in range (0,0,0) to (255,255,255) and set parameters
----------------------------------------------------------------------- */
public NeuQuant(byte[] thepic, int len, int sample)
thepicture =
lengthcount =
samplefac =
network = new int[netsize][];
for (i = 0; i & i++)
network[i] = new int[4];
p = network[i];
p[0] = p[1] = p[2] = (i && (netbiasshift + 8)) /
freq[i] = intbias / /* 1/netsize */
bias[i] = 0;
public byte[] ColorMap()
byte[] map = new byte[3 * netsize];
int[] index = new int[netsize];
for (int i = 0; i & i++)
index[network[i][3]] =
int k = 0;
for (int i = 0; i & i++)
int j = index[i];
map[k++] = (byte) (network[j][0]);
map[k++] = (byte) (network[j][1]);
map[k++] = (byte) (network[j][2]);
/* Insertion sort of network and building of netindex[0..255] (to do after unbias)
------------------------------------------------------------------------------- */
public void Inxbuild()
int i, j, smallpos,
int previouscol,
previouscol = 0;
startpos = 0;
for (i = 0; i & i++)
p = network[i];
smallpos =
smallval = p[1]; /* index on g */
/* find smallest in i..netsize-1 */
for (j = i + 1; j & j++)
q = network[j];
if (q[1] & smallval)
{ /* index on g */
smallpos =
smallval = q[1]; /* index on g */
q = network[smallpos];
/* swap p (i) and q (smallpos) entries */
if (i != smallpos)
q[0] = p[0];
q[1] = p[1];
q[2] = p[2];
q[3] = p[3];
/* smallval entry is now in position i */
if (smallval != previouscol)
netindex[previouscol] = (startpos + i) && 1;
for (j = previouscol + 1; j & j++)
netindex[j] =
previouscol =
startpos =
netindex[previouscol] = (startpos + maxnetpos) && 1;
for (j = previouscol + 1; j & 256; j++)
netindex[j] = /* really 256 */
/* Main Learning Loop
------------------ */
public void Learn()
int i, j, b, g,
int radius, rad, alpha, step, delta,
if (lengthcount & minpicturebytes)
samplefac = 1;
alphadec = 30 + ((samplefac - 1) / 3);
samplepixels = lengthcount / (3 * samplefac);
delta = samplepixels /
rad = radius &&
if (rad &= 1)
for (i = 0; i & i++)
radpower[i] =
alpha * (((rad * rad - i * i) * radbias) / (rad * rad));
//fprintf(stderr,"beginning 1D learning: initial radius=%d\n", rad);
if (lengthcount & minpicturebytes)
else if ((lengthcount % prime1) != 0)
step = 3 * prime1;
if ((lengthcount % prime2) != 0)
step = 3 * prime2;
if ((lengthcount % prime3) != 0)
step = 3 * prime3;
step = 3 * prime4;
while (i & samplepixels)
b = (p[pix + 0] & 0xff) &&
g = (p[pix + 1] & 0xff) &&
r = (p[pix + 2] & 0xff) &&
j = Contest(b, g, r);
Altersingle(alpha, j, b, g, r);
if (rad != 0)
Alterneigh(rad, j, b, g, r); /* alter neighbours */
if (pix &= lim)
if (delta == 0)
delta = 1;
if (i % delta == 0)
alpha -= alpha /
radius -= radius /
rad = radius &&
if (rad &= 1)
for (j = 0; j & j++)
radpower[j] =
alpha * (((rad * rad - j * j) * radbias) / (rad * rad));
//fprintf(stderr,"finished 1D learning: readonly alpha=%f !\n",((float)alpha)/initalpha);
/* Search for BGR values 0..255 (after net is unbiased) and return colour index
---------------------------------------------------------------------------- */
public int Map(int b, int g, int r)
int i, j, dist, a,
bestd = 1000; /* biggest possible dist is 256*3 */
best = -1;
i = netindex[g]; /* index on g */
j = i - 1; /* start at netindex[g] and work outwards */
while ((i & netsize) || (j &= 0))
if (i & netsize)
p = network[i];
dist = p[1] - /* inx key */
if (dist &= bestd)
i = /* stop iter */
if (dist & 0)
a = p[0] -
if (a & 0)
if (dist & bestd)
a = p[2] -
if (a & 0)
if (dist & bestd)
best = p[3];
if (j &= 0)
p = network[j];
dist = g - p[1]; /* inx key - reverse dif */
if (dist &= bestd)
j = -1; /* stop iter */
if (dist & 0)
a = p[0] -
if (a & 0)
if (dist & bestd)
a = p[2] -
if (a & 0)
if (dist & bestd)
best = p[3];
return (best);
public byte[] Process()
Unbiasnet();
Inxbuild();
return ColorMap();
/* Unbias network to give byte values 0..255 and record position i to prepare for sort
----------------------------------------------------------------------------------- */
public void Unbiasnet()
for (i = 0; i & i++)
network[i][0] &&=
network[i][1] &&=
network[i][2] &&=
network[i][3] = /* record colour no */
/* Move adjacent neurons by precomputed alpha*(1-((i-j)^2/[r]^2)) in radpower[|i-j|]
--------------------------------------------------------------------------------- */
protected void Alterneigh(int rad, int i, int b, int g, int r)
int j, k, lo, hi, a,
if (lo & -1)
if (hi & netsize)
j = i + 1;
k = i - 1;
while ((j & hi) || (k & lo))
a = radpower[m++];
if (j & hi)
p = network[j++];
p[0] -= (a * (p[0] - b)) /
p[1] -= (a * (p[1] - g)) /
p[2] -= (a * (p[2] - r)) /
catch (Exception e)
} // prevents 1.3 miscompilation
if (k & lo)
p = network[k--];
p[0] -= (a * (p[0] - b)) /
p[1] -= (a * (p[1] - g)) /
p[2] -= (a * (p[2] - r)) /
catch (Exception e)
/* Move neuron i towards biased (b,g,r) by factor alpha
---------------------------------------------------- */
protected void Altersingle(int alpha, int i, int b, int g, int r)
/* alter hit neuron */
int[] n = network[i];
n[0] -= (alpha * (n[0] - b)) /
n[1] -= (alpha * (n[1] - g)) /
n[2] -= (alpha * (n[2] - r)) /
/* Search for biased BGR values
---------------------------- */
protected int Contest(int b, int g, int r)
/* finds closest neuron (min dist) and updates freq */
/* finds best neuron (min dist-bias) and returns position */
/* for frequently chosen neurons, freq[i] is high and bias[i] is negative */
/* bias[i] = gamma*((1/netsize)-freq[i]) */
int i, dist, a, biasdist,
int bestpos, bestbiaspos, bestd,
bestd = ~(((int) 1) && 31);
bestbiasd =
bestpos = -1;
bestbiaspos =
for (i = 0; i & i++)
n = network[i];
dist = n[0] -
if (dist & 0)
a = n[1] -
if (a & 0)
a = n[2] -
if (a & 0)
if (dist & bestd)
biasdist = dist - ((bias[i]) && (intbiasshift - netbiasshift));
if (biasdist & bestbiasd)
bestbiasd =
bestbiaspos =
betafreq = (freq[i] && betashift);
freq[i] -=
bias[i] += (betafreq && gammashift);
freq[bestpos] +=
bias[bestpos] -=
return (bestbiaspos);
二:新建一个网站:
  1:建立一个验证码类,代码如下
using Common.G
using System.Collections.G
using System.D
using System.IO;
using System.L
using System.T
using System.W
namespace Common.Tools
public class VerificationCode
private AnimatedGifEncoder coder = new AnimatedGifEncoder();
// private Stream stream = new MemoryStream();
private char[] _identifyingC
private int _defaultIdentifyingCodeLen = 4;
private string _availableLetters = @"的一是在了不和有大这主中人上为们地个用工时要动国产以我到他会作来分生对于学下级就年阶义发成部民可出能方进同行面说种过命度革而多子后自社加小机也经力线本电高量长党得实家定深法表着水理化争现所二起政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批如应形想制心样干都向变关点育重其思与间内去因件日利相由压员气业代全组数果期导平各基或月毛然问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫知轴研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书术状厂须离再目海交权且儿青才证低越际八试规斯近注办布门铁需走议县兵固除般引齿千胜细影济白格效置推空配刀叶率述今选养德话查差半敌始片施响收华觉备名红续均药标记难存测士身紧液派准斤角降维板许破述技消底床田势端感往神便贺村构照容非搞亚磨族火段算适讲按值美态黄易彪服早班麦削信排台声该击素张密害侯草何树肥继右属市严径螺检左页抗苏显苦英快称坏移约巴材省黑武培著河帝仅针怎植京助升王眼她抓含苗副杂普谈围食射源例致酸旧却充足短划剂宣环落首尺波承粉践府鱼随考刻靠够满夫失包住促枝局菌杆周护岩师举曲春元超负砂封换太模贫减阳扬江析亩木言球朝医校古呢稻宋听唯输滑站另卫字鼓刚写刘微略范供阿块某功套友限项余倒卷创律雨让骨远帮初皮播优占死毒圈伟季训控激找叫云互跟裂粮粒母练塞钢顶策双留误础吸阻故寸盾晚丝女散焊功株亲院冷彻弹错散商视艺灭版烈零室轻血倍缺厘泵察绝富城冲喷壤简否柱李望盘磁雄似困巩益洲脱投送奴侧润盖挥距触星松送获兴独官混纪依未突架宽冬章湿偏纹吃执阀矿寨责熟稳夺硬价努翻奇甲预职评读背协损棉侵灰虽矛厚罗泥辟告卵箱掌氧恩爱停曾溶营终纲孟钱待尽俄缩沙退陈讨奋械载胞幼哪剥迫旋征槽倒握担仍呀鲜吧卡粗介钻逐弱脚怕盐末阴丰编印蜂急拿扩伤飞露核缘游振操央伍域甚迅辉异序免纸夜乡久隶缸夹念兰映沟乙吗儒杀汽磷艰晶插埃燃欢铁补咱芽永瓦倾阵碳演威附牙芽永瓦斜灌欧献顺猪洋腐请透司危括脉宜笑若尾束壮暴企菜穗楚汉愈绿拖牛份染既秋遍锻玉夏疗尖殖井费州访吹荣铜沿替滚客召旱悟刺脑措贯藏敢令隙炉壳硫煤迎铸粘探临薄旬善福纵择礼愿伏残雷延烟句纯渐耕跑泽慢栽鲁赤繁境潮横掉锥希池败船假亮谓托伙哲怀割摆贡呈劲财仪沉炼麻罪祖息车穿货销齐鼠抽画饲龙库守筑房歌寒喜哥洗蚀废纳腹乎录镜妇恶脂庄擦险赞钟摇典柄辩竹谷卖乱虚桥奥伯赶垂途额壁网截野遗静谋弄挂课镇妄盛耐援扎虑键归符庆聚绕摩忙舞遇索顾胶羊湖钉仁音迹碎伸灯避泛亡答勇频皇柳哈揭甘诺概宪浓岛袭谁洪谢炮浇斑讯懂灵蛋闭孩释乳巨徒私银伊景坦累匀霉杜乐勒隔弯绩招绍胡呼痛峰零柴簧午跳居尚丁秦稍追梁折耗碱殊岗挖氏刃剧堆赫荷胸衡勤膜篇登驻案刊秧缓凸役剪川雪链渔啦脸户洛孢勃盟买杨宗焦赛旗滤硅炭股坐蒸凝竟陷枪黎救冒暗洞犯筒您宋弧爆谬涂味津臂障褐陆啊健尊豆拔莫抵桑坡缝警挑污冰柬嘴啥饭塑寄赵喊垫康遵牧遭幅园腔订香肉弟屋敏恢忘衣孙龄岭骗休借丹渡耳刨虎笔稀昆浪萨茶滴浅拥穴覆伦娘吨浸袖珠雌妈紫戏塔锤震岁貌洁剖牢锋疑霸闪埔猛诉刷狠忽灾闹乔唐漏闻沈熔氯荒茎男凡抢像浆旁玻亦忠唱蒙予纷捕锁尤乘乌智淡允叛畜俘摸锈扫毕璃宝芯爷鉴秘净蒋钙肩腾枯抛轨堂拌爸循诱祝励肯酒绳穷塘燥泡袋朗喂铝软渠颗惯贸粪综墙趋彼届墨碍启逆卸航雾冠丙街莱贝辐肠付吉渗瑞惊顿挤秒悬姆烂森糖圣凹陶词迟蚕亿矩";
private Random random = new Random();
private int _frameCount = 4;
private int _delay = 900;
private int _noiseCount = 15;
private int _width = 150, _height = 60;
public int Width
get { return _ }
public int Height
get { return _ }
public string IdentifyingCode
get { return new string(_identifyingCode); }
public VerificationCode(int width, int height)
_width = width & 1 ? 1 :
_height = height & 1 ? 1 :
coder.SetSize(Width, Height);
coder.SetRepeat(0);
private void GenerateIdentifyingCode(int codeLength)
if (codeLength & 1)
codeLength = _defaultIdentifyingCodeL
List&char& codes = new List&char&();
for (int i = 0; i & codeL i++)
codes.Add(_availableLetters[random.Next(0, _availableLetters.Length)]);
_identifyingCode = new char[codes.Count];
codes.CopyTo(_identifyingCode);
public Stream Create(Stream stream)
coder.Start(stream);
Process();
public MemoryStream Create()
MemoryStream stream = new MemoryStream();
coder.Start(stream);
Process();
private void Process()
GenerateIdentifyingCode(_defaultIdentifyingCodeLen);
Brush br = Brushes.W
Rectangle rect = new Rectangle(0, 0, Width, Height);
Font f = new Font(FontFamily.GenericSansSerif, 14, FontStyle.Bold);
for (int i = 0; i & _frameC i++)
Image im = new Bitmap(Width, Height);
Graphics ga = Graphics.FromImage(im);
ga.FillRectangle(br, rect);
int fH = (int)f.GetHeight();
int fW = (int)ga.MeasureString(IdentifyingCode, f).W
AddNoise(ga);
ga.DrawString(IdentifyingCode, f, SystemBrushes.Desktop, new PointF(random.Next(1, Width - 1 - fW), random.Next(1, Height - 1 - fH)));
ga.Flush();
coder.SetDelay(_delay);
coder.AddFrame(im);
im.Dispose();
coder.Finish();
private void AddNoise(Graphics ga)
Pen pen = new Pen(SystemColors.GrayText);
Point[] ps = new Point[_noiseCount];
for (int i = 0; i & _noiseC i++)
ps[i] = new Point(random.Next(1, Width - 1), random.Next(1, Height - 1));
ga.DrawLines(pen, ps);
public void Create(string path)
//coder.Start(path);用它的这个方法,比用 stream 生成的要大!
FileStream fs = new FileStream(path, FileMode.Create);
coder.Start(fs);
Process();
fs.Close();
public void ProcessRequest(HttpContext context)
context.Response.ClearContent();
context.Response.ContentType = "image/Gif";
var stream = Create();
context.Response.BinaryWrite(stream.ToArray());
stream.Dispose();
  2:使用验证码类
public void Index()
Response.ClearContent();
Response.ContentType = "image/Gif";
using (MemoryStream m = new MemoryStream())
VerificationCode va = new VerificationCode(105, 30);
var s = va.Create(m);
string code = Common.DEncrypt.DESEncrypt.Encrypt(va.IdentifyingCode.ToLower());
var cookie = new HttpCookie("cheakcode", code);
if (Request.Url.Host.ToLower() != "localhost")
cookie.Domain = Request.Url.H
cookie.HttpOnly =
Response.Cookies.Add(cookie);
Response.BinaryWrite(m.ToArray());
  3: 运行结果图
阅读(...) 评论()

我要回帖

更多关于 百度富文本框 的文章

 

随机推荐