Antecedentes: Não tenho nada para fazer recentemente e, a pedido de um membro do fórum, queria criar um site para download de emoticons QQ. Originalmente as coisas eram muito simples, bastava escrever um pequeno CRUD, mas como Hahahaha é um programador .Net, é claro que ele tem que usar .Net para implementá-lo. Hoje usaremos .Net para implementar a função de empacotamento do formato de expressão CFC (custom face cab?).
Para alcançar esta função, devemos primeiro entender este formato, primeiro pesquisá-lo no Google. Encontramos este artigo da Universidade de Tsinghua: Explicação detalhada do formato de arquivo FC.
Neste artigo, aprendemos que o formato de arquivo CFC é aproximadamente o seguinte:
Um bloco tem 15 campos, como segue:
comprimento da string md5, comprimento da tecla de atalho de 4 bytes, comprimento do nome do emoticon de 4 bytes, comprimento do nome do arquivo emoticon de 4 bytes, comprimento do arquivo emoticon de 4 bytes, comprimento do nome do arquivo de miniatura de 4 bytes, Comprimento do arquivo em miniatura de 4 bytes, número do quadro do arquivo emoticon de 4 bytes, imagem de 4 bytes forma de string md5 tecla de atalho nome do emoticon nome do arquivo emoticon nome do arquivo em miniatura conteúdo do arquivo emoticon conteúdo da miniatura Apenas conheça o formato Feito, vamos definir uma estrutura (estrutura) passo a passo
1 Estrutura#região Estrutura
2 estrutura pública FaceBlock
3 {
4 unidade pública MD5Length; //32
5 public uint uintcutLength; //4
6 public uint FaceNameLength; //4
7 public uint FaceFileNameLength; //36 md5 + extensão
8 uint público FileLength;
9 public uint ThumbnailFileNameLength; //41 md5 + fixo.bmp
10 público uint ThumbnailFileLength;
11 unidade pública FrameLength;
12 cadeia pública MD5;
13 cortes de string públicos;
14 string pública FaceName;
15 string pública FaceFileName;
16 string pública ThumbnailFileName;
17 bytes públicos[] FaceData;
18 bytes públicos[] ThumbnailData;
19
20 FaceBlock estático público FromImage (arquivo string)
vinte e um {
22 retorne FaceHelper.GetFaceBlockFromImage(arquivo);
vinte e três }
vinte e quatro
25 bytes[] GetBytes(valor uint)
26 {
27 bytes[] bt = BitConverter.GetBytes(valor);
28 Lista
29 bytes.AddRange(bt);
30 se (bytes.Contagem <4)
31 {
32 int l = 4 - bytes.Count;
33 para (int i = 0; i
35}
36 retorna bytes.ToArray();
37}
38
39 bytes públicos[]ToBytes()
40 {
41 Lista
42 Codificação e = Codificação.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 bytes de retorno.ToArray();
62}
63}
64 #endregion contém dois métodos, um é um método estático para obter essa estrutura do arquivo e o outro é converter essa estrutura em uma matriz de bytes.
Vamos criar outra classe e nomeá-la: FaceHelper
O código é o seguinte:
classe pública FaceHelper
{
FaceBlock estático interno GetFaceBlockFromImage (arquivo string)
{
FaceBlock fb = new FaceBlock();
//Abre o fluxo de arquivos
FileStream fs = novo FileStream(arquivo, FileMode.Open, FileAccess.Read);
//Obtém a imagem
Imagem img = Image.FromStream(fs);
//Obter uma miniatura 20*20
Miniatura da imagem = img.GetThumbnailImage(20, 20, null, IntPtr.Zero);
MemoryStream ms = new MemoryStream();
//Converte a imagem em miniatura em uma matriz de bytes
thumbnail.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] thumbnailData = ms.ToArray();
ms.Fechar();
ms.Dispose();
thumbnail.Dispose();
//Obter uma string MD5 exclusiva
string md5 = GetMD5(fs);
//Nome do arquivo, o formato é: md5 + extensão
string fileName = string.Format("{0}{1}", md5, Path.GetExtension(arquivo));
//Nome do arquivo em miniatura, formato: md5 + fixo.bmp
string thumbnailName = string.Format("{0}fixed.bmp", md5);
//Definir uma tecla de atalho aleatória
string uintcuts = "qq.5inet.net_" + RandomNum(6);
fs.Fechar();
fs.Dispose();
//Obtém o número total de quadros
System.Drawing.Imaging.FrameDimension fd = System.Drawing.Imaging.FrameDimension.Resolution;
int frameCount = img.FrameDimensionsList.Length;
img.Dispose()
;
fb.MD5Length = (uint)md5.Length;
fb.uintcuts = uintcuts;
fb.uintcutLength = (uint)uintcuts.Length;
fb.FaceName = uintcuts;
fb.FaceNameLength = (uint)uintcuts.Length;
fb.FaceFileName = nomedoarquivo;
fb.FaceFileNameLength = (uint)fileName.Length;
fb.ThumbnailFileName = miniaturaNome;
fb.ThumbnailFileNameLength = (uint)thumbnailName.Length;
fb.FaceData = Arquivo.ReadAllBytes(arquivo);
fb.FileLength = (uint)fb.FaceData.Length;
fb.ThumbnailData = miniaturaData;
fb.ThumbnailFileLength = (uint)thumbnailData.Length;
fb.FrameLength = (uint)frameCount
;
}
Ajudante#região Ajudante
//método aleatório
string estática interna RandomNum(int n) //
{
stringstrchar = "0,1,2,3,4,5,6,7,8,9";
string[] VcArray = strchar.Split(',');
string VNum = "";//Como a string é muito curta, F77pclw,cnetworkG|?,ye,e'b não precisa do StringBuilder
int temp = -1; //Registre o último valor aleatório e tente evitar gerar vários números aleatórios idênticos.
//Use um algoritmo simples para garantir a diferença nos números aleatórios gerados
Rand aleatório = new Random();
para (int i = 1; i
se (temperatura! = -1)
{
rand = new Random(i * temp * unchecked((int)
DateTime.Now.Ticks));
}
//int t = rand.Next(35);
int t = rand.Next(10);
if (temperatura! = -1 && temp == t)
{
returnNumAleatório(n);
}
temperatura = t;
VNum += VcArray[t];
}
return VNum; //Retorna o número aleatório gerado
}
//Obtém MD5 do nome do arquivo
string estática interna GetMD5 (FileStream fs)
{
MD5CryptoServiceProvider md5 = novo MD5CryptoServiceProvider();
byte[] md5byte = md5.ComputeHash(fs);
string str = string.Empty;
int eu, j;
foreach (byte b em md5byte)
{
i = Convert.ToInt32(b);
j = eu >> 4;
str += (Convert.ToString(j, 16));
j = ((i << 4) & 0x00ff) >> 4;
str += (Convert.ToString(j, 16));
}
return str.ToUpper();
}
#endregion
//Gera uma coleção de arquivos CFC de um diretório
vazio estático público
BuildCFCFileFromDirectory(diretório de string)
{
Lista
foreach (arquivo de string em Directory.GetFiles(diretório))
{
if (!IsImageFile(arquivo))
continuar;
bytes.AddRange(FaceBlock.FromImage(arquivo).ToBytes());
}
string fName = Path.Combine(diretório, Path.GetDirectoryName(diretório) + ".cfc");
FileStream fs = Arquivo.Create(fNome);
fs.Write(bytes.ToArray(), 0, bytes.Count);
fs.Fechar();
}
//O método para determinar se é um arquivo de imagem é relativamente simples.
bool estático privado IsImageFile (arquivo string)
{
Lista
".bmp",
".jpg",
".jpeg",
".gif",
".png",
});
return validExt.Contains(Path.GetExtension(arquivo).ToLower());
}
}
Ok, com o método acima, podemos chamá-lo.
Chamar o método é muito simples.
FaceHelper.BuildCFCFileFromDirectory(Server.MapPath("~/img/"));
Tudo bem. Agora vá para o diretório raiz do seu site e veja se existe um arquivo img.cfc. Clique duas vezes novamente. Todos os arquivos do diretório img foram importados para os emoticons QQ? Aproveite a codificação!
Este artigo foi publicado originalmente por: Wuyuan IT Teaching Network
http://www.cnblogs.com/skyover/archive/2006/10/03/520581.html