Hintergrund: Ich hatte in letzter Zeit nichts zu tun und wollte auf Wunsch eines Mitglieds des Forums eine Website zum Herunterladen von QQ-Emoticons erstellen. Ursprünglich waren die Dinge sehr einfach: Schreiben Sie einfach ein kleines CRUD, aber da Hahahaha ein .Net-Programmierer ist, muss er natürlich .Net verwenden, um es zu implementieren. Heute werden wir .Net verwenden, um die Verpackungsfunktion des CFC-Ausdrucksformats (Custom Face Cab?) zu implementieren.
Um diese Funktion zu erreichen, müssen wir zuerst dieses Format verstehen und es zuerst googeln. Wir haben diesen Artikel von der Tsinghua-Universität gefunden: Ausführliche Erklärung des FC-Dateiformats.
Aus diesem Artikel haben wir erfahren, dass das CFC-Dateiformat ungefähr wie folgt lautet:
Ein Block hat 15 Felder wie folgt:
Länge der MD5-Zeichenfolge, Länge der Tastenkombination 4 Byte, Länge des Emoticon-Namens 4 Byte, Länge des Namens der Emoticon-Datei 4 Byte, Länge der Emoticon-Datei 4 Byte, Länge des Dateinamens der Miniaturansicht 4 Byte, 4-Byte-Miniaturdateilänge, 4-Byte-Bildnummer der Emoticondatei, 4-Byte-Bild-MD5-Zeichenfolgenform Tastenkombination Emoticonname Emoticondateiname Miniaturbild Dateiname Emoticondateiinhalt Miniaturbildinhalt Kennen Sie einfach das Format Fertig, definieren wir eine Struktur (Struktur) Schritt für Schritt
1 Struktur#Region Struktur
2 öffentliche Struktur FaceBlock
3 {
4 public uint MD5Length; //32
5 public uint uintcutLength; //4
6 public uint FaceNameLength; //4
7 public uint FaceFileNameLength; //36 md5 + Erweiterung
8 public uint FileLength;
9 public uint ThumbnailFileNameLength; //41 md5 + Fixed.bmp
10 public uint ThumbnailFileLength;
11 public uint FrameLength;
12 öffentliche Zeichenfolge MD5;
13 öffentliche String-Uintcuts;
14 öffentliche Zeichenfolge FaceName;
15 öffentliche Zeichenfolge FaceFileName;
16 öffentliche Zeichenfolge ThumbnailFileName;
17 öffentliches Byte[] FaceData;
18 öffentliches Byte[] ThumbnailData;
19
20 öffentliches statisches FaceBlock FromImage (String-Datei)
einundzwanzig {
22 return FaceHelper.GetFaceBlockFromImage(file);
dreiundzwanzig }
vierundzwanzig
25 Byte[] GetBytes(uint-Wert)
26 {
27 byte[] bt = BitConverter.GetBytes(value);
28 List
29 Bytes.AddRange(bt);
30 if (bytes.Count < 4)
31 {
32 int l = 4 - bytes.Count;
33 für (int i = 0; i < l; i++)
34 Bytes.Add((byte)0);
35}
36 Rückgabebytes.ToArray();
37 }
38
39 öffentliches Byte[]ToBytes()
40 {
41 List
42 Codierung e = Encoding.ASCII;
43 Bytes.AddRange(GetBytes(MD5Length));
44 Bytes.AddRange(GetBytes(uintcutLength));
45 Bytes.AddRange(GetBytes(FaceNameLength));
46 Bytes.AddRange(GetBytes(FaceFileNameLength));
47 Bytes.AddRange(GetBytes(FileLength));
48 Bytes.AddRange(GetBytes(ThumbnailFileNameLength));
49 Bytes.AddRange(GetBytes(ThumbnailFileLength));
50 Bytes.AddRange(GetBytes(FrameLength));
51
52 Bytes.AddRange(e.GetBytes(MD5));
53 Bytes.AddRange(e.GetBytes(uintcuts));
54 Bytes.AddRange(e.GetBytes(FaceName));
55 Bytes.AddRange(e.GetBytes(FaceFileName));
56 Bytes.AddRange(e.GetBytes(ThumbnailFileName));
57
58 Bytes.AddRange(FaceData);
59 Bytes.AddRange(ThumbnailData);
60
61 Rückgabebytes.ToArray();
62 }
63}
64 #endregion enthält zwei Methoden: Eine ist eine statische Methode zum Abrufen dieser Struktur aus der Datei und die andere dient zum Konvertieren dieser Struktur in ein Byte-Array.
Erstellen wir eine weitere Klasse und benennen sie: FaceHelper
Der Code lautet wie folgt:
öffentliche Klasse FaceHelper
{
interner statischer FaceBlock GetFaceBlockFromImage(String-Datei)
{
FaceBlock fb = new FaceBlock();
//Dateistream öffnen
FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read);
//Hol dir das Bild
Bild img = Image.FromStream(fs);
//Erhalte ein 20*20-Thumbnail
Bild-Miniaturansicht = img.GetThumbnailImage(20, 20, null, IntPtr.Zero);
MemoryStream ms = new MemoryStream();
//Konvertieren Sie das Miniaturbild in ein Byte-Array
thumbnail.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] thumbnailData = ms.ToArray();
ms.Close();
ms.Dispose();
thumbnail.Dispose();
//Eine eindeutige MD5-Zeichenfolge abrufen
string md5 = GetMD5(fs);
//Dateiname, das Format ist: MD5 + Erweiterung
string fileName = string.Format("{0}{1}", md5, Path.GetExtension(file));
//Thumbnail-Dateiname, Format: MD5 + Fixed.bmp
string thumbnailName = string.Format("{0}fixed.bmp", md5);
//Legen Sie eine zufällige Tastenkombination fest
string uintcuts = "qq.5inet.net_" + RandomNum(6);
fs.Close();
fs.Dispose();
//Erhalte die Gesamtzahl der Frames
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 = Dateiname;
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;
}
Helfer#region Helfer
//Zufallsmethode
interner statischer String RandomNum(int n) //
{
string strchar = "0,1,2,3,4,5,6,7,8,9";
string[] VcArray = strchar.Split(',');
string VNum = "";//Da die Zeichenfolge sehr kurz ist, benötigt F77pclw,cnetworkG|?,ye,e'b keinen StringBuilder
int temp = -1; //Den letzten Zufallswert aufzeichnen und versuchen, die Generierung mehrerer identischer Zufallszahlen zu vermeiden.
//Verwenden Sie einen einfachen Algorithmus, um den Unterschied in den generierten Zufallszahlen sicherzustellen
Zufälliger Rand = new Random();
for (int i = 1; i < n + 1; i++)
{
if (temp != -1)
{
rand = new Random(i * temp * unchecked((int)
DateTime.Now.Ticks));
}
//int t = rand.Next(35);
int t = rand.Next(10);
if (temp != -1 && temp == t)
{
return RandomNum(n);
}
temp = t;
VNum += VcArray[t];
}
return VNum;//Gib die generierte Zufallszahl zurück
}
//MD5 aus Dateinamen abrufen
interner statischer String GetMD5(FileStream fs)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] md5byte = md5.ComputeHash(fs);
string str = string.Empty;
int i, j;
foreach (Byte b in md5byte)
{
i = Convert.ToInt32(b);
j = i >> 4;
str += (Convert.ToString(j, 16));
j = ((i << 4) & 0x00ff) >> 4;
str += (Convert.ToString(j, 16));
}
return str.ToUpper();
}
#endregion
//Generieren Sie eine CFC-Dateisammlung aus einem Verzeichnis
öffentliche statische Leere
BuildCFCFileFromDirectory(String-Verzeichnis)
{
List
foreach (String-Datei in Directory.GetFiles(Verzeichnis))
{
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();
}
// Die Methode zur Bestimmung, ob es sich um eine Bilddatei handelt, ist relativ einfach.
privater statischer Bool IsImageFile(String-Datei)
{
List
„.bmp“,
„.jpg“,
„.jpeg“,
„.gif“,
„.png“,
});
return validExt.Contains(Path.GetExtension(file).ToLower());
}
}
Okay, mit der obigen Methode können wir es aufrufen.
Der Aufruf der Methode ist wirklich einfach.
FaceHelper.BuildCFCFileFromDirectory(Server.MapPath("~/img/"));
Das ist in Ordnung. Gehen Sie nun in das Stammverzeichnis Ihrer Website und prüfen Sie, ob dort eine img.cfc-Datei vorhanden ist. Doppelklicken Sie erneut. Wurden alle Dateien im IMG-Verzeichnis in QQ-Emoticons importiert? Viel Spaß beim Programmieren!
Dieser Artikel wurde ursprünglich veröffentlicht von: Wuyuan IT Teaching Network
http://www.cnblogs.com/skyover/archive/2006/10/03/520581.html