C# 让RichTextBox支持GIF

我只是做了一些简单的测试...有疑问给我发消息把.

使用方法

//获取选择的图形 并且保存出来

  1. private void button2_Click(object sender, EventArgs e)
  2.         {
  3.             IListMemoryStream> _List = gifRichTextBox1.LoadSelectFile();

  4.             for (int i = 0; i != _List.Count; i++)
  5.             {
  6.                 File.WriteAllBytes(@"C:\Temp\A" + i.ToString() + ".gif", _List[0].ToArray());
  7.             }
  8.         }

  9. //添加一个GIF图形
  10.         private void button3_Click(object sender, EventArgs e)
  11.         {
  12.             gifRichTextBox1.AddFile(@"C:\Temp\0.gif");
  13.         }

  14. //获取当前的RTF文字 你可以直接保存这个到数据库 或则通过SOCKET发送出去.
  15.         string _Text = "";
  16.         private void button1_Click(object sender, EventArgs e)
  17.         {
  18.             _Text = gifRichTextBox1.Rtf;


  19.         }

  20. //重新显示RTF内容

  21.         private void button4_Click(object sender, EventArgs e)
  22.         {
  23.             gifRichTextBox1.Rtf = _Text;
  24.         }

  25. 如果没有这个类..保存出的RTF数据..在其他RTF浏览的时候可能是个白色的矩形..

  26. 下面是全部的类

  27. using System;
  28. using System.Collections.Generic;
  29. using System.Text;
  30. using System.IO;
  31. using System.Windows.Forms;
  32. using System.Drawing;

  33. namespace Zgke.WindowFrom.Window.Controls.UserControls
  34. {
  35.     ///
  36.     /// RichTextBox支持 GIF图形
  37.     /// zgke@sina.com
  38.     /// qq:116149
  39.     ///
  40.     public class GifRichTextBox : RichTextBox
  41.     {
  42.         public GifRichTextBox()
  43.         {
  44.           
  45.         }

  46.         ///
  47.         /// 重绘
  48.         ///
  49.         ///
  50.         protected override void WndProc(ref Message m)
  51.         {
  52.             if (m.Msg == 0xF)
  53.             {
  54.                 foreach (Control _SubControl in base.Controls)
  55.                 {
  56.                     _SubControl.Tag = "1";
  57.                 }

  58.                 GetRichTextObjRectangle();

  59.                 for (int i = 0; i != base.Controls.Count; i++)
  60.                 {
  61.                     if (base.Controls[i].Tag.ToString() == "1")
  62.                     {
  63.                         base.Controls.RemoveAt(i);
  64.                         i--;
  65.                     }
  66.                 }
  67.             }
  68.             base.WndProc(ref m);
  69.         }

  70.         ///
  71.         /// 添加一个文件资源到RTF数据
  72.         ///
  73.         /// 文件路径
  74.         public void AddFile(string p_FileFullPath)
  75.         {
  76.             byte[] _FileBytes = File.ReadAllBytes(p_FileFullPath);
  77.             Image _Image = Image.FromStream(new MemoryStream(_FileBytes));
  78.             string _Guid = BitConverter.ToString(Guid.NewGuid().ToByteArray()).Replace("-", "");
  79.             StringBuilder _RtfText = new StringBuilder(@"{\rtf1\ansi\ansicpg936\deff0\deflang1033\deflangfe2052{\fonttbl{\f0\fnil\fcharset134 \'cb\'ce\'cc\'e5;}}\uc1\pard\lang2052\f0\fs18{\object\objemb{\*\objclass Paint.Picture}");
  80.             int _Width = _Image.Width * 15;
  81.             int _Height = _Image.Height * 15;
  82.             _RtfText.Append(@"\objw" + _Width.ToString() + @"\objh" + _Height.ToString());
  83.             _RtfText.AppendLine(@"{\*\objdata");
  84.             _RtfText.AppendLine(@"010500000200000007000000504272757368000000000000000000" + BitConverter.ToString(BitConverter.GetBytes(_FileBytes.Length + 20)).Replace("-", ""));
  85.             _RtfText.Append("7A676B65" + _Guid); //标记
  86.             _RtfText.AppendLine(BitConverter.ToString(_FileBytes).Replace("-", ""));
  87.             _RtfText.AppendLine(@"0105000000000000}{\result{\pict\wmetafile0}}}}");
  88.             base.SelectedRtf = _RtfText.ToString();
  89.         }

  90.         ///
  91.         /// 获取选择的文件
  92.         ///
  93.         /// 文件列表
  94.         public IListMemoryStream> LoadSelectFile()
  95.         {
  96.             IListMemoryStream> _FileList = new ListMemoryStream>();
  97.             int _Index = base.SelectedRtf.IndexOf(@"{\*\objdata");
  98.             if (_Index == -1) return _FileList;

  99.             while (_Index != -1)
  100.             {
  101.                 MemoryStream _File = new MemoryStream();
  102.                 _Index += 80;
  103.                 string _LengthText = base.SelectedRtf.Substring(_Index, 8);

  104.                 int _Length = BitConverter.ToInt32(new byte[] { Convert.ToByte(_LengthText.Substring(0, 2), 16), Convert.ToByte(_LengthText.Substring(2, 2), 16), Convert.ToByte(_LengthText.Substring(4, 2), 16), Convert.ToByte(_LengthText.Substring(6, 2), 16) }, 0);
  105.                 _Index += 10;

  106.                 string _Head = base.SelectedRtf.Substring(_Index, 8);
  107.                 if (_Head.ToUpper() == "7A676B65")
  108.                 {
  109.                     _Index += 40;
  110.                     _Length -= 20;
  111.                     int _EndIndex = base.SelectedRtf.IndexOf("01050000", _Index);
  112.                     int _ReadIndex = 0;
  113.                     _FileList.Add(LoadMemoryStream(base.SelectedRtf.Substring(_Index, _EndIndex - _Index), ref _ReadIndex, _Length));
  114.                     _Index = _EndIndex;
  115.                 }
  116.                 _Index = base.SelectedRtf.IndexOf(@"{\*\objdata", _Index);
  117.             }
  118.             return _FileList;
  119.         }

  120.         ///
  121.         /// 获取图形或则改动PictureBox的位置
  122.         ///
  123.         ///
  124.         private void PointFile(string p_Rtf, Point p_StarPoint, int p_Width, int p_Height)
  125.         {
  126.             int _Index = p_Rtf.IndexOf(@"{\*\objdata");
  127.             if (_Index == -1) return;
  128.             _Index += 80;
  129.             string _LengthText = p_Rtf.Substring(_Index, 8);

  130.             int _Length = BitConverter.ToInt32(new byte[] { Convert.ToByte(_LengthText.Substring(0, 2), 16), Convert.ToByte(_LengthText.Substring(2, 2), 16), Convert.ToByte(_LengthText.Substring(4, 2), 16), Convert.ToByte(_LengthText.Substring(6, 2), 16) }, 0);
  131.             _Index += 10;

  132.             string _Head = p_Rtf.Substring(_Index, 8);
  133.             if (_Head.ToUpper() != "7A676B65") return; //如果不是标记出来的 就不生成PictureBox
  134.             _Index += 8;

  135.             string _Guid = p_Rtf.Substring(_Index, 32);

  136.             Control _Controls = base.Controls[_Guid];
  137.             if (_Controls == null)
  138.             {
  139.                 PictureBox _PictureBox = new PictureBox();
  140.                 _PictureBox.Name = _Guid;
  141.                 _PictureBox.Tag = "0";
  142.                 _PictureBox.Location = p_StarPoint;
  143.                 _PictureBox.Size = new Size(p_Width, p_Height);

  144.                 _Index += 32;
  145.                 _Length -= 20;

  146.                 _PictureBox.Image = Image.FromStream(LoadMemoryStream(p_Rtf, ref _Index,_Length));

  147.                 base.Controls.Add(_PictureBox);
  148.             }
  149.             else
  150.             {
  151.                 _Controls.Location = p_StarPoint;
  152.                 _Controls.Size = new Size(p_Width, p_Height);
  153.                 _Controls.Tag = "0";
  154.             }
  155.         }

  156.         ///
  157.         /// 根据RTF保存的内容获取内存流
  158.         ///
  159.         /// RTF
  160.         /// 开始位置
  161.         /// 读取数量
  162.         /// 内存流
  163.         private MemoryStream LoadMemoryStream(string p_Text,ref int p_Index,int p_Count)
  164.         {
  165.             MemoryStream _File =new MemoryStream();
  166.             char[] _Text = p_Text.ToCharArray();
  167.             for (int i = 0; i != p_Count; i++)
  168.             {
  169.                 if (_Text[p_Index] == '\r' && _Text[p_Index + 1] == '\n')
  170.                 {
  171.                     i--;
  172.                 }
  173.                 else
  174.                 {
  175.                     _File.WriteByte(Convert.ToByte(_Text[p_Index].ToString() + _Text[p_Index + 1].ToString(), 16));
  176.                 }
  177.                 p_Index += 2;
  178.             }
  179.             return _File;
  180.         }
  181.        
  182.         ///
  183.         /// 获取RICHTEXTBOX所有图形的位置
  184.         ///
  185.         /// RICHTEXTBOX
  186.         /// 位置信息
  187.         private void GetRichTextObjRectangle()
  188.         {
  189.             RichTextBox _RichText = new RichTextBox();
  190.             _RichText.Rtf = base.Rtf;
  191.             int _Count = base.Text.Length;

  192.             for (int i = 0; i != _Count; i++)
  193.             {
  194.                 if (base.Text[i] == ' ')
  195.                 {
  196.                     _RichText.Select(i, 1);

  197.                     if (_RichText.SelectionType.ToString() == "Object")
  198.                     {
  199.                         Point _StarPoint = base.GetPositionFromCharIndex(i);

  200.                         System.Text.RegularExpressions.Regex _RegexWidth = new System.Text.RegularExpressions.Regex(@"(?);
  201.                         System.Text.RegularExpressions.Regex _RegexHeight = new System.Text.RegularExpressions.Regex(@"(?);

  202.                         int _Width = 0;
  203.                         int _Height = 0;

  204.                         if (int.TryParse(_RegexWidth.Match(_RichText.SelectedRtf).Value, out _Width) && int.TryParse(_RegexHeight.Match(_RichText.SelectedRtf).Value, out _Height))
  205.                         {
  206.                             _Width = _Width / 15;
  207.                             _Height = _Height / 15;
  208.                             PointFile(_RichText.SelectedRtf, _StarPoint, _Width, _Height);
  209.                         }
  210.                     }
  211.                 }
  212.             }
  213.             _RichText.Dispose();
  214.         }
  215.     }
  216. }

另加一个检测GIF文件是否被损坏的方法:

  1. class Utility
  2.     {

  3.         //Bonus. A simple check on the GIF files because some may contain "bad" data and crash the program.
  4.         public static bool IsImageCorrupted(Image img)
  5.         {
  6.             bool itis = false;

  7.             try
  8.             {
  9.                 if (!ImageAnimator.CanAnimate(img))
  10.                 {
  11.                     return itis;
  12.                 }
  13.                 int frames = img.GetFrameCount(System.Drawing.Imaging.FrameDimension.Time);
  14.                 if (frames = 1)
  15.                 {
  16.                     return itis;
  17.                 }
  18.                 byte[] times = img.GetPropertyItem(0x5100).Value;
  19.                 int frame = 0;
  20.                 for (; ; )
  21.                 {
  22.                     int dur = BitConverter.ToInt32(times, 4 * frame);
  23.                     if (++frame >= frames) break;
  24.                     img.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Time, frame);
  25.                 }

  26.             }
  27.             catch (Exception ex)
  28.             {
  29.                 throw ex;
  30.             }

  31.             return itis;
  32.         }
  33.     }

转载着修改自博客:
http://www.cnblogs.com/jxsoft/archive/2011/06/22/2087435.html
上一篇:数据结构基础(13) --链式栈的设计与实现


下一篇:面试经之给刚毕业的大学生和刚入门的程序员的忠告及图书推荐