【问题标题】:How to send and receive a TMemoryStream (in a TObject) using DataSnap in Delphi 10.1如何在 Delphi 10.1 中使用 DataSnap 发送和接收 TMemoryStream(在 TObject 中)
【发布时间】:2020-06-15 13:42:02
【问题描述】:

我有一个使用 REST Datasnap 用 Delphi 10.1 编写的应用程序。

此应用程序包括客户端和服务器。

客户端是移动应用程序 (Android),服务器是连接到 firebird 数据库的 Windows 服务。

我有一个对象:-

TJob = class(TObject)
  private
    FID: Integer;
    FThe_Name: String;
    FImage: TMemoryStream;
  public
    constructor Create;
    destructor Destroy;
  end;

constructor TJob.Create;
begin
  inherited;
  FImage := TMemoryStream.Create;
end;

destructor TJob.Destroy;
begin
  FreeAndNil(FImage);
  inherited;
end;

当我尝试将服务器上的图像保存到数据库以及尝试在客户端打开并显示图像时,我遇到了访问冲突。

我有一个独立的多设备应用程序,它使用与客户端/服务器相同的功能(获取、保存和显示图像)并且可以工作。

客户端在表单上显示图像:-

if (Job.Image.Size > 0) then
  begin
    rectangle.Fill.Kind := TBrushKind.Bitmap;
    rectangle.Fill.Bitmap.Bitmap.LoadFromStream(Job.Image);
    rectangle.Repaint;
    Layout.Repaint;
  end;

客户端从表单中获取图像:-

if not(rectangle.Fill.Bitmap.Bitmap.IsEmpty) then
  begin
    Job.Image.Seek(0, soFromBeginning);
    rectangle.Fill.Bitmap.Bitmap.SaveToStream(Job.Image);
    Job.Image.Position := 0;
  end;

服务器将图像保存到数据库:-

  Job.Image.Position := 0;
  (TBlobField(FieldByName('MyImage'))).SaveToStream(Job.Image);

服务器从数据库中获取图像:-

(TBlobField(FieldByName('MyImage'))).SaveToStream(Job.Image);

独立应用程序使用相同的方式工作,但是在尝试保存或显示图像时出现错误。

我在数据库中填充了各种格式的图像,我可以在数据库中查看这些图像,但不能从客户端 (AV) 中查看。

关于我做错了什么的任何想法以及如何解决修复的示例?

谢谢

【问题讨论】:

  • 这里没有足够的代码。我们需要查看调用服务器方法的完整客户端代码,以及服务器方法代码。
  • 这可能是也可能不是红鲱鱼,但当我通过 TMemorystream 时,它是否需要涉及编组?我不知道它是如何工作的,所以例子将不胜感激。
  • 您使用的图像是否大于 256kb?,因为我在传递比这更大的流时遇到问题,它们会被截断,所以我不得不将它们分成块传递。 stackoverflow.com/questions/41854631/…
  • 感谢马克的指点。我找到并使用了 Base64FromBitmap 和 BitmapFromBase64。我已经用我的最新来源更新了主要帖子。 1. 我的客户将只处理 BMP 文件(只需添加一个独立的应用程序就适用于大多数类型)。 2.我的服务器在尝试保存时有一个AV,调用BitmapFromBase64(这不会发生在我的单机上)

标签: image delphi delphi-10.1-berlin datasnap


【解决方案1】:

服务器从数据库中获取图像:-

  PngImage := TPngImage.Create;
  MemoryStream := TMemoryStream.Create;
  try
    (TBlobField(FieldByName('Image'))).SaveToStream(MemoryStream);
    MemoryStream.Position := 0;
    PngImage.LoadFromStream(MemoryStream);
    Job.Image_AsStr := Base64FromPngImage(PngImage);
  finally
    MemoryStream.Free;
  end;

客户端在表单上显示图像:-

  if (Job.Image_AsStr <> '') then
  begin
    rImage.Fill.Kind := TBrushKind.Bitmap;  
    rImage.Fill.Bitmap.Bitmap := BitmapFromBase64(Job.Image_AsStr);
    rCustomer_Signature.Repaint;
    lCustomer_Signature.Repaint;
  end;

客户端从表单中获取图像:-

  if not(rImage.Fill.Bitmap.Bitmap.IsEmpty) then
  begin
    rImage.Fill.Kind := TBrushKind.Bitmap;
    Job.Image_AsStr := Base64FromBitmap(rImage.Fill.Bitmap.Bitmap);
  end
  else
    Job.Image_AsStr := '';

服务器将图像保存到数据库:-

if Job.Image_AsStr <> '' then
begin
  MemoryStream := TMemoryStream.Create;
  try
    PngImage := PngImageFromBase64(Job.Image_AsStr);
    PngImage.SaveToStream(MemoryStream);
    MemoryStream.Position := 0;
    Params[1].LoadFromStream(MemoryStream, ftBlob);
  finally
    MemoryStream.Free;
  end;
end
else
  Params[1].Clear;

根据我的经验,图像以 PngImage 的形式返回服务器,即使 它被打包为 BMP。

我现在可以确认我已在 Android 手机上进行安装和测试。 *笔记。发布的原始问题是关于使用 TMemoryStream,这些示例使用字符串。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多