数据库中的图像

问题描述 投票:0回答:2

我的程序管理“项目”(将它们想象成庄严的家)并与每个项目关联零个、一个或多个图像。到目前为止,这些都在数据库之外。数据库中的项目通过文件名和路径指向图像。图像保存在专用文件夹树中。现在需要将图像移动到数据库本身。 需要处理的图像类型有: jpeg(最常见,有时大到 4 Mb) bmp(也很常见,而且很大) PNG 电动势 wmf gif(仅静态,罕见,但确实会出现)。

目前,当一个文件与一个项目相关联时,除了在图像数据库表中创建一个条目之外,没有对图像做任何事情。当用户查看项目时,将使用 ShellBrowser 显示图像缩略图以访问文件并生成显示在屏幕上的 96 x 96 缩略图位图。

我的计划是将图像和缩略图作为每个记录的两个新 BLOB 字段存储在图像表中,全图和缩略图,都是位图。

这是我第一次涉足数据库中的图像,所以请耐心等待我加快速度。

问题一:下面的代码段是否将上述6种文件类型转换为完整的图像位图?好像是这样的

uses 
  Graphics, Jpeg, pngimage, GIFImg; 

procedure TForm1.Button1Click (Sender: TObject); 
var 
  Picture: TPicture; 
  Bitmap: TBitmap; 
begin 
  Picture := TPicture.Create; 
  try 
    Picture.LoadFromFile('C:\imagedata.dat'); 
    Bitmap := TBitmap.Create; 
    try 
      Bitmap.Width := Picture.Width; 
      Bitmap.Height := Picture.Height; 
      Bitmap.Canvas.Draw(0, 0, Picture.Graphic); 
      Bitmap.SaveToFile('C:\test.bmp'); 
    finally 
      Bitmap.Free; 
    end; 
  finally 
    Picture.Free; 
  end; 
end; 

问题 2:如何使用 TStream 或 TMemoryStream 将位图移动到 Blob 字段中?优势和问题的对比。代码将位图移动到流以及从流到 BLOB ??

问题三:我的感觉是,将原始文件存储在Blob字段中,占用空间小,但更难在屏幕上呈现。有什么想法吗?

image delphi bitmapimage blobstorage
2个回答
0
投票
  1. TPicture.LoadFromFile()
    使用文件扩展名来知道使用哪个
    TGraphic
    类来加载数据。除非您创建了自定义类,否则标准类都不会使用
    .dat
    .

  2. 使用

    TDataSet.CreateBlobStream()
    TGraphic.SaveToStream()
    /
    LoadFromStream()
    。不过,我不会强行将所有图像转换为 BMP 进行存储。那会使数据库膨胀。 JPG 和 PNG 更加紧凑。

  3. 存储在blob中的图像可以显示在

    TDBImage
    中。或者,您可以简单地自己加载图像,然后将其分配给
    TImage
    .


0
投票

既然我现在已经设法回答了我原来的问题,我觉得发布我最终的“研究”代码是合适的,以防将来它可能对其他人有用。

需要说的是,已经决定将图像保存在数据库之外以避免膨胀,但将缩略图保存在数据库中。

uses Vcl.imaging.pngimage, Vcl.imaging.GIFImg, Vcl.imaging.jpeg;
    
procedure TImagesInABLOB.LoadImageButtonClick (Sender: TObject);
var
  Name_And_Path_File_Selected:  string;
  File_Extension:   string;
  Local_ShellBrowser:   TShellBrowser;
  Thumbnail_Bitmap:     TBitmap;
  Thumbnail_Stream:     TMemoryStream;
  ADO_Stream: TADOBlobStream;
    
  mRect: TRect;
  nRect: TRect;
label
  Load_Thumbnail_Into_DB;
begin
// Using ShellBrowser, create a 96 x 96 pixel thumbnail image as a bitmap.
// ShellBrowser returns nil when the image type is .emf or .wmf.
// The bitmap created is upside down and must be rotated 180 degrees.
  Local_ShellBrowser := TShellBrowser.Create(Self);
  try
    Local_ShellBrowser.FullPath := Name_And_Path_File_Selected;
    Thumbnail_Bitmap := Local_ShellBrowser.GetThumbnailBitmap (96, 96, False);
  finally
    Local_ShellBrowser.Free;
  end;
    
  if (Thumbnail_Bitmap <> nil) then
    begin                                          // Turn bitmap upside down.
      mRect := rect (0, 0, Thumbnail_Bitmap.Width, Thumbnail_Bitmap.Height);
      nRect := rect (0, Thumbnail_Bitmap.Height - 1, Thumbnail_Bitmap.Width, -1);   
      Thumbnail_Bitmap.Canvas.CopyRect(mRect, Thumbnail_Bitmap.Canvas, nRect);      
      goto Load_Thumbnail_Into_DB;
    end;
// If the image file extension is .emf or .wmf, call an appropriate routine to
// to create a thumbnail bitmap from the metafile.
  File_Extension := LowerCase(ExtractFileExt(Name_And_Path_File_Selected));
  if ((Thumbnail_Bitmap = nil) and (File_Extension = '.emf')) then
    begin
      Get_EMF_Thumbnail (Name_And_Path_File_Selected, 96, 96, Thumbnail_Bitmap);
      if (Thumbnail_Bitmap = nil) then
        JFMessageDlg ('Thumbnail could not be created from the .emf file.', mtError, [mbOK], [Txt_Btn_Caption_OK]);
  goto Load_Thumbnail_Into_DB;
    end;
    
  if ((Thumbnail_Bitmap = nil) and (File_Extension = '.wmf')) then
    begin
      Get_WMF_Thumbnail (Name_And_Path_File_Selected, 96, 96, Thumbnail_Bitmap);
      if (Thumbnail_Bitmap = nil) then
        JFMessageDlg ('Thumbnail could not be created from the .wmf file.', mtError, [mbOK], [Txt_Btn_Caption_OK]);
    end;
// If Thumbnail_Bitmap exists, load the thumbnail bitmap into the current record
// record of the Oracle table and release the thumbnail bitmap.

Load_Thumbnail_Into_DB:
  if (Thumbnail_Bitmap <> nil) then
    begin
      if ((QryImages_In_BLOB.State <> dsEdit) and (QryImages_In_BLOB.State <> dsInsert)) then
        QryImages_In_BLOB.Edit;
        ADO_Stream := TADOBlobStream.Create(QryImages_In_BLOBTHUMBNAIL_IMAGE, bmWrite);
      try
        Thumbnail_Bitmap.SaveToStream(ADO_Stream);
      finally
        ADO_Stream.Free;
      end;
    
      Thumbnail_Bitmap.Free;
    end;
// Post any change made to the current record.
  if ((QryImages_In_BLOB.State = dsEdit) or (QryImages_In_BLOB.State = dsInsert)) then
    QryImages_In_BLOB.Post;
end;
{--------------------------------------------------------------------------------}
procedure TImagesInABLOB.Get_EMF_Thumbnail (const Path: Unicodestring; Width: 
                               Integer; Height: Integer; out   Bitmap: TBitmap);
var
  APicture: TPicture;
begin
  if (LowerCase(ExtractFileExt(Path)) = '.emf') then
    begin
      APicture := TPicture.Create;
      try
        APicture.LoadFromFile(Path);
        Bitmap := TBitmap.Create;       // Must be freed by the caller.
        Bitmap.PixelFormat := pf24bit;
        Bitmap.Width  := Width;
        Bitmap.Height := Height;
        Bitmap.Canvas.Lock;   // Important in multithreaded applications,
                              // see http://qc.embarcadero.com/wc/qcmain.aspx?d=55871
        Bitmap.Canvas.StretchDraw(Rect(0, 0, Width, Height), APicture.Graphic);
        Bitmap.Canvas.Unlock;
      finally
        APicture.Free;
      end;
    end;
end;
{------------------------------------------------------------------------}
procedure TImagesInABLOB.Get_WMF_Thumbnail (const Path:   Unicodestring; Width: 
                               Integer; Height: Integer; out   Bitmap: TBitmap);
var
  APicture: TPicture;
begin
  if (LowerCase(ExtractFileExt(Path)) = '.wmf') then
    begin
      APicture := TPicture.Create;
      try
        APicture.LoadFromFile(Path);
        Bitmap := TBitmap.Create;       // Must be freed by the caller.
        Bitmap.PixelFormat := pf24bit;
        Bitmap.Width  := Width;
        Bitmap.Height := Height;
        Bitmap.Canvas.Lock;   // Important in multithreaded applications,
                              // see http://qc.embarcadero.com/wc/qcmain.aspx?d=55871
        Bitmap.Canvas.StretchDraw(Rect(0, 0, Width, Height), APicture.Graphic);
        Bitmap.Canvas.Unlock;
      finally
        APicture.Free;
      end;
    end;
end;
© www.soinside.com 2019 - 2024. All rights reserved.