将文字输出成会动的gif

标题:将文字输出成会动的gif
Tag:dynamic gif,GDI+,gif89a,dot net,c sharp,fallseir.lee,飞扬·轻狂
作者:飞扬·轻狂 (fallseir·lee)
来源:http://www.livejournal.com/users/fallseir/14263.html

<%@ WebHandler Language="C#" Class="FeedSkyGif" %>

using System;
using System.Web;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Design;
using System.Drawing.Text;
using System.IO;

/// <summary>
/// 输出会动的gif
/// create by fallseir.lee(飞扬·轻狂 http://www.livejournal.com/~fallseir)
/// --20050811 18:01
/// </summary>
public class FeedSkyGif : IHttpHandler {
   
    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "image/gif";
        DrawGif(context.Response.OutputStream, "f://feed0.bmp", new string[] { "hello", "feedsky.com" });
        context.Response.End();
    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }
    /// <summary>
    /// 图像扩展信息
    /// </summary>
    public byte[] ExtensionBlock = new byte[]{
        0x21,0xFF,0x0B,0x4E,0x45,0x54,0x53,0x43,0x41,0x50,0x45,0x32,0x2E,0x30,0x03,0x01,0x00,0x00,0x00,0x21,0xF9,0x04,0x05,0x32,0x00,0x05,0x00
    };
    /// <summary>
    /// 绘制图像
    /// </summary>
    /// <param name="outStream"></param>
    /// <param name="bkimage"></param>
    /// <param name="msgs"></param>
    public void DrawGif(Stream outStream, string bkimage, string[] msgs)
    {
        Bitmap bmp = new Bitmap(bkimage);
        Color color = Color.FromArgb(255, 0, 0);
        Font font = new Font("宋体", 9, FontStyle.Regular);
        MemoryStream ms = new MemoryStream();
        OutImageHeader(ms,bmp);
        OutImageData(ms, bmp, 0, 0, bmp.Width, bmp.Height, new string[] { "" }, color, font, 0);
        for (int i = 0; i < msgs.Length; i++)
        {
            OutImageData(ms, bmp, 5, 21, bmp.Width - 5 - 5, bmp.Height - 21 - 5, new string[] { "msg:" , msgs[i] }, color, font, 150);
            OutImageData(ms, bmp, 5, 21, bmp.Width - 5 - 5, bmp.Height - 21 - 5, new string[] { "msg:", msgs[i] }, Color.FromArgb(50,255,00,00), font, 50);
            OutImageData(ms, bmp, 5, 21, bmp.Width - 5 - 5, bmp.Height - 21 - 5, new string[] { "msg:", msgs[i] }, Color.FromArgb(12, 255,00, 00), font, 50);
        }
        bmp.Dispose();
        ms.Write(new byte[] { 0x3B }, 0, 1);
        ms.WriteTo(outStream);
        ms.Close();
    }
    /// <summary>
    /// 输出头像头
    /// </summary>
    /// <param name="ms"></param>
    /// <param name="bk"></param>
    public void OutImageHeader(MemoryStream ms, Bitmap bk)
    {
        MemoryStream m = new MemoryStream();
        bk.Save(m, ImageFormat.Gif);       
        byte[] buffer = m.ToArray();
        byte[] header = GetHeader(buffer);
        ms.Write(header, 0, header.Length);       
        m.Close();    
    }
    /// <summary>
    /// 输出图像数据
    /// </summary>
    /// <param name="ms">输出流</param>
    /// <param name="bk">背景图片(使用背景图片的一部分x,y,width,height)</param>
    /// <param name="x">left</param>
    /// <param name="y">top</param>
    /// <param name="width">width</param>
    /// <param name="height">height</param>
    /// <param name="msg">message string</param>
    /// <param name="color">color</param>
    /// <param name="font">font</param>
    /// <param name="delay">delay time</param>
    public void OutImageData(MemoryStream ms,Bitmap bk,float x,float y,int width,int height,string[] msgs,Color color,Font font,int delay)
    {
        MemoryStream m = new MemoryStream();
        Bitmap b = Draw(bk.Clone(new RectangleF(x, y, width, height), PixelFormat.Format32bppPArgb), msgs, color, font, 0, 0);
        b.Save(m, ImageFormat.Gif);
        b.Dispose();
        byte[] buffer = m.ToArray();
        if (ms.Length == 0)
        {
            byte[] header = GetHeader(buffer);
            ms.Write(header, 0, header.Length);
        }
        byte[] image = GetImageData(buffer,(int)x,(int)y,delay);
        ms.Write(image, 0, image.Length);
        m.Close();      
    }
    //获取图像头
    public byte[] GetHeader(byte[] image)
    {
        int size = GetHeaderSize(image);
        if (size < 0) return new byte[] { };
        byte[] buffer = new byte[size];
        Array.Copy(image, 0, buffer, 0, size);
        return buffer;
    }
    /// <summary>
    /// 获取图像数据
    /// </summary>
    /// <param name="image">单张的gif数据</param>
    /// <param name="x">left</param>
    /// <param name="y">top</param>
    /// <param name="delay">delay time</param>
    /// <returns></returns>
    public byte[] GetImageData(byte[] image, int x, int y,int delay)
    {
        int begin = GetImageBegin(image);
        byte[] block=GenerateExtensionBlock();
        block[23] = Convert.ToByte(delay);
        int size=image.Length-begin+block.Length-1;
        image[begin + 1] = Convert.ToByte(x);//left
        image[begin + 3] = Convert.ToByte(y);//top
        byte[] data = new byte[size];
        Array.Copy(block, data, block.Length);
        Array.Copy(image, begin, data, block.Length, image.Length - begin-1);
        return data;
    }
    private byte[] GenerateExtensionBlock()
    {
        byte[] block =(byte[]) ExtensionBlock.Clone();
        return block;
    }
    //获取图像头大小
    private int GetHeaderSize(byte[] image)
    {
        if (!(image[0] == (byte)'G' && image[1] == (byte)'I' && image[2] == (byte)'F'))
        { return -1; }
        int size = -1;
        for (int i = 12; i < image.Length; i++)
        {
            if (image[i] == 0x21)
            {
                i++;
                if (image[i] == 0xf9)
                {
                    size = i - 1;
                    break;
                }
            }
        }
        return size;
    }
    //获取图像数据开始位置
    private int GetImageBegin(byte[] image)
    {
        int hsize = GetHeaderSize(image);
        int begin = -1;
        if (hsize > 0)
        {
            for (int i = hsize; i < image.Length; i++)
            {
                if (image[i] == 0x00)
                {
                    i++;
                    if (image[i] == 0x2c)
                    {
                        begin = i;
                        break;
                    }
                }
            }
            return begin;
        }
        return -1;
    }
    public Bitmap Draw(Bitmap bmp, string[] msgs, Color color, Font font, float x, float y)
    {
        Graphics g = Graphics.FromImage(bmp);
        for (int i = 0; i < msgs.Length; i++)
        {
            g.DrawString(msgs[i], font, new SolidBrush(color), x, y+i*(font.Height-1));           
        }
        g.Dispose();
        return bmp;
    }

}


/* Gif Format
 *
 * <GIF Header><!-- 0-12 begin with GIF89a or GIF87a -->
 *  <Global Color Table/>
 *  <Blocks/>
 * </GIF Header>
 *
 * <Blocks>
 *  <block>
 *   <Extensions>
 *    <Graphic Control Extension Block>
 *    <Comment Extension Block>
 *    <Plain Text Extension Block>
 *   </Extensions>
 *   <Image>
 *   </Image>
 *  </block>
 * </Blocks>
 *
GIF format http://www.onicos.com/staff/iz/formats/gif.html#gceb
Byte Order: Little-endian

GIF Header
Offset   Length   Contents
  0      3 bytes  "GIF"
  3      3 bytes  "87a" or "89a"
  6      2 bytes  <Logical Screen Width>
  8      2 bytes  <Logical Screen Height>
 10      1 byte   bit 0:    Global Color Table Flag (GCTF)
                  bit 1..3: Color Resolution
                  bit 4:    Sort Flag to Global Color Table
                  bit 5..7: Size of Global Color Table: 2^(1+n)
 11      1 byte   <Background Color Index>
 12      1 byte   <Pixel Aspect Ratio>
 13      ? bytes  <Global Color Table(0..255 x 3 bytes) if GCTF is one>
         ? bytes  <Blocks>
         1 bytes  <Trailer> (0x3b)

Image Block
Offset   Length   Contents
  0      1 byte   Image Separator (0x2c)
  1      2 bytes  Image Left Position
  3      2 bytes  Image Top Position
  5      2 bytes  Image Width
  7      2 bytes  Image Height
  8      1 byte   bit 0:    Local Color Table Flag (LCTF)
                  bit 1:    Interlace Flag
                  bit 2:    Sort Flag
                  bit 2..3: Reserved
                  bit 4..7: Size of Local Color Table: 2^(1+n)
         ? bytes  Local Color Table(0..255 x 3 bytes) if LCTF is one
         1 byte   LZW Minimum Code Size
[ // Blocks
         1 byte   Block Size (s)
        (s)bytes  Image Data
]*
         1 byte   Block Terminator(0x00)

Graphic Control Extension Block
Offset   Length   Contents
  0      1 byte   Extension Introducer (0x21)
  1      1 byte   Graphic Control Label (0xf9)
  2      1 byte   Block Size (0x04)
  3      1 byte   bit 0..2: Reserved
                  bit 3..5: Disposal Method
                  bit 6:    User Input Flag
                  bit 7:    Transparent Color Flag
  4      2 bytes  Delay Time (1/100ths of a second)
  6      1 byte   Transparent Color Index
  7      1 byte   Block Terminator(0x00)

Comment Extension Block
Offset   Length   Contents
  0      1 byte   Extension Introducer (0x21)
  1      1 byte   Comment Label (0xfe)
[
         1 byte   Block Size (s)
        (s)bytes  Comment Data
]*
         1 byte   Block Terminator(0x00)

Plain Text Extension Block
Offset   Length   Contents
  0      1 byte   Extension Introducer (0x21)
  1      1 byte   Plain Text Label (0x01)
  2      1 byte   Block Size (0x0c)
  3      2 bytes  Text Grid Left Position
  5      2 bytes  Text Grid Top Position
  7      2 bytes  Text Grid Width
  9      2 bytes  Text Grid Height
 10      1 byte   Character Cell Width(
 11      1 byte   Character Cell Height
 12      1 byte   Text Foreground Color Index(
 13      1 byte   Text Background Color Index(
[
         1 byte   Block Size (s)
        (s)bytes  Plain Text Data
]*
         1 byte   Block Terminator(0x00)

Application Extension Block
Offset   Length   Contents
  0      1 byte   Extension Introducer (0x21)
  1      1 byte   Application Label (0xff)
  2      1 byte   Block Size (0x0b)
  3      8 bytes  Application Identifire
[
         1 byte   Block Size (s)
        (s)bytes  Application Data
]*
         1 byte   Block Terminator(0x00)


--------------------------------------------------------------------------------

GIF87a:

GIF Header
Image Block
Trailer


--------------------------------------------------------------------------------

GIF89a:

GIF Header
Graphic Control Extension
Image Block
Trailer


--------------------------------------------------------------------------------

GIF Animation

GIF Header
Application Extension
[
  Graphic Control Extension
  Image Block
]*
Trailer

*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值