加载图片时报错,请大虾帮忙看看!

加载图片时报错,请大虾帮忙看看! Delphi / Windows SDK/API
http://www.delphi2007.net/DelphiMultimedia/html/delphi_20061103170415180.html
fbmp:TBitMap   ;  
  fbmp.loadfromfile('c:\abc.bmp');  
  执行到这一步时报错,提示读stream时出错。图片abc.bmp是经过photoshop从24位压缩到8位的。  
  如果没有压缩是不会报错的,但压缩后图片还是bmp图片,在Windows下也是可以打开的,就是  
  在Delphi下打不开,直接在Delphi中的控件Timage中也不能加载,请问哪位知道原因!

var  
        fbmp:TBitMap   ;  
  begin  
  fbmp:=     TBitMap.Create;  
  fbmp.loadfromfile('c:\abc.bmp');

fbmp:=   TBitMap.Create;

我的代码中是执行过fbmp:=   TBitMap.Create;的,只是我在这里没写出来,问题不是出在创建图片对象上。请各位指教指教!

看下错误代码。  
  PixelFormat   设置下格式看看

好象不能处理过大的图象,我试过最大处理4MB多,应该是图片太大了。

图片还没超过100K;应该不是图片的大小问题!  
  只有图片被加载后才能设置格式,因为这里加载时就报错了,所以不是PixelFormat!  
  不知哪位能帮我解答......

Delphi自带的TBitmap不能支持这种压缩格式  
  必须使用其它的图像库

直接在Delphi自带的图像控件Timage中加载都报错!

把下面的单元包含在你的程序中试试,需要编译一次。  
   
  unit   GdiplusBitmap;  
   
  interface  
   
  uses  
      Windows,   SysUtils,   ActiveX,   Classes,   Graphics;  
   
  type  
      TGdipBitmap   =   class(TBitmap)  
      public  
          procedure   LoadFromStream(Stream:   TStream);   override;  
          procedure   SaveToFile(const   Filename:   string);   override;  
          procedure   SaveToStream(Stream:   TStream);   override;  
      end;  
   
  implementation  
   
  const  
      gpdll   =   'gdiplus.dll';  
   
  type  
      TStatus   =   Integer;  
   
      PGdiplusStartupInput   =   ^TGdiplusStartupInput;  
      TGdiplusStartupInput   =   packed   record  
          GdiplusVersion:   Integer;  
          DebugEventCallback:   Pointer;  
          SuppressBackgroundThread:   BOOL;  
          SuppressExternalCodecs:   BOOL;  
      end;  
   
      TImageCodecInfo   =   packed   record  
          Clsid:   TGUID;                             //   能识别特定编码解码器的   GUID。  
          FormatID:   TGUID;                       //   识别编码解码器格式的   GUID  
          CodecName:   PWCHAR;                   //   编码解码器名称的字符串  
          DllName:   PWCHAR;                       //   存放编码解码器的   DLL   的路径名字符串  
          FormatDescription:   PWCHAR;   //   描述编码解码器的文件格式的字符串。  
          FilenameExtension:   PWCHAR;   //   编码解码器中使用的文件扩展名的字符串  
          MimeType:   PWCHAR;                     //   编码解码器的多用途网际邮件扩充协议   (MIME)   类型的字符串  
          Flags:   DWORD;                             //   有关编码解码器的其他信息(ImageCodecFlags若干标志的组合)  
          Version:   DWORD;                         //   编码解码器的版本号  
          SigCount:   DWORD;  
          SigSize:   DWORD;  
          SigPattern:   PByte;                   //   表示编码解码器签名的二维字节数组  
          SigMask:   PByte;                         //   用作筛选器的二维字节数组  
      end;  
      PImageCodecInfo   =   ^TImageCodecInfo;  
   
  function   GdiplusStartup(var   token:   DWORD;   const   input:   PGdiplusStartupInput;   output:   Pointer):   TStatus;  
          stdcall;   external   gpdll   name   'GdiplusStartup';  
  procedure   GdiplusShutdown(token:   DWORD);  
          stdcall;   external   gpdll   name   'GdiplusShutdown';  
  function   GdipCreateBitmapFromStream(stream:   ISTREAM;   var   bitmap:   Pointer):   TStatus;  
          stdcall;   external   gpdll   name   'GdipCreateBitmapFromStream';  
  function   GdipCreateBitmapFromHBITMAP(hbm:   HBITMAP;   hpal:   HPALETTE;   var   bitmap:   Pointer):   TStatus;  
          stdcall;   external   gpdll   name   'GdipCreateBitmapFromHBITMAP';  
  function   GdipSaveImageToStream(image:   Pointer;   stream:   ISTREAM;   const   clsidEncoder:   PGUID;   const   encoderParams:   Pointer):   TStatus;  
          stdcall;   external   gpdll   name   'GdipSaveImageToStream';  
  function   GdipDisposeImage(image:   Pointer):   TStatus;  
          stdcall;   external   gpdll   name   'GdipDisposeImage';  
  function   GdipCreateHBITMAPFromBitmap(bitmap:   Pointer;   var   hbmReturn:   HBITMAP;   background:   DWORD):   TStatus;  
          stdcall;   external   gpdll   name   'GdipCreateHBITMAPFromBitmap';  
  function   GdipGetImageEncodersSize(var   numEncoders,   size:   Integer):   TStatus;  
          stdcall;   external   gpdll   name   'GdipGetImageEncodersSize';  
  function   GdipGetImageEncoders(numEncoders,   size:   Integer;   encoders:   PImageCodecInfo):   TStatus;  
          stdcall;   external   gpdll   name   'GdipGetImageEncoders';  
  function   GdipGetImagePixelFormat(image:   Pointer;   var   format:   Integer):   TStatus;  
          stdcall;   external   gpdll   name   'GdipGetImagePixelFormat';  
   
  type  
      TGpBitmap   =   class  
      public  
          Native:   Pointer;  
          constructor   Create(stream:   IStream);   overload;  
          destructor   Destroy;   override;  
          constructor   Create(hbm:   HBITMAP;   hpal:   HPALETTE);   overload;  
          function   GetHBITMAP:   HBITMAP;  
          function   GetPixelFormat:   Integer;  
          procedure   Save(stream:   IStream;   const   clsidEncoder:   TCLSID);  
      end;  
   
  procedure   CheckStatus(Status:   TStatus);  
  begin  
      if   Status   <>   0   then  
          raise   Exception.Create('Gdiplus   Error!');  
  end;  
   
  {   TGpBitmap   }  
   
  constructor   TGpBitmap.Create(stream:   IStream);  
  begin  
      CheckStatus(GdipCreateBitmapFromStream(stream,   Native));  
  end;  
   
  constructor   TGpBitmap.Create(hbm:   HBITMAP;   hpal:   HPALETTE);  
  begin  
      CheckStatus(GdipCreateBitmapFromHBITMAP(hbm,   hpal,   Native));  
  end;  
   
  destructor   TGpBitmap.Destroy;  
  begin  
      GdipDisposeImage(Native);  
  end;  
   
  function   TGpBitmap.GetHBITMAP:   HBITMAP;  
  begin  
      CheckStatus(GdipCreateHBITMAPFromBitmap(Native,   Result,   0));  
  end;  
   
  function   TGpBitmap.GetPixelFormat:   Integer;  
  begin  
      CheckStatus(GdipGetImagePixelFormat(Native,   Result));  
  end;  
   
  procedure   TGpBitmap.Save(stream:   IStream;   const   clsidEncoder:   TCLSID);  
  begin  
        CheckStatus(GdipSaveImageToStream(Native,   stream,   @clsidEncoder,   nil));  
  end;  
   
  var  
      GdiplusStartupInput:   TGdiplusStartupInput;  
      gdipToken:   DWord;  
      ImageFormat:   string   =   '';  
   
  procedure   SetImageFormat(const   Filename:   string);  
  begin  
      ImageFormat   :=   ExtractFileExt(Filename);  
      if   ImageFormat   <>   ''   then  
      begin  
          Delete(ImageFormat,   1,   1);  
          if   CompareText(ImageFormat,   'jpg')   =   0   then  
              ImageFormat   :=   'jpeg'  
          else   if   CompareText(ImageFormat,   'tif')   =   0   then  
              ImageFormat   :=   'tiff';  
      end   else   ImageFormat   :=   'bmp';  
      ImageFormat   :=   'image/'   +   ImageFormat;  
  end;  
   
  function   GetImageEncoderClsid(format:   String;   var   Clsid:   TGUID):   integer;  
  var  
      num,   size,   i:   Integer;  
      ImageCodecInfo:   PImageCodecInfo;  
  type  
      InfoArray   =   array   of   TImageCodecInfo;  
  begin  
      num     :=   0;  
      size   :=   0;  
      Result   :=   -1;  
      GdipGetImageEncodersSize(num,   size);  
      if   (size   =   0)   then   exit;  
      GetMem(ImageCodecInfo,   size);  
      if(ImageCodecInfo   =   nil)   then   exit;  
      try  
          GdipGetImageEncoders(num,   size,   ImageCodecInfo);  
          i   :=   0;  
          while   (i   <   num)   and   (CompareText(InfoArray(ImageCodecInfo)[i].MimeType,   format)   <>   0)   do  
              Inc(i);  
          if   i   <   num   then  
          begin  
              Clsid   :=   InfoArray(ImageCodecInfo)[i].Clsid;  
              Result   :=   i;  
          end;  
      finally  
          FreeMem(ImageCodecInfo,   size);  
      end;  
  end;  
   
  {   TGdipBitmap   }  
   
  procedure   TGdipBitmap.LoadFromStream(Stream:   TStream);  
  var  
      Adaper:   TStreamAdapter;  
      tmp:   TGpBitmap;  
  begin  
      Adaper   :=   TStreamAdapter.Create(Stream,   soReference);  
      tmp   :=   TGpBitmap.Create(Adaper);  
      try  
          Handle   :=   tmp.GetHBITMAP;  
          case   (tmp.GetPixelFormat   shr   8)   and   $ff   of  
              1:   PixelFormat   :=   pf1bit;  
              4:   PixelFormat   :=   pf4bit;  
              8:   PixelFormat   :=   pf8bit;  
              16:   PixelFormat   :=   pf16bit;  
              24:   PixelFormat   :=   pf24bit;  
              32:   PixelFormat   :=   pf32bit;  
              else   PixelFormat   :=   pfCustom;  
          end;  
      finally  
          tmp.Free;  
      end;  
  end;  
   
  procedure   TGdipBitmap.SaveToFile(const   Filename:   string);  
  begin  
      SetImageFormat(Filename);  
      inherited   SaveToFile(Filename);  
      ImageFormat   :=   '';  
  end;  
   
  procedure   TGdipBitmap.SaveToStream(Stream:   TStream);  
  var  
      tmp:   TGpBitmap;  
      Adaper:   TStreamAdapter;  
      Clsid:   TGUID;  
  begin  
      if   (ImageFormat   <>   '')   and   (GetImageEncoderClsid(ImageFormat,   Clsid)   <>   -1)   then  
      begin  
          tmp   :=   TGpBitmap.Create(Handle,   Palette);  
          try  
              Adaper   :=   TStreamAdapter.Create(Stream,   soReference);  
              tmp.Save(Adaper,   Clsid);  
          finally  
              tmp.Free;  
          end;  
      end   else  
          inherited   SaveToStream(Stream);  
  end;  
   
  initialization  
  begin  
      FillChar(GdiplusStartupInput,   Sizeof(GdiplusStartupInput),   0);  
      GdiplusStartupInput.GdiplusVersion   :=   1;  
      GdiplusStartup(gdipToken,   @GdiplusStartupInput,   nil);  
      TPicture.RegisterFileFormat('bmp',   'BMP   File',   TGdipBitmap);  
      TPicture.RegisterFileFormat('Exif',   'TIFF   File',   TGdipBitmap);  
      TPicture.RegisterFileFormat('tiff',   'TIFF   File',   TGdipBitmap);  
      TPicture.RegisterFileFormat('tif',   'TIFF   File',   TGdipBitmap);  
      TPicture.RegisterFileFormat('png',   'PNG   File',   TGdipBitmap);  
      TPicture.RegisterFileFormat('gif',   'GIF   File',   TGdipBitmap);  
      TPicture.RegisterFileFormat('jpeg',   'JPEG   File',   TGdipBitmap);  
      TPicture.RegisterFileFormat('jpg',   'JPG   File',   TGdipBitmap);  
  end;  
  finalization  
  begin  
      TPicture.UnregisterGraphicClass(TGdipBitmap);  
      GdiplusShutdown(gdipToken);  
  end;  
   
  end.

包含上面单元,编译一次,可直接从TImage载入,如果使用TBitmap,可以用以下代码:  
  var  
      fbmp:TBitMap   ;  
      tmp:   TGdipBitmap;  
  begin  
      tmp   :=   TGdipBitmap.Create;  
      tmp.LoadFromFile('c:\abc.bmp');  
      fbmp.Assign(tmp);  
      tmp.Free;  
  end;  
   
 

路过

var  
      fbmp:TBitMap   ;  
      tmp:   TGdipBitmap;  
  begin  
      tmp   :=   TGdipBitmap.Create;  
      tmp.LoadFromFile('c:\abc.bmp');  
      fbmp   :=   TBitmap.Create;  
      fbmp.Assign(tmp);  
      tmp.Free;  
  end

TO:maozefa(阿发伯)    
  程序中加了以上代码后无法运行!

程序中加了以上代码后无法运行!  
  ==================================================  
  你用的什么操作系统?

我重新试了一下,上面代码在XP,2000下绝对没有问题的。你的图像能否装进来是另一会事,但是应该不可能无法运行。除非你的操作系统是98。

如果你的操作系统是98,可以下载Gdiplus.DLL到你的系统或者你的程序目录

我的电脑系统是Win2000个人版的,运行之前我也搜索了一下Gdiplus.DLL,系统中可以找到Gdiplus.DLL的,加了GdiplusBitmap之后,可以编译,但不能运行。

有一个gdi+包   你下载一下把pas文件加到你的项目里,,在网上可以找到

To:hongqi162(失踪的月亮)  
  能不能给个具体的名字!

怎么没人回答。

自带的image不支持这种压缩格式吧。

delphi中就是这样,有时候bmp的在window中能打开,但是在delphi中就不能加载,也可能是你那个本本就不是bmp的,但是后缀是bmp的,这样的文件在window中是能打开的,但是delphi会检测是不是真的bmp文件,如果不是就报错了.....

^

GDI+包下载:  
  http://www.2ccc.com/article.asp?articleid=3131  
  GDI+已经支持非常的图形格式,图像处理增强,更易用。。。

posted on 2008-11-05 09:32  delphi2007  阅读(337)  评论(0编辑  收藏  举报