【问题标题】:Check image size before storing it in delphi在将图像存储到delphi之前检查图像大小
【发布时间】:2018-04-13 03:39:10
【问题描述】:

如何在将图像存储到数据库之前检查图像大小。我需要在用户上传图片之前检查图片大小,以避免无法写入数据库的错误。

下面是我如何在我的数据库中插入图像的片段,它工作正常,除了大于我将其存储在数据库中的字段大小的图像。

数据库中的image字段为LONGVARBINARY484 Physical Length

              dtm.cds.Insert;
              Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);
              Image1.Visible := false;
              Field := TBlobField(dtm.cds.FieldByName('PICTURE'));
              Stream := dtm.cds.CreateBlobStream(field, bmwrite);

              JpegImage := TJPEGImage.Create;
              try
                     JpegImage.Assign(Image1.Picture);
                     JpegImage.SaveToStream(Stream);
              finally
                     Stream.Free;
                     dtm.cds.Post;
                     dtm.cds.ApplyUpdates(-1);
              end;

【问题讨论】:

  • 484 字节 (!) 长图像要么非常小,要么很难看,要么无法存储。除了更改架构以允许存储无限量的数据之外,别无所求。
  • @Victoria 不确定这是否是 484 字节。我当前存储的图像大小为 11.7 KB。如果以字节为单位,那么它将是 0.484 KB,并且该图像不适合该字段。
  • 如果不是 484 则显示表的实际架构。你用的是什么数据库?什么数据库组件?你怎么连接?直接的? ODBC?还有什么?什么版本的德尔福?
  • 尝试执行事务。如果失败,回滚并报错。

标签: delphi


【解决方案1】:

TField 有一个Size 属性:

表示在定义支持不同大小的数据类型的物理数据库字段中使用的大小。

试试这样的:

MemStream := TMemoryStream.Create;
try
  JpegImage := TJPEGImage.Create;
  try
    Picture := TPicture.Create;
    try
      Picture.LoadFromFile(OpenPictureDialog1.FileName);
      JpegImage.Assign(Picture.Graphic);
    finally
      Picture.Free;
    end;
    JpegImage.SaveToStream(MemStream);
  finally
    JpegImage.Free;
  end;
  Field := dtm.cds.FieldByName('PICTURE');
  if MemStream.Size > Field.Size then
    raise Exception.Create('Image as a JPEG is too large to store!');
  dtm.cds.Insert;
  try
    Stream := dtm.cds.CreateBlobStream(Field, bmWrite);
    try
      Stream.CopyFrom(MemStream, 0);
    finally
      Stream.Free;
    end;
    dtm.cds.Post;
  except
    dtm.cds.Cancel;
    raise;
  end;
finally
  MemStream.Free;
end;
dtm.cds.ApplyUpdates(-1);

【讨论】:

  • LONGVARBINARY 是可变长度数据类型,数据库不会施加任何长度约束。这就是为什么它被映射到一个 blob,它的大小是你设置的任何东西。
  • @SertacAkyuz 如果那是真的(我不争论它不是)那么我看不出任何原因为什么 OP 会在发布不同大小的图像时遇到问题,除非真的有是否达到了某个最大限制。我想这取决于使用的是哪种数据库。 OP尚未说明。
  • 确实,OP 在数据库级别上一直非常离散,在之前的问题中也是如此。我曾想过一个触发器,但谁知道..
【解决方案2】:

您可以使用您正在使用的流的Size 属性。当然,您需要知道数据库允许的确切大小。例如:

const
   MAXIMAGESIZE = ???;
   IMAGEOVERSIZE = 'Image size is larger than allowed';
..
  ...
  try
      JpegImage.Assign(Image1.Picture);
      JpegImage.SaveToStream(Stream);
      if Stream.Size <= MAXIMAGESIZE then begin
          dtm.cds.Post;
          dtm.cds.ApplyUpdates(-1);
      end else begin
          dtm.cds.Cancel;
          raise Exception.Create(IMAGEOVERSIZE);
      end;
  finally
      Stream.Free;
  end;

【讨论】:

  • 谢谢,我会尝试并尽快报告。
  • "你当然需要知道数据库允许的确切大小" - TField.Size 属性告诉你。
  • 谢谢。我现在知道该字段的最大大小。我不确定该表是如何定义的。我将使用此方法将图像限制在大小限制内。
  • 我建议先将 JPEG 保存到一个临时的 TMemoryStream,然后仅在合适的情况下上传,否则甚至不要 Insert 一个新记录。如果您将 JPEG 直接保存到 blob 字段并且它超过了 blob 的大小,您可能会收到上述代码未考虑的错误。另外,你不应该使用不可见的TImage,而是使用你自己的TPicture 对象
  • @RemyLebeau 好的,谢谢。实际上这就是让我检查图像大小的原因。
猜你喜欢
  • 2017-05-27
  • 2021-08-19
  • 1970-01-01
  • 2018-08-28
  • 2017-04-27
  • 2018-02-09
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
相关资源
最近更新 更多