前些天发表了一个帖子 由于没阐述清楚 引发了众多朋友的口水,对此道歉!现在我重新描述一下!我现在要实现的是将所有影像格式的文件或者所有图片格式的文件,通过我的程序,能够压缩到一起!这个程序有如下要求!
1. 有解析功能,能够将我合成后的这个文件解析显示出来
2. 假如是将10个文件压缩在一起了,可以任意打开其中的一个或多个文件。比如说打开第4个和第7个 就是将4和7组合起 来!
3. 这些文件的组合方式就如同WORD文档里插入了几张图片那样, 不交叉的一个跟着一个排列开来!不需要按坐标或者其他标志重叠!希望大家能给点思路!对于新格式的定义 以及 解析 给点想法 咱一窍不通
1. 有解析功能,能够将我合成后的这个文件解析显示出来
2. 假如是将10个文件压缩在一起了,可以任意打开其中的一个或多个文件。比如说打开第4个和第7个 就是将4和7组合起 来!
3. 这些文件的组合方式就如同WORD文档里插入了几张图片那样, 不交叉的一个跟着一个排列开来!不需要按坐标或者其他标志重叠!希望大家能给点思路!对于新格式的定义 以及 解析 给点想法 咱一窍不通
因为这些信息在压缩格式下浏览以及解压缩的时候都有用的。
至于压缩算法,网上或者.net类库里面有现成的,直接拿来用就行了。
1.任何文件要加进去都AppendFile一下,通过纯字节方式自动打包进c:\A.ALL,
2.要解析出哪个文件就ExtractFile出哪个,还能另存
3.不是很理解你说的解出第4个和第7个,又说组合起来是什么意思,反正合并和解析都写了,基本功能算可以了吧4.如果你说的是多张不同格式图片合并成一张图片,那也许可以试试把图片都image.save成bitmap,然后都g.draw到一个大的新bitmap里去using System;
using System.Collections.Generic;
using System.Text;
using System.IO;namespace ConsoleApplication22
{
class Program
{
const String ObjectFileName = @"c:\A.ALL"; static void Main(string[] args)
{
File.Delete(ObjectFileName);
AppendFile(@"c:\windows\system.ini");
AppendFile(@"c:\windows\regedit.exe");
Console.WriteLine("合并完成");
ExtractFile(@"system.ini", @"c:\system2.ini");
ExtractFile(@"regedit.exe", @"c:\regedit2.exe");
Console.WriteLine("分解完成");
Console.Read(); } static void AppendFile(String AppendFileName)
{
FileStream ObjectFS = null;
FileStream FS = null;
try
{
ObjectFS = new FileStream(ObjectFileName, FileMode.Append);
FS = new FileStream(AppendFileName, FileMode.Open);
ObjectFS.Seek(0, SeekOrigin.End);
char[] Length = new char[10];
FS.Length.ToString().CopyTo(0, Length, 0, FS.Length.ToString().Length);
foreach (char C in Length)
ObjectFS.WriteByte((byte)C);
char[] Name = new char[256];
Path.GetFileName(AppendFileName).CopyTo(0, Name, 0, Path.GetFileName(AppendFileName).Length);
foreach (char C in Name)
ObjectFS.WriteByte((byte)C);
FS.Seek(0, SeekOrigin.Begin);
while (FS.Position < FS.Length)
ObjectFS.WriteByte((byte)FS.ReadByte());
}
finally
{
if (FS != null)
FS.Close();
if (ObjectFS != null)
ObjectFS.Close();
}
} static void ExtractFile(String ExtractFileName, String SaveToFileName)
{
FileStream ObjectFS = null;
FileStream FS = null;
try
{
ObjectFS = new FileStream(ObjectFileName, FileMode.OpenOrCreate);
ObjectFS.Seek(0, SeekOrigin.Begin);
byte[] FileLength = new byte[10];
ObjectFS.Read(FileLength, 0, 10);
String LengthString = String.Empty;
foreach (byte B in FileLength)
LengthString += (char)B;
int Length = int.Parse(LengthString);
byte[] FileName = new byte[256];
ObjectFS.Read(FileName, 0, 256);
String Name = String.Empty;
foreach (byte B in FileName)
if ((char)B != '\0')
Name += (char)B;
else
break;
while (Name != ExtractFileName)
{
ObjectFS.Seek(Length, SeekOrigin.Current);
int x = ObjectFS.Read(FileLength, 0, 10);
LengthString = String.Empty;
foreach (byte B in FileLength)
LengthString += (char)B;
Length = int.Parse(LengthString.Trim());
ObjectFS.Read(FileName, 0, 256);
Name = String.Empty;
foreach (byte B in FileName)
if ((char)B != '\0')
Name += (char)B;
else
break;
}
if (ObjectFS.Position < ObjectFS.Length)
{
FS = new FileStream(SaveToFileName, FileMode.Create);
for (int i = 0; i < Length; i++)
FS.WriteByte((byte)ObjectFS.ReadByte());
}
}
finally
{
if (FS != null)
FS.Close();
if (ObjectFS != null)
ObjectFS.Close();
}
}
}
}
下面是一个psd格式的C#操作类
http://tech.e800.com.cn/articles/2009/525/1243217133388_1.html
ps:如果你觉得psd或者mapx格式理解起来有困难或没那么多时间去理解,那么就请自己设计格式
ls的代码实际就是一个自己设计的格式,但是少了一部分和图层分布的信息呵呵,如果你操作过photoshop或flash那么你可能会更能理解我说的,
按lz的描述,你想设计的东西应该是和flash的图层和元件库很类似吧如果是我,如果不是为通用性的话,我可能直接设计一个可序列化的类就成,当然还要设计一个能对这个类进行显示操作的控件。
class 图层信息
{
image 图形元素;
point 图形位置;
bool 是否显示;
}class 图形包
{
image 底图;
image[] 图层的集合;
}
上面是一个基本思路,如果你看明白了自己去扩展他把
或者干脆啥不不理,直接设计一个xml文件,图形数据直接 base64后,然后cdate入xml节点
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;namespace ConsoleApplication22
{
class Program
{
const String ObjectFileName = @"c:\A.ALL"; // 最终合并文件名 static void Main(string[] args)
{
File.Delete(ObjectFileName);// 最终合并文件如果存在,则删除,重新创建
AppendFile(@"c:\windows\system.ini"); // 添加第一个文件到最终合并文件
AppendFile(@"c:\windows\regedit.exe"); // 添加第二个文件到最终合并文件
Console.WriteLine("合并完成");
ExtractFile(@"system.ini", @"c:\system2.ini"); // 分解当初的合并文件"system.ini"从最终合并文件并另存为c:\system2.ini
ExtractFile(@"regedit.exe", @"c:\regedit2.exe"); // 分解当初的合并文件"regedit.exe"从最终合并文件并另存为c:\regedit2.exe
Console.WriteLine("分解完成");
Console.Read(); } static void AppendFile(String AppendFileName)
{
FileStream ObjectFS = null; // 要新建的最终合并文件的文件流
FileStream FS = null; // 要合并的文件的文件流
try
{
ObjectFS = new FileStream(ObjectFileName, FileMode.Append); // 新建最终合并文件
FS = new FileStream(AppendFileName, FileMode.Open); // 打开要合并的文件
ObjectFS.Seek(0, SeekOrigin.End); // 最终合并文件定位到最后准备添加 ,这句多余,我忘删了,本来是打算可以续写,后来觉得没必要
char[] Length = new char[10];
FS.Length.ToString().CopyTo(0, Length, 0, FS.Length.ToString().Length);
foreach (char C in Length)
ObjectFS.WriteByte((byte)C); // 要合并的文件的长度值转换成字节存入
char[] Name = new char[256];
Path.GetFileName(AppendFileName).CopyTo(0, Name, 0, Path.GetFileName(AppendFileName).Length);
foreach (char C in Name)
ObjectFS.WriteByte((byte)C); // 要合并的文件的名称转换成字节存入
FS.Seek(0, SeekOrigin.Begin);
while (FS.Position < FS.Length)
ObjectFS.WriteByte((byte)FS.ReadByte()); // 要合并的文件的具体内容转换成字节存入
}
finally
{
if (FS != null)
FS.Close();
if (ObjectFS != null)
ObjectFS.Close();
}
} static void ExtractFile(String ExtractFileName, String SaveToFileName)
{
FileStream ObjectFS = null; // 要分解的最终合并文件的文件流
FileStream FS = null; // 要另存的文件的文件流
try
{
ObjectFS = new FileStream(ObjectFileName, FileMode.OpenOrCreate); // 打开要分解的最终合并文件
ObjectFS.Seek(0, SeekOrigin.Begin); // 要分解的最终合并文件定位到开始
byte[] FileLength = new byte[10];
ObjectFS.Read(FileLength, 0, 10); // 读出文件长度值
String LengthString = String.Empty;
foreach (byte B in FileLength)
LengthString += (char)B;
int Length = int.Parse(LengthString);
byte[] FileName = new byte[256];
ObjectFS.Read(FileName, 0, 256); // 读出文件名
String Name = String.Empty;
foreach (byte B in FileName)
if ((char)B != '\0')
Name += (char)B;
else
break;
while (Name != ExtractFileName) // 如果这个文件不是要分解的,继续往下搜索
{
ObjectFS.Seek(Length, SeekOrigin.Current); //要分解的最终合并文件定位到当前+文件具体内容长度,就是跳过这个文件
int x = ObjectFS.Read(FileLength, 0, 10); // 读出文件长度值
LengthString = String.Empty;
foreach (byte B in FileLength)
LengthString += (char)B;
Length = int.Parse(LengthString.Trim());
ObjectFS.Read(FileName, 0, 256); // 读出文件名
Name = String.Empty;
foreach (byte B in FileName)
if ((char)B != '\0')
Name += (char)B;
else
break;
}
if (ObjectFS.Position < ObjectFS.Length) // 如果没有到要分解的最终合并文件尾,说明有内容,文件没被破坏,就另存
{
FS = new FileStream(SaveToFileName, FileMode.Create);
for (int i = 0; i < Length; i++)
FS.WriteByte((byte)ObjectFS.ReadByte()); // 另存
}
}
finally
{
if (FS != null)
FS.Close();
if (ObjectFS != null)
ObjectFS.Close();
}
}
}
}