如何获取照片缩略图? ( 积分: 50 )

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

Gingerzy

Unregistered / Unconfirmed
GUEST, unregistred user!
大部分图片里面有一块存储缩略图的信息,可以读出。但也有一些图片的这部分信息遭到破坏,所以无法直接读取缩略图信息,我的办法是将图片按比例压缩,但遇到大图片时速度很慢,有没有好的办法解决这个问题?谢谢!!
 
看到过一段CB写的,不复杂吧。建议先看看http://www.exif.org/specifications.html了解一下exif的存储结构

Get EXIF data from a JPG
EXIF data is stored in the JPGs created by most digital cameras. It contains information about the camera, the environment when the image was taken, the date, time, etc..

UINT32 w,h,d;

// get the dimensions - we'll we really don't care about the dims.
// we just want to force a JPG marker read and this is the quickest way
// to do it.
HISSRC hSrc = ISOpenFileSource( pFilename );
ISGetJPGDims( hSrc, &w, &h, &d, NULL);
ISCloseSource( hSrc );

// loop over all JPEG_APPx markers
int ct=ISGetJPGInputMarkerCount();

for (int i=0; i < ct; i++)
{
// get a JPG marker from ImgSoruce
HGLOBAL hData = NULL;
UINT32 len, type;
ISGetJPGInputMarker(i, &amp;hData, &amp;len, &amp;type);

// only interested in JPEG_APP1 (#225)
if (type!=225)
{
GlobalFree(hData);
continue;
}
else
{
// start the EXIF parser
HGLOBAL hEXIF = ISEXIFInit((BYTE *)hData, len);

if (hEXIF!=NULL)
{
// get string with tag ID #271 (camera model)
// look in all subsections (1 | 2 | 4 | 8 = 15)
HGLOBAL hStr = NULL;
UINT32 uStrLen;
ISEXIFGetString(hEXIF, 272, 15, &amp;hStr, &amp;uStrLen);
if (hStr!=NULL)
{
// got it!
TRACE(&quot;model = %s/n&quot;, (char *)hStr);
GlobalFree(hStr);
}

// try the thumbnail
HGLOBAL hThumbnail = NULL;
UINT32 uTNLen = 0;
if (ISEXIFGetThumbnail(hEXIF, &amp;hThumbnail, &amp;uTNLen)==IS_ERR_OK)
{
// there is a thumbnail.

// what format is it?
int iFmt = 0;
HGLOBAL hStr = NULL;
UINT32 uStrLen;
ISEXIFGetString(hEXIF, 259, 8, &amp;hStr, &amp;uStrLen);
if (hStr!=NULL)
{
// got it!
TRACE(&quot;fmt = %s/n&quot;, (char *)hStr);
iFmt = atoi((char *)hStr);
GlobalFree(hStr);
}

if (iFmt==6) // 6 = JPG. 1 = TIFF, 0 = RGB, but most are JPG
{
// convet that to RGB
HISSRC hSrc = ISOpenMemorySource((BYTE *)hThumbnail, uTNLen);
HGLOBAL hImg = ISReadJPG(hSrc, &amp;w, &amp;h, 24);
ISCloseSource(hSrc);

if (hImg)
{
// draw it
CDC *pDC = GetDC();
ISDrawRGB( pDC->m_hDC, (BYTE *)hImg, w, h, 0, 0, w, h, NULL );
ReleaseDC(pDC);

GlobalFree(hImg);
}
}

// clean up
GlobalFree(hThumbnail);
}

// clean up
ISEXIFDestroy(hEXIF);
}
}

GlobalFree(hData);
}
 
以下是百度出来的....
http://www.window07.com/dev/code/delphi/devs/2006-2-23/k9470.htm
作者:姜亮
用Delphi实现缩略图查看本来想投个杂志什么的,现在想来也没那个必要了。 用Delphi实现缩略图查看
===========>>原文较长,打开链接直接看吧
 
又搜了一个:
用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)^=$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文件的缩览图。
 
盒子上有个例子,很不错,去下载吧:http://www.2ccc.com/article.asp?articleid=3831
 
大部分图片里面有一块存储缩略图的信息,

晕!你听谁说的?
 
好轻浮的回答,上面的没有一句是对的。人家说的就是没有exif中的索略图信息,更何况,你怎么知道一定是jpg图片?
我觉得,没有exif信息的时候的时候,可以考虑采用抽线等的方式。
 
多人接受答案了。
 
后退
顶部