如何用DELPHI在jpeg等图像文件中插入一定的信息字符串或数字?不影响显示效果!(200分)

  • 主题发起人 主题发起人 ambush
  • 开始时间 开始时间
A

ambush

Unregistered / Unconfirmed
GUEST, unregistred user!
如何利用JPEG文件格式中的结构,将应用程序生成的特定信息保存进去,如作者、创作时间、用途、加密字符串等信息。能给出源码吗?高分奉送啊!
 
一、Delphi中流的基本概念及函数声明
在Delphi中,所有流对象的基类为TStream类,其中定义了所有流的共同属性和方法。
TStream类中定义的属性介绍如下:
1、Size:此属性以字节返回流中数据大小。
2、Position:此属性控制流中存取指针的位置。
Tstream中定义的虚方法有四个:
1、Read:此方法实现将数据从流中读出。函数原形为:
Function Read(var Buffer;Count:Longint):Longint;virtual;abstract;
参数Buffer为数据读出时放置的缓冲区,Count为需要读出的数据的字节数,该方法返回值为实际读出的字节数,它可以小于或等于Count中指定的值。
2、Write:此方法实现将数据写入流中。函数原形为:
Function Write(var Buffer;Count:Longint):Longint;virtual;abstract;
参数Buffer为将要写入流中的数据的缓冲区,Count为数据的长度字节数,该方法返回值为实际写入流中的字节数。
3、Seek:此方法实现流中读取指针的移动。函数原形为:
Function Seek(Offset:Longint;Origint:Word):Longint;virtual;abstract;
参数Offset为偏移字节数,参数Origint指出Offset的实际意义,其可能的取值如下:
soFromBeginning:Offset为移动后指针距离数据开始的位置。此时Offset必须大于或者等于零。
soFromCurrent:Offset为移动后指针与当前指针的相对位置。
soFromEnd:Offset为移动后指针距离数据结束的位置。此时Offset必须小于或者等于零。该方法返回值为移动后指针的位置。
4、Setsize:此方法实现改变数据的大小。函数原形为:
Function Setsize(NewSize:Longint);virtual;
另外,TStream类中还定义了几个静态方法:
1、ReadBuffer:此方法的作用是从流中当前位置读取数据。函数原形为:
Procedure ReadBuffer(var Buffer;Count:Longint);
参数的定义跟上面的Read相同。注意:当读取的数据字节数与需要读取的字节数不相同时,将产生EReadError异常。
2、WriteBuffer:此方法的作用是在当前位置向流写入数据。函数原形为:
Procedure WriteBuffer(var Buffer;Count:Longint);
参数的定义跟上面的Write相同。注意:当写入的数据字节数与需要写入的字节数不相同时,将产生EWriteError异常。
3、CopyFrom:此方法的作用是从其它流中拷贝数据流。函数原形为:
Function CopyFrom(Source:TStream;Count:Longint):Longint;
参数Source为提供数据的流,Count为拷贝的数据字节数。当Count大于0时,CopyFrom从Source参数的当前位置拷贝Count个字节的数据;当Count等于0时,CopyFrom设置Source参数的Position属性为0,然后拷贝Source的所有数据;
TStream还有其它派生类,其中最常用的是TFileStream类。使用TFileStream类来存取文件,首先要建立一个实例。声明如下:
constructor Create(const Filename:string;Mode:Word);
Filename为文件名(包括路径),参数Mode为打开文件的方式,它包括文件的打开模式和共享模式,其可能的取值和意义如下:
打开模式:
fmCreate :用指定的文件名建立文件,如果文件已经存在则打开它。
fmOpenRead :以只读方式打开指定文件
fmOpenWrite :以只写方式打开指定文件
fmOpenReadWrite:以写写方式打开指定文件
共享模式:
fmShareCompat :共享模式与FCBs兼容
fmShareExclusive:不允许别的程序以任何方式打开该文件
fmShareDenyWrite:不允许别的程序以写方式打开该文件
fmShareDenyRead :不允许别的程序以读方式打开该文件
fmShareDenyNone :别的程序可以以任何方式打开该文件
TStream还有一个派生类TMemoryStream,实际应用中用的次数也非常频繁。它叫内存流,就是说在内存中建立一个流对象。它的基本方法和函数跟上面是一样的。
好了,有了上面的基础后,我们就可以开始我们的编程之行了。
-----------------------------------------------------------------------
二、实际应用之一:利用流制作EXE文件加密器、捆绑、自解压文件及安装程序
我们先来说一下如何制作一个EXE文件加密器吧。
EXE文件加密器的原理:建立两个文件,一个用来添加资源到另外一个EXE文件里面,称为添加程序。另外一个被添加的EXE文件称为头文件。该程序的功能是把添加到自己里面的文件读出来。Windows下的EXE文件结构比较复杂,有的程序还有校验和,当发现自己被改变后会认为自己被病毒感染而拒绝执行。所以我们把文件添加到自己的程序里面,这样就不会改变原来的文件结构了。我们先写一个添加函数,该函数的功能是把一个文件当作一个流添加到另外一个文件的尾部。函数如下:
Function Cjt_AddtoFile(SourceFile,TargetFile:string):Boolean;
var
Target,Source:TFileStream;
MyFileSize:integer;
begin
try
Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareExclusive);
Target:=TFileStream.Create(TargetFile,fmOpenWrite or fmShareExclusive);
try
Target.Seek(0,soFromEnd);//往尾部添加资源
Target.CopyFrom(Source,0);
MyFileSize:=Source.Size+Sizeof(MyFileSize);//计算资源大小,并写入辅程尾部
Target.WriteBuffer(MyFileSize,sizeof(MyFileSize));
finally
Target.Free;
Source.Free;
end;
except
Result:=False;
Exit;
end;
Result:=True;
end;
有了上面的基础,我们应该很容易看得懂这个函数。其中参数SourceFile是要添加的文件,参数TargetFile是被添加到的目标文件?热缢蛋補.exe添加到b.exe里面可以:Cjt_AddtoFile('a.exe',b.exe');如果添加成功就返回True否则返回假。
根据上面的函数我们可以写出相反的读出函数:
Function Cjt_LoadFromFile(SourceFile,TargetFile :string):Boolean;
var
Source:TFileStream;
Target:TMemoryStream;
MyFileSize:integer;
begin
try
Target:=TMemoryStream.Create;
Source:=TFileStream.Create(SourceFile,fmOpenRead or fmShareDenyNone);
try
Source.Seek(-sizeof(MyFileSize),soFromEnd);
Source.ReadBuffer(MyFileSize,sizeof(MyFileSize));//读出资源大小
Source.Seek(-MyFileSize,soFromEnd);//定位到资源位置
Target.CopyFrom(Source,MyFileSize-sizeof(MyFileSize));//取出资源
Target.SaveToFile(TargetFile);//存放到文件
finally
Target.Free;
Source.Free;
end;
except
Result:=false;
Exit;
end;
Result:=true;
end;
其中参数SourceFile是已经添加了文件的文件名称,参数TargetFile是取出文件后保存的目标文件名?热缢礐jt_LoadFromFile('b.exe','a.txt');在b.exe中取出文件保存为a.txt。如果取出成功就返回True否则返回假。
打开Delphi,新建一个工程,在窗口上放上一个Edit控件Edit1和两个Button:Button1和Button2。Button的Caption属性分别设置为“确定”和“取消”。在Button1的Click事件中写代码:
var S:string;
begin
S:=ChangeFileExt(Application.ExeName,'.Cjt');
if Edit1.Text='790617' then
begin
Cjt_LoadFromFile(Application.ExeName,S);
{取出文件保存在当前路径下并命名"原文件.Cjt"}
Winexec(pchar(S),SW_Show);{运行"原文件.Cjt"}
Application.Terminate;{退出程序}
end
else
Application.MessageBox('密码不对,请重新输入!','密码错误',MB_ICONERROR+MB_OK);
编译这个程序,并把EXE文件改名为head.exe。新建一个文本文件head.rc,内容为: head exefile head.exe,然后把它们拷贝到Delphi的BIN目录下,执行Dos命令Brcc32.exe head.rc,将产生一个head.res的文件,这个文件就是我们要的资源文件,先留着。
我们的头文件已经建立了,下面我们来建立添加程序。
新建一个工程,放上以下控件:一个Edit,一个Opendialog,两个Button1的Caption属性分别设置为"选择文件"和"加密"。在源程序中添加一句:{$R head.res}并把head.res文件拷贝到程序当前目录下。这样一来就把刚才的head.exe跟程序一起编译了。
在Button1的Cilck事件里面写下代码:
if OpenDialog1.Execute then Edit1.Text:=OpenDialog1.FileName;
在Button2的Cilck事件里面写下代码:
var S:String;
begin
S:=ExtractFilePath(Edit1.Text);
if ExtractRes('exefile','head',S+'head.exe') then
if Cjt_AddtoFile(Edit1.Text,S+'head.exe') then
if DeleteFile(Edit1.Text) then
if RenameFile(S+'head.exe',Edit1.Text) then
Application.MessageBox('文件加密成功!','信息',MB_ICONINFORMATION+MB_OK)
else
begin
if FileExists(S+'head.exe') then DeleteFile(S+'head.exe');
Application.MessageBox('文件加密失败!','信息',MB_ICONINFORMATION+MB_OK)
end;
end;
其中ExtractRes为自定义函数,它的作用是把head.exe从资源文件中取出来。
Function ExtractRes(ResType, ResName, ResNewName : String):boolean;
var
Res : TResourceStream;
begin
try
Res := TResourceStream.Create(Hinstance, Resname, Pchar(ResType));
try
Res.SavetoFile(ResNewName);
Result:=true;
finally
Res.Free;
end;
except
Result:=false;
end;
end;
注意:我们上面的函数只不过是简单的把一个文件添加到另一个文件的尾部。实际应用中可以改成可以添加多个文件,只要根据实际大小和个数定义好偏移地址就可以了?热缢滴募?Π蠡?褪前蚜礁龌蛘叨喔龀绦蛱砑拥揭桓鐾肺募?锩妗D切┳越庋钩绦蚝桶沧俺绦虻脑?硪彩且谎?模?还?嗔搜顾醵?选1热缢滴颐强梢砸?靡桓鯨AH单元,把流压缩后再添加,这样文件就会变的很小。读出来时先解压就可以了。另外,文中EXE加密器的例子还有很多不完善的地方,比如说密码固定为"790617",取出EXE运行后应该等它运行完毕后删除等等,读者可以自行修改。
---------------------------------------------------------------------
 
Jpeg图像的Exif就可以保存你要的信息啊。源码我没有,网上有EXIF的文档,你去下载下来看看吧,难度不大,代码还是自己写吧,现成的估计没有。
 
[red]Jpeg图像的Exif中,哪些段是用来扩展的啊?[/red]
 
JPEG文件格式

JPEG是joint Photographic Experts Group(联合图像专家组)的缩写,文件后辍名为".jpg"或".jpeg",是最常用的图像文件格式,由一个软件开发联合会组织制定,是一种有损压缩格式,能够将图像压缩在很小的储存空间,图像中重复或不重要的资料会被丢失,因此容易造成图像数据的损伤。尤其是使用过高的压缩比例,将使最终解压缩后恢复的图像质量明显降低,如果追求高品质图像,不宜采用过高压缩比例。但是JPEG压缩技术十分先进,它用有损压缩方式去除冗余的图像数据,在获得极高的压缩率的同时能展现十分丰富生动的图像,换句话说,就是可以用最少的磁盘空间得到较好的图像品质。而且 JPEG是一种很灵活的格式,具有调节图像质量的功能,允许用不同的压缩比例对文件进行压缩,支持多种压缩级别,压缩比率通常在10:1到40:1之间,压缩比越大,品质就越低;相反地,压缩比越小,品质就越好。比如可以把1.37Mb的BMP位图文件压缩至20.3KB。当然也可以在图像质量和文件尺寸之间找到平衡点。JPEG格式压缩的主要是高频信息,对色彩的信息保留较好,适合应用于互联网,可减少图像的传输时间,可以支持24bit真彩色,也普遍应用于需要连续色调的图像。

JPEG格式是目前网络上最流行的图像格式,是可以把文件压缩到最小的格式,在 Photoshop软件中以JPEG格式储存时,提供11级压缩级别,以0—10级表示。其中0级压缩比最高,图像品质最差。即使采用细节几乎无损的10 级质量保存时,压缩比也可达 5:1。以BMP格式保存时得到4.28MB图像文件,在采用JPG格式保存时,其文件仅为178KB,压缩比达到24:1。经过多次比较,采用第8级压缩为存储空间与图像质量兼得的最佳比例。

JPEG格式的应用非常广泛,特别是在网络和光盘读物上,都能找到它的身影。目前各类浏览器均支持JPEG这种图像格式,因为JPEG格式的文件尺寸较小,下载速度快。

JPEG2000作为JPEG的升级版,其压缩率比JPEG高约30%左右,同时支持有损和无损压缩。JPEG2000格式有一个极其重要的特征在于它能实现渐进传输,即先传输图像的轮廓,然后逐步传输数据,不断提高图像质量,让图像由朦胧到清晰显示。此外,JPEG2000还支持所谓的"感兴趣区域" 特性,可以任意指定影像上感兴趣区域的压缩质量,还可以选择指定的部分先解压缩。

JPEG2000和JPEG相比优势明显,且向下兼容,因此可取代传统的JPEG格式。JPEG2000即可应用于传统的JPEG市场,如扫描仪、数码相机等,又可应用于新兴领域,如网路传输、无线通讯等等。

EXIF格式

EXIF的格式是1994年富士公司提倡的数码相机图像文件格式,其实与JPEG格式相同,区别是除保存图像数据外,还能够存储摄影日期、使用光圈、快门、闪光灯数据等曝光资料和附带信息以及小尺寸图像。
这里的——“附带信息以及小尺寸图像”是什么啊?似乎这个“附带信息”可以利用,是吗?
 
我以前下过Exif2.2文档,现在不知道到哪个版本了,肯定有扩展部分的,你先去找个完整的文档看看,然后找几张没有PS过的JPEG图像写代码读读试试看。现在很多看图软件都可以显示Exif信息的,你可以对照下。
小尺寸图像就是保存在JPEG文件中的缩略图,不是一定有的。
 
Exif文件格式

Exif (Exchangeable image file format) 是可交换图像文件的缩写,是专门为数码相机的照片设定的,可以记录数字照片的属性信息和拍摄数据。

Exif 最初由日本电子工业发展协会在 1996 年制定,版本为 1.0。1998 年,升级到 2.1,增加了对音频文件的支持。2002 年 3 月,发表了 2.2 版。

Exif 可以附加于 JPEG、TIFF、RIFF 等文件之中,为其增加有关数码相机拍摄信息的内容和索引图或图像处理软件的版本信息。
Exif 是一个为数码相机使用的图像文件格式而制定的标准规格。它由日本电子工业发展协会(JEIDA - Japan Electronic Industry Development Association)创建。该规格使用现有的文件格式,如 JPEG,TIFF Rev. 6.0,和 RIFF WAVE 音频文件格式,和一些额外添加的特殊元数据标签。它不支持 JPEG 2000 或 PNG。

该规格的 V2.1 版本于 1998 年 1 月制定,V2.2 版本于 2002 年 4 月制定。
在 Exif 标准中定义的元数据标签包括以下几大方面的信息:
日期和时间信息。数码相机将记录当前日期和时间,并把这些信息记录在元数据标签里。
相机设置。这包括静态信息,如相机型号、生产厂商,及每张照片改变的信息(方位、光圈、快门速度、焦距、测光模式和ISO感光速度等信息)。
照片拍摄地的位置信息。可以由 GPS(全球卫星定位系统)接收器连接到数码相机上,来提供相关全球定位信息。2004 年,仅有极少数数码相机支持这个特性。因此,有人使用普通的GPS接受器来记录他当时所在位置的地理信息,然后在图像的时间戳里,根据接受器日志记录的内容,为图像添加相机错失了的照片拍摄地地理信息。
描述和版权信息。一些数码相机高端机型会在相机上提供允许用户编写这部分信息的功能。
范例
下面列出几项在 Exif 里保存的信息(由 Opanda IExif 提供):
项目 信息
制造厂商 = Canon
相机型号 = Canon EOS-1D Mark II
影像方向 = 正常(upper-left)
影像分辨率 X = 72
影像分辨率 Y = 72
分辨率单位 = dpi
处理软件 = Adobe Photoshop CS Macintosh
最后异动时间 = 2005:10:06 12:53:19
YCbCrPositioning = 2

曝光时间 = 0.00800 (1/125) sec
光圈值 = F1.6
拍摄模式 = 光圈优先
ISO 感光值 = 100
Exif 信息版本 = 30,32,32,31
影像拍摄时间 = 2005:09:25 15:00:18
影像存入时间 = 2005:09:25 15:00:18
曝光补偿(EV+-) = 0
测光模式 = 点测光 (Spot)
闪光灯 = 关闭
镜头实体焦长 = 85 mm
Flashpix 版本 = 30,31,30,30
影像色域空间 = sRGB
影像尺寸 X = 800 pixel
影像尺寸 Y = 533 pixel
 
你找的这个文档还是笼统,网上也有部分源码的,我刚刚搜了下,不难找的。
 
后退
顶部