我想生成一副JPG图象的缩略图,怎么做?(50分)

  • 主题发起人 主题发起人 星期一
  • 开始时间 开始时间

星期一

Unregistered / Unconfirmed
GUEST, unregistred user!
生成大图象的缩略图,怎么写?
 
这缩略图要显示在哪里?
 
保存成文件
 
 JPEG图像文件以高压缩比和高图像质量著称,市面上的图库光盘中的图像文件大都是JPEG格式的。怎样从一大堆JPEG文件中查找合适的图像呢?使用JPEG文件的缩览图就是其中方法之一。

  在PhotoShop 4.0(或以上版本)的打开文件对话框中,当打开JPEG文件时,PhotoShop很快把它的缩览图显示出来。为什么PhotoShop能这么快地显示出JPEG文件的缩览图呢?

  原来PhotoShop在保存JPEG文件时把它的缩览图也保存在文件里。PhotoShop定义了新的段FF ED,这个段保存了一个JPEG文件格式的缩览图,大图中有小图。FF ED段后两个字节是这个段的长度,在这个段里有缩览图的开始标志FF D8和结束标志FF D9,将这个段拷贝出来即可获得该图的缩览图。值得注意的是PhotoShop 4.0解出的缩览图,像素格式不是常规的RGB,而是BGR格式,所以还得加入BGR转为RGB的代码,转化过程是在内存里把B和R的位置交换。

  下面是Delphi编写的快速读取PhotoShop 4.0(或以上版本)JPEG文件的缩览图的程序,程序用TFileStream读取JPEG文件的FF ED段,结合TmemoryStream、TJPEGimage, 返回BMP格式的缩览图。

  function LoadThumb(filename:shortstring):TBitmap;

  procedure BGR2RGB(var bmp:TBitmap);

  var

  x,y:integer; t:char; data:pchar;

  begin

  for y:=bmp.Height-1 downto 0 do

  begin

  data:=bmp.ScanLine[y];

  for x:=0 to bmp.Width-1 do

  begin

  t:=data[x*3];

  data[x*3]:=data[x*3+2];

  data[x*3+2]:=t;

  end;

  end;

  end;

  var

  fstream:Tfilestream; mstream:Tmemorystream;

  j,i:word;data:pchar; buf:array [0..3] of byte;

  filesize:DWORD; fjpg:Tjpegimage;bmp:Tbitmap;

  begin

  result:=nil;

  fstream:=Tfilestream.create(filename,fmOpenRead);

  //建立文件流,读JPEG文件

  fstream.Seek(20,soFromBeginning); //FF ED段在文件的第20个字节处

  fstream.Read(buf,sizeof(buf));

  if PWORD(@buf[0])^=$EDFF then

  begin

  j:=buf[2]*256+buf[3]; //FF ED的大小,高位在前,低位在后

  if j<1024 then //FF ED段的大小若为1024个字节则文件不包含缩览图,退出程序

  begin

  fstream.free;

  exit;

  end;

  mstream:=TMemorystream.Create;//建立内存流

  mstream.CopyFrom(fstream,j); //把FF ED段拷贝到mstream

  data:=mstream.Memory;

  for i:=300 to 700 do //找缩览图的开始标志FF D8

  if PWORD(@data)^=$D8FF then break;

  if i<700 then

  begin

  fjpg:=Tjpegimage.Create; //建立TJPEGimage 解出缩览图

  bmp:=TBitmap.Create;

  mstream.Position:=i;

  fjpg.LoadFromStream(mstream);//fjpg读取mstream

  bmp.Assign(fjpg); //JPEG转BMP

  if PWORD(@data[i+57])^=$2e34 then //PhotoShop 4.0的缩览图

  BGR2RGB(bmp); //BMP的像素格式BGR 而不是RGB,要把BGR转化为RGB

  result:=bmp; //函数返回BMP

  mstream.Free;

  fjpg.Free; //释放Object

  end;end;

  fstream.free;

  end;

  可直接把Delphi 的Timage可视控件拖到Form上,用image.picture.bitmap:= LoadThumb(filename) 即可显示PhotoShop JPEG文件的缩览图。
 
问题是我是不仅要生成PHOTOSHOP的文件的缩略图,还有其他格式的,象BMP,GIF,JPG等
 
用个GraphicX控件(可能个别单词拼写有误),一切搞定!
 
是GraphicEx v.8.7 (10.06.2001) - 915 Kb

支持一下所有格式:
TIFF (*.tif; *.tiff) [uncompressed, LZW compressed]
GFI fax (*.fax),
SGI (*.bw, *.rgb, *.rgba, *.sgi)
Autodesk CEL (*.cel, *.pic)
Truevision (*.tga; *.vst; *.icb; *.vda; *.win)
ZSoft Paintbrush (*.pcx, *.pcc)
Word 5.x screen capture files (*.scr)
Kodak Photo-CD (*.pcd)
Portable pixel/gray map (*.ppm, *.pgm, *.pbm)
Dr. Halo (*.cut, *.pal)
CompuServe (*.gif)
SGI Wavefront (*.rla, *.rpf)
Standard Windows (*.bmp, *.rle, *.dib)
Photoshop (*.psd, *.pdd)
Paintshop Pro (*.psp)
Portable network graphic (*.png)
 
哪下载?
 
http://cakk.126.com
 
那个控件是不错,可是怎么搞定。我对图象编程不了解。我的想法是用一个image控件读入
一副图(strech设为TRUE),根据长、宽比例调整大小。这时image显示的缩小后的图象保
存就行了,问题是,怎么取到image的图象。

 
试试下面这些: 可用

Thumbnail Browser Example by Boern Ischo
A very simple example on how to create a thumbnail image browser.
There's a lot of stuff to do to use this for a serious program, but
I thought beginners might be interested in this. You're welcome to
send my any questions or comments on this to bjoern@ischo.de

Public Domain. Feel free to use this code in any way you like.



unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, FileCtrl, StdCtrls,jpeg;

type
TForm1 = class(TForm)
DriveComboBox1: TDriveComboBox;
DirectoryListBox1: TDirectoryListBox;
ScrollBox1: TScrollBox;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure DirectoryListBox1Change(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

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;

var
Form1: TForm1;

implementation

{$R *.DFM}

var buffer_jpeg:tjpegimage;

//a simple class for thumbnails...

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;

//*<----------------------------------------------------


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;

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

begin
foundlist:=tstringlist.create;

try

//look for jpg files
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;

//create the thumbnails
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;

end.
 
uses clipbrd,jpeg;

procedure TForm1.Button1Click(Sender: TObject);
var bitmap,map:tbitmap;
arect,brect:trect;
w,h,tw,th,tem:integer;
s:string;
begin
w:=32; //缩略图宽
h:=32; //缩略图高
Bitmap := TBitmap.Create;
map := TBitmap.Create;
s:=('D:/Documents and Settings/Administrator/My Documents/My Pictures/wen1.jpg');
image1.picture.LoadFromFile(s);
tw:=image1.Picture.Width;
th:=image1.Picture.height;
Clipboard.Assign(Image1.Picture);
map.LoadFromClipBoardFormat(cf_BitMap,ClipBoard.GetAsHandle(cf_Bitmap),0);
bitmap.Width :=w;
bitmap.height:=h;
bitmap.Canvas.Rectangle(brect);
if(tw<w)and(th<h) then
bitmap.canvas.Draw(w div 2-tw div 2,h div 2-th div 2,map)
else
begin
if tw>th then
begin
arect.left:=0;
arect.Right:=w;
tem:=round(w*(th/tw));
arect.top:=(h-tem) div 2;
arect.bottom:=arect.top+tem;
end
else
begin
arect.top:=0;
tem:=round(h*(tw/th));
arect.Left :=w div 2- tem div 2;
arect.Right:=arect.left+tem;
arect.bottom:=h;
end;
bitmap.Canvas.StretchDraw(arect,map)
end;
image1.Picture.Bitmap := bitmap;
image1.Picture.SaveToFile('c:/1.jpg');

end;
 
不管是什么格式的图片,转成bitmap 画出来(strech设为TRUE),再保存就可以。



 
http://www.playicq.com/dispdoc.asp?id=1086
 
其实, 直接用流设定大小就行了。
 
to lance2000:你指的源代码只是显示缩略图,这我已经没问题了,我的问题是,如何保存……

to sim_might:能不能详细点?
 
procedure SavePicToMiniature(SourceJpg: TJPEGImage; Width, Height: Integer);
//保存JPEG的缩略图
var
jpg: TJPEGImage;
bmp: TBitmap;
begin
bmp := TBitmap.Create;
bmp.Width := Width;
bmp.Height := Height;
bmp.PixelFormat := pf24bit;
bmp.Canvas.StretchDraw(Rect(0,0,Width,Height), SourceJpg);
jpg := TJPEGImage.Create;
jpg.Assign(bmp);
jpg.SaveToFile('C:/temp/minijpg.jpg');
bmp.Free;
jpg.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var AJpg: TJPEGImage;
begin
AJpg := TJPEGImage.Create;
if OpenPictureDialog1.Execute then
begin
AJpg.LoadFromFile(OpenPictureDialog1.FileName);
SavePicToMiniature(AJpg, 320, 240);
Image1.Picture.LoadFromFile('C:/temp/minijpg.jpg');
end;
AJpg.Free;
end;
 
另一个选择:微软结构化存储技术
 
//保存JPEG的缩略图
procedure SavePicToMiniature(SourceFileName,DescFileName: String);
const
MaxWidth = 120 ;//最大宽度
MaxHigth = 120 ;//最大高度
var
jpg: TJPEGImage;
bmp: TBitmap;
SourceJpg: TJPEGImage;
Width, Height,tmpInt: Integer;
begin
try
bmp := TBitmap.Create;
SourceJpg := TJPEGImage.Create;
Jpg:= TJPEGImage.Create;
//读取源文件
SourceJpg.LoadFromFile(SourceFileName);
//计算缩小比例
if SourceJpg.Width >= SourceJpg.Height then
tmpInt := SourceJpg.Width div MaxWidth
else
tmpInt := SourceJpg.Height div MaxHigth ;
Width := SourceJpg.Width div tmpInt ;
Height := SourceJpg.Height div tmpInt ;
//缩小
bmp.Width := Width;
bmp.Height := Height;
bmp.PixelFormat := pf24bit;
bmp.Canvas.StretchDraw(Rect(0,0,Width,Height), SourceJpg);
//保存
jpg.Assign(bmp);
jpg.SaveToFile(DescFileName);
finally
bmp.Free;
jpg.Free;
SourceJpg.Free;
end;
end;
 
后退
顶部