求jpg转换成bmp的算法(100分)

  • 主题发起人 主题发起人 Gingerzy
  • 开始时间 开始时间
G

Gingerzy

Unregistered / Unconfirmed
GUEST, unregistred user!
因为要用Listview显示图片的缩略图,而ImageList只能用bmp格式的,所以需要将jpg文件先转换成bmp,然后再显示,jpg转换成bmp的函数如下,一张3M多的数码照片转换起来明显感觉到有些慢,如果照片多了速度就会非常慢,有没有好一点的办法可以提高速度?谢谢!


jpgFile := TJpgImage.Create;
bmpFile := TBitmap.Create;
try
jpgFile.LoadFromFile(JpgFileName);
bmpFile.Assign(jpgFile);
except

end;
 
试试这种方法:

创建像ACDSee那样的缩略图浏览器,这并不是一件简单的事。以下就是一个很原始的缩略图控件的源代码:

uses jpeg

type
tbi_thumb=class(tcustomcontrol)
fmypic : tjpegimage;
private
procedure getpic(value:tjpegimage);
public
procedure paint; override;
constructor create(aowner:tcomponent); override;
destructor destroy; override;
published
property pic:tjpegimage write getpic;
end;

constructor tbi_thumb.create(aowner:tcomponent);
begin
inherited;
fmypic:=tjpegimage.create;
end;

destructor tbi_thumb.destroy;
begin
inherited;
fmypic.free;
end;

procedure tbi_thumb.getpic(value:tjpegimage);
begin
fmypic.scale:=jshalf;
fmypic.assign(value);
fmypic.dibneeded;
end;

procedure tbi_thumb.paint;
var
arect : trect;
ratio : single;
begin
arect:=clientrect;
canvas.stretchdraw(arect,fmypic);
frame3d(canvas,arect,clblack,clwhite,2);
end;

(这不是一个可视控件。)

下面来实现

新建一个Form,并在其上添加一个Directory List Box和一个Scrollbox,其中Scrollbox的宽度(Width)大约为430个象素。
当用户选定了一个新的目录,我们需要扫描这个目录,为其中每一个JPEG文件创建一个实例。为了加快这一过程的速度,可以将JPEG参数设为jpbestspeed。JPEG文件将被读入一个临时缓冲区,然后被赋值给一个新的缩略图对象的pic属性。

在unit中添加一个新的变量:
var
buffer_jpeg:tjpegimage;

下面的代码用来创建和释放buffer_jpeg变量:

procedure TForm1.FormCreate(Sender: TObject);
begin
buffer_jpeg:=tjpegimage.create;
buffer_jpeg.Performance:=jpbestspeed;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
buffer_jpeg.free;
while scrollbox1.ComponentCount>0 do
scrollbox1.components[0].free;
end;

以下的代码在文件夹中检索JPEG文件并创建缩略图:

procedure TForm1.DirectoryListBox1Change(Sender: TObject);
var
i,x,y : integer;
anewthumb : tbi_thumb;
foundlist : tstringlist;
sr : TSearchRec;

begin
foundlist:=tstringlist.create;

try
//检索JPEG文件
if FindFirst(directorylistbox1.Directory+'/*.jpg', faAnyFile, sr) = 0 then
begin
foundlist.add(sr.name);
while FindNext(sr) = 0 do
foundlist.add(sr.name);
FindClose(sr);
end;

x:=0;
y:=0;

//创建缩略图
for i:=0 to FoundList.count-1 do
begin
anewthumb:=tbi_thumb.create(self);
buffer_jpeg.loadfromfile(foundlist);
with anewthumb do
begin
pic:=buffer_jpeg;
parent:=scrollbox1;
left:=x;
top:=y;
width:=120;
height:=90;
visible:=true;
inc(x,122);
if x>244 then
begin
x:=0;
inc(y,92);
end;
application.processmessages;
end;
end;

finally
foundlist.free;
end;

end;

以上就是一个极简单的缩略图浏览器实现,你可以继续在里面添加需要的功能。
 
都是用楼主的方法。JPEG没有代码
 
1.有些jpg可以直接获取缩略图,如果能获取可以直接显示。
2.但也有一些jpg文件不能直接获取缩略图,所以只好先将jpg文件转换成bmp,然后再将转换后的bmp文件缩小显示出来。

问题出在第2各情况,在将一个3M的jpg文件用原始的方法转换成bmp的过程很慢。所以要找好的办法来提高速度。
 
以前做过,但记不清了,记得和这个属性有关,你看看帮助吧
type TJPEGPixelFormat = (jf24Bit, jf8Bit);
property PixelFormat: TJPEGPixelFormat;
jpeg图片是jp24bit格式的,你转换成jf8bit格式,虽然变得不清楚,但由于你用的是缩略图,效果就好很多,基本上没什么太大的差别
 
建议用GDI+,呵呵!
 
速度慢主要在这句上:bmpFile.Assign(jpgFile);
使用jpgFile.Scale属性先缩小Jpg输出图像大小,可以极大的加快处理速度(=jsEighth 速度只有原来的1/8)

var
jpgFile : TJPEGImage;
bmpFile : TBitmap;
i: Integer;
begin
try
jpgFile := TJpegImage.Create;
bmpFile := TBitmap.Create;
jpgFile.LoadFromFile('L:/100SSCAM/SSL20780.JPG');

i:= GetTickCount;
jpgFile.Scale := jsEighth; //有这句和没有这句,差别太大了
//jpgFile.PixelFormat := jf8Bit;//经测试,加这句只会变得更慢,可能是增加了一个转换工作,(对Bmp图片,降低PixelFormat值,是可以加快图片处理速度的)
bmpFile.Assign(jpgFile);
ShowMessage(IntToStr(GetTickCount-i));

Canvas.Draw(0, 0, bmpFile);
finally
bmpFile.Free;
jpgFile.Free;
end;
end;
 
有没有想过直接操作ImageList啊
先把jpg读到一个image里
 
多人接受答案了。
 

Similar threads

D
回复
0
查看
792
DelphiTeacher的专栏
D
D
回复
0
查看
826
DelphiTeacher的专栏
D
D
回复
0
查看
658
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部