当用Timage打开一个较大的JPG文件时(6,7MB)速度非常非常慢,咋样读它的略缩图出来?我在网上找了点资料,只找见读PHOTOSHOP4.0以上版本的JPG文件略缩图,是不是如果不是PHOTOSHOP的JPG文件,我试过就读不出略缩图了,BMP文件咋读略缩图?像windows略缩图是咋做的?我见它读大JPG文件时也非常快。谁能给我代码???请高手帮一下忙吧。万分感谢!!!!

解决方案 »

  1.   

    无论如何你需要了解文件格式。有的图象格式内部本身就含有缩略图,比如JPEG。而大部分图象格式是不含缩略图的,因此需要了解文件格式。比如,对于BMP文件,根据固定格式可以得到图象的尺寸、色彩数等关键数据,然后需要你制定预期的缩略图尺寸等关键数据,最后通过采样得到缩略图。比较典型的如AcdSee。如果试图利用TImage的Stretch属性来实现缩略图,在效率上与完全打开图片没什么区别。以前在DOS环境中用Trubo Pascal做过这样的东东,现在只记得思路,源代码早已消失。
      

  2.   

    直接用image的stretch,如果是bmp的话,可以直接用api函数stretchblt都可以达到你的要求。
    The StretchBlt function copies a bitmap from a source rectangle into a destination rectangle, stretching or compressing the bitmap to fit the dimensions of the destination rectangle, if necessary. The system stretches or compresses the bitmap according to the stretching mode currently set in the destination device context. BOOL StretchBlt(
      HDC hdcDest,      // handle to destination DC
      int nXOriginDest, // x-coord of destination upper-left corner
      int nYOriginDest, // y-coord of destination upper-left corner
      int nWidthDest,   // width of destination rectangle
      int nHeightDest,  // height of destination rectangle
      HDC hdcSrc,       // handle to source DC
      int nXOriginSrc,  // x-coord of source upper-left corner
      int nYOriginSrc,  // y-coord of source upper-left corner
      int nWidthSrc,    // width of source rectangle
      int nHeightSrc,   // height of source rectangle
      DWORD dwRop       // raster operation code
    );
      

  3.   

    to 搂主
    当用Timage打开一个较大的JPG文件时(6,7MB)速度非常非常慢
    这个慢是从硬盘读到内存慢呢?还是用TIMAGE控件处理这个jpg慢。。
    可不可以用TJPEGIMAGE读入图像,经过处理(放缩之类的)再到timage中
    显示?
      

  4.   

    用Delphi读取JPEG文件的缩览图    
      用Delphi读取JPEG文件的缩览图 
    --------------------------------------------------------------------------------  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[i])^=$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文件的缩览图。 
     
       
      

  5.   

    to ghostmirror(mirror) ( )读到内存里慢,楼上的上面的我有了,如果不是PHOTOSHOP的JPG文件就慢得很了,比如说数码相机拍下的JPG照片就非常大.Timage读它非常非常慢.who can help me?????
      

  6.   

    绝对不赞成把jpg读到TImage中,TImage中的操作很慢,超慢。
    JPeg.LoadFromFile('adfa.jpg');//jpg从文件读的话照计应该不是很慢。把它画到canvas上去、实现缩放功能可以用下面代码(f为你放大的倍数):
     var
           rct: TRect;
            f: real;
            rct.Left := 0 ;
            rct.Top := 0;
            rct.Right := rct.Left + trunc(jpg.Width * f);
            rct.Bottom := rct.Top +  trunc(jpg.height * f);
           Canvas.StretchDraw(rct, jpg);
    不过你要在你Canvas所在的窗口的窗口过程中相应WM_PAINT消息。应该会吧?
      

  7.   

    TOpenPictureDlg读Jpg文件的速度比TImage要快,可还是比不上ACDSee...我来试试流文件,估计也很慢,下午见 :)
      

  8.   

    不行呀,用流还是很慢... :(这还是数码相机,搞广告喷绘的一张Jpg动辄几百兆,用TImage的话,估计一天打开几个文件就要下班了。这是ACDSee预览一张631K的Jpg文件的全部过程,用FileMon捕获的: FindOpen C:\CODETEST\JPG.JPG SUCCESS Jpg.jpg
    FindClose C:\CODETEST\JPG.JPG SUCCESS
    Attributes C:\CODETEST\JPG.JPG SUCCESS GetAttributes
    Open C:\CODETEST\JPG.JPG SUCCESS OPENEXISTING READONLY DENYNONE
    Read C:\CODETEST\JPG.JPG SUCCESS Offset: 0 Length: 4095 
    Close C:\CODETEST\JPG.JPG SUCCESS CLOSE_FINAL
    Attributes C:\CODETEST\JPG.JPG SUCCESS GetAttributes
    Open C:\CODETEST\JPG.JPG SUCCESS OPENEXISTING READONLY DENYNONE 
    Read C:\CODETEST\JPG.JPG SUCCESS Offset: 0 Length: 4095 
    //先读了4096个字节,不知道是不是采样
    Close C:\CODETEST\JPG.JPG SUCCESS CLOSE_FINAL
    Open C:\CODETEST\JPG.JPG SUCCESS OPENEXISTING READONLY DENYNONE 
    Read C:\CODETEST\JPG.JPG SUCCESS Offset: 0 Length: 1024 
    //又读了1024字节,不知道干什么 
    Seek C:\CODETEST\JPG.JPG SUCCESS Beginning Offset: 0 / New offset: 0
    Read C:\CODETEST\JPG.JPG SUCCESS Offset: 0 Length: 4096 
    //开始循环,每次4K(4096)
    Read C:\CODETEST\JPG.JPG SUCCESS Offset: 4096 Length: 4096
    Read C:\CODETEST\JPG.JPG SUCCESS Offset: 8192 Length: 4096
    Read C:\CODETEST\JPG.JPG SUCCESS Offset: 12288 Length: 4096
    Read C:\CODETEST\JPG.JPG SUCCESS Offset: 16384 Length: 4096
    Read C:\CODETEST\JPG.JPG SUCCESS Offset: 20480 Length: 4096
    Read C:\CODETEST\JPG.JPG SUCCESS Offset: 24576 Length: 4096
    ............ //省略大量的读文件过程 
    Read C:\CODETEST\JPG.JPG SUCCESS Offset: 630784 Length: 4096
    Read C:\CODETEST\JPG.JPG SUCCESS Offset: 634880 Length: 4096
    Read C:\CODETEST\JPG.JPG SUCCESS Offset: 638976 Length: 4096
    Read C:\CODETEST\JPG.JPG SUCCESS Offset: 643072 Length: 4096
    //读完了,631K
    Close C:\CODETEST\JPG.JPG SUCCESS CLOSE_FINAL而不论是TImage还是流读取然后画,都是这样的:FindOpen C:\CODETEST\JPG.JPG SUCCESS Jpg.jpg
    FindClose C:\CODETEST\JPG.JPG SUCCESS
    Open C:\CODETEST\JPG.JPG SUCCESS OPENEXISTING READONLY DENYWRITE 
    Seek C:\CODETEST\JPG.JPG SUCCESS Beginning Offset: 0 / New offset: 0
    Seek C:\CODETEST\JPG.JPG SUCCESS End Offset: 0 / New offset: 0
    Seek C:\CODETEST\JPG.JPG SUCCESS Beginning Offset: 0 / New offset: 0
    Seek C:\CODETEST\JPG.JPG SUCCESS Beginning Offset: 0 / New offset: 0
    Read C:\CODETEST\JPG.JPG SUCCESS Offset: 0 Length: 645222 
    //一次全部读取631K
    Close C:\CODETEST\JPG.JPG SUCCESS CLOSE_FINAL很可能ACDSee从每次读取的4K数据中,取一小部分显示出来形成缩略图。所以,速度瓶颈不是在于从硬盘读到内存的速度,而是在于图片被显示出来的速度。点阵图,图片越大,需要处理的点越多。 具体如何实现,我来试试吧。以前也碰到过类似的问题,当时想想等一等不也就显示出来了,这回来搞定它。
      

  9.   

    哪位兄弟有Jpeg文件格式的资料。我发现Photoshop, Photoimpact和ACDSee生成的Jpeg文件的格式都不相同。估计工作量相当于再写一个ACDSee,豪杰大眼睛不是吗? :(