嘻哈人间,我醉逍遥

while(true){this.StudyDotNet(DotNetLanguage.CSharp);}

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

背景:最近闲来无事,也应论坛某会员要求,想做个QQ表情下载的站点。本来事情是很简单的,写个小小的CRUD也就可以了,但嘻哈呵嘿既然是个.Net程序员,当然要使用.Net来实现了。今天我们就用.Net来实现CFC ( custom face cab? ) 的表情格式的打包功能。

要做到这个功能,我们必须先了解这个格式,首先Google一下。我们找到了这一篇来自清华大学的文章:FC文件格式详解

从这篇文章里我们得知了CFC的文件格式大概如下:

一个块有15个字段,如下

  1. md5的字符串形式长度,4个字节
  2. 快捷键长度,4字节
  3. 表情名称长度,4字节
  4. 表情文件名长度,4字节
  5. 表情文件长度,4字节
  6. 微缩图文件名长度,4字节
  7. 微缩文件长度,4字节
  8. 表情文件帧数,4字节
  9. 图片md5的字符串形式
  10. 快捷键
  11. 表情名称
  12. 表情文件名
  13. 微缩图文件名
  14. 表情文件内容
  15. 微缩图内容
知道了格式就好办了,我们按步就班定义一个结构(struct)
 1    Struct
其中含有两方法,一个是从文件得到一个此结构的静态方法,另一个是将此结构转化为byte数组。

我们再建一个类,命名为:FaceHelper
代码如下:
    public class FaceHelper
    
{
        
internal static FaceBlock GetFaceBlockFromImage(string file)
        
{
            FaceBlock fb 
= new FaceBlock();
            
//打开文件流   
            FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read);
            
//获取图像
            Image img = Image.FromStream(fs);
            
//获得一个20*20的缩略图
            Image thumbnail = img.GetThumbnailImage(2020null, IntPtr.Zero);
            MemoryStream ms 
= new MemoryStream();
            
//将缩图图转化数byte数组
            thumbnail.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
            
byte[] thumbnailData = ms.ToArray();
            ms.Close();
            ms.Dispose();
            thumbnail.Dispose();

            
//得到一个唯一的MD5字符串
            string md5 = GetMD5(fs);
            
//文件名,格式为:md5 + 扩展名
            string fileName = string.Format("{0}{1}", md5, Path.GetExtension(file));
            
//缩略图文件名,格式为:md5 + fixed.bmp
            string thumbnailName = string.Format("{0}fixed.bmp", md5);
            
//随机设置一个快捷键
            string uintcuts = "qq.5inet.net_" + RandomNum(6);
            fs.Close();
            fs.Dispose();

            
//取得总的帧数
System.Drawing.Imaging.FrameDimension fd = System.Drawing.Imaging.FrameDimension.Resolution;
            
int frameCount = img.FrameDimensionsList.Length;
            img.Dispose();

            fb.MD5 
= md5;
            fb.MD5Length 
= (uint)md5.Length;
            fb.uintcuts 
= uintcuts;
            fb.uintcutLength 
= (uint)uintcuts.Length;
            fb.FaceName 
= uintcuts;
            fb.FaceNameLength 
= (uint)uintcuts.Length;
            fb.FaceFileName 
= fileName;
            fb.FaceFileNameLength 
= (uint)fileName.Length;
            fb.ThumbnailFileName 
= thumbnailName;
            fb.ThumbnailFileNameLength 
= (uint)thumbnailName.Length;
            fb.FaceData 
= File.ReadAllBytes(file);
            fb.FileLength 
= (uint)fb.FaceData.Length;
            fb.ThumbnailData 
= thumbnailData;
            fb.ThumbnailFileLength 
= (uint)thumbnailData.Length;
            fb.FrameLength 
= (uint)frameCount;

            
return fb;
        }


        
Helper

        
//从一个目录生成一个CFC文件集合
        public static void 
BuildCFCFileFromDirectory(
string directory)
        
{
            List
<byte> bytes = new List<byte>();
            
foreach (string file in Directory.GetFiles(directory))
            
{
                
if (!IsImageFile(file))
                    
continue;

                bytes.AddRange(FaceBlock.FromImage(file).ToBytes());
            }


            
string fName = Path.Combine(directory, Path.GetDirectoryName(directory) + ".cfc");
            FileStream fs 
= File.Create(fName);
            fs.Write(bytes.ToArray(), 
0, bytes.Count);
            fs.Close();
        }


        
//判断是否为图像文件,方法比较简陋。
        private static bool IsImageFile(string file)
        
{
            List
<string> validExt = new List<string>(new string[]{
                
".bmp",
                
".jpg",
                
".jpeg",
                
".gif",
                
".png",
            }
);

            
return validExt.Contains(Path.GetExtension(file).ToLower());
        }

    }

好,有了上面的方法,我们就可以调用了。
调用方法实在是有些简单。

FaceHelper.BuildCFCFileFromDirectory(Server.MapPath("~/img/"));

这样就OK了,现在去你的网站根目录下看看,有没有一个img.cfc的文件呢?再双击一下,是不是将img目录下的文件全部导入到QQ表情里了呢? enjoy coding!

本文原发:无垠IT教学网
如有不妥,请各位光临论坛指教。
posted on 2006-10-03 15:15  嘻哈呵嘿  阅读(34587)  评论(6编辑  收藏  举报
欢迎访问无垠IT教学网论坛