Contexte : Je n'ai rien à faire ces derniers temps, et à la demande d'un membre du forum, j'ai souhaité créer un site de téléchargement d'émoticônes QQ. À l'origine, les choses étaient très simples, il suffit d'écrire un petit CRUD, mais comme Hahahaha est un programmeur .Net, il doit bien sûr utiliser .Net pour l'implémenter. Aujourd'hui, nous utiliserons .Net pour implémenter la fonction d'empaquetage du format d'expression CFC (custom face cab ?).
Pour réaliser cette fonction, il faut d’abord comprendre ce format, d’abord le rechercher sur Google. Nous avons trouvé cet article de l'Université Tsinghua : Explication détaillée du format de fichier FC.
De cet article, nous avons appris que le format de fichier CFC est à peu près le suivant :
Un bloc comporte 15 champs, comme suit :
longueur de chaîne md5, longueur de touche de raccourci de 4 octets, longueur de nom d'émoticône de 4 octets, longueur de nom de fichier d'émoticône de 4 octets, longueur de fichier d'émoticône de 4 octets, longueur de nom de fichier miniature de 4 octets, Longueur du fichier miniature de 4 octets, numéro de cadre du fichier d'émoticône de 4 octets, image de 4 octets forme de chaîne md5 touche de raccourci nom de l'émoticône nom du fichier d'émoticône nom de fichier miniature contenu du fichier d'émoticône contenu de la miniature Connaissez simplement le format Terminé, définissons une structure (struct) pas à pas
1 Structure#region Structure
2 structures publiques FaceBlock
3 {
4 uint public MD5Length ; //32
5 public uintcutLength; //4
6 public uint FaceNameLength; //4
7 public uint FaceFileNameLength; //36 md5 + extension
8 public uint FileLength;
9 public uint ThumbnailFileNameLength; //41 md5 + fixe.bmp
10 public uint ThumbnailFileLength ;
11 public uint FrameLength ;
12 chaînes publiques MD5 ;
13 uintcuts de chaînes publiques ;
14 chaîne publique FaceName ;
15 chaîne publique FaceFileName ;
16 chaîne publique ThumbnailFileName ;
17 octets publics[] FaceData ;
18 octets publics[] ThumbnailData ;
19
20 FaceBlock statique public FromImage (fichier de chaîne)
vingt-et-un {
22 return FaceHelper.GetFaceBlockFromImage(file);
vingt-trois }
vingt-quatre
25 octets[] GetBytes (valeur uint)
26 {
27 octets[] bt = BitConverter.GetBytes(value);
28 List
29 octets.AddRange(bt);
30 si (octets.Count < 4)
31 {
32 int l = 4 - octets.Count ;
33 pour (int i = 0; i < l; i++)
34 octets.Add((byte)0);
35}
36 octets de retour.ToArray();
37 }
38
39 octets publics[]ToBytes()
40 {
41 List
42 Codage e = Encodage.ASCII;
43 octets.AddRange(GetBytes(MD5Length));
44 octets.AddRange(GetBytes(uintcutLength));
45 octets.AddRange(GetBytes(FaceNameLength));
46 octets.AddRange(GetBytes(FaceFileNameLength));
47 octets.AddRange(GetBytes(FileLength));
48 octets.AddRange(GetBytes(ThumbnailFileNameLength));
49 octets.AddRange(GetBytes(ThumbnailFileLength));
50 octets.AddRange(GetBytes(FrameLength));
51
52 octets.AddRange(e.GetBytes(MD5));
53 octets.AddRange(e.GetBytes(uintcuts));
54 octets.AddRange(e.GetBytes(FaceName));
55 octets.AddRange(e.GetBytes(FaceFileName));
56 octets.AddRange(e.GetBytes(ThumbnailFileName));
57
58 octets.AddRange(FaceData);
59 octets.AddRange(ThumbnailData);
60
61 octets de retour.ToArray();
62 }
63}
64 #endregion contient deux méthodes, l'une est une méthode statique pour obtenir cette structure à partir du fichier et l'autre consiste à convertir cette structure en un tableau d'octets.
Créons une autre classe et nommons-la : FaceHelper
Le code est le suivant :
classe publique FaceHelper
{
FaceBlock statique interne GetFaceBlockFromImage (fichier de chaîne)
{
FaceBlock fb = nouveau FaceBlock();
// Ouvrir le flux de fichiers
FileStream fs = nouveau FileStream(file, FileMode.Open, FileAccess.Read);
//Récupère l'image
Image img = Image.FromStream(fs);
//Obtenir une vignette 20*20
Vignette de l'image = img.GetThumbnailImage(20, 20, null, IntPtr.Zero);
MemoryStream ms = nouveau MemoryStream();
//Convertir l'image miniature en un tableau d'octets
vignette.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] thumbnailData = ms.ToArray();
ms.Close();
ms.Dispose();
thumbnail.Dispose();
//Obtenir une chaîne MD5 unique
chaîne md5 = GetMD5(fs);
//Nom du fichier, le format est : md5 + extension
string fileName = string.Format("{0}{1}", md5, Path.GetExtension(file));
//Nom du fichier de miniature, format : md5 +fixe.bmp
string thumbnailName = string.Format("{0}fixed.bmp", md5);
//Définit une touche de raccourci aléatoire
chaîne uintcuts = "qq.5inet.net_" + RandomNum(6);
fs.Close();
fs.Dispose();
//Obtenir le nombre total d'images
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(fichier);
fb.FileLength = (uint)fb.FaceData.Length;
fb.ThumbnailData = miniatureData;
fb.ThumbnailFileLength = (uint)thumbnailData.Length;
fb.FrameLength = (uint)frameCount;
return fb;
}
Aide#région Aide
//méthode aléatoire
chaîne statique interne RandomNum(int n) //
{
chaîne strchar = "0,1,2,3,4,5,6,7,8,9" ;
string[] VcArray = strchar.Split(',');
string VNum = "";//Comme la chaîne est très courte, F77pclw,cnetworkG|?,ye,e'b n'a pas besoin de StringBuilder
int temp = -1; //Enregistrez la dernière valeur aléatoire et essayez d'éviter de générer plusieurs nombres aléatoires identiques.
//Utilisez un algorithme simple pour garantir la différence entre les nombres aléatoires générés
Rand aléatoire = new Random();
pour (int i = 1; i < n + 1; i++)
{
si (temp != -1)
{
rand = new Random(i * temp * unchecked((int)
DateTime.Now.Ticks));
}
//int t = rand.Next(35);
int t = rand.Next(10);
si (temp != -1 && temp == t)
{
retourner RandomNum(n);
}
température = t ;
VNum += VcArray[t];
}
return VNum;//Renvoyer le nombre aléatoire généré
}
//Obtenir MD5 à partir du nom de fichier
chaîne statique interne GetMD5 (FileStream fs)
{
MD5CryptoServiceProvider md5 = nouveau MD5CryptoServiceProvider();
octet[] md5byte = md5.ComputeHash(fs);
string str = string.Empty;
int je, j;
foreach (octet b dans md5byte)
{
je = Convertir.ToInt32(b);
j = je >> 4;
str += (Convertir.ToString(j, 16));
j = ((i << 4) & 0x00ff) >> 4;
str += (Convertir.ToString(j, 16));
}
return str.ToUpper();
}
#endregion
//Générer une collection de fichiers CFC à partir d'un répertoire
vide statique public
BuildCFCFileFromDirectory (répertoire de chaînes)
{
List
foreach (fichier de chaîne dans Directory.GetFiles (répertoire))
{
si (!IsImageFile(fichier))
continuer ;
octets.AddRange(FaceBlock.FromImage(file).ToBytes());
}
chaîne fName = Path.Combine(répertoire, Path.GetDirectoryName(répertoire) + ".cfc");
FileStream fs = File.Create(fName);
fs.Write(bytes.ToArray(), 0, bytes.Count);
fs.Close();
}
//La méthode pour déterminer s'il s'agit d'un fichier image est relativement simple.
bool statique privé IsImageFile (fichier de chaîne)
{
List
".bmp",
".jpg",
".jpeg",
".gif",
".png",
});
renvoie validExt.Contains(Path.GetExtension(file).ToLower());
}
}
D'accord, avec la méthode ci-dessus, nous pouvons l'appeler.
Appeler la méthode est vraiment simple.
FaceHelper.BuildCFCFileFromDirectory(Server.MapPath("~/img/"));
C'est bon. Allez maintenant dans le répertoire racine de votre site Web et voyez s'il y a un fichier img.cfc ? Double-cliquez à nouveau. Tous les fichiers du répertoire img ont-ils été importés dans les émoticônes QQ ? Profitez du codage !
Cet article a été initialement publié par : Wuyuan IT Teaching Network
http://www.cnblogs.com/skyover/archive/2006/10/03/520581.html