从Android photo上传到Datasnap服务器的图像具有不同的图像类型和尺寸

从Android photo上传到Datasnap服务器的图像具有不同的图像类型和尺寸,android,delphi,delphi-xe5,datasnap,tstream,Android,Delphi,Delphi Xe5,Datasnap,Tstream,我正在尝试创建一个DelphiXe5 Android Datasnap应用程序(常规,而不是REST),用于上传图片 请参阅下面的代码。代码有效!安卓手机上的摄像头拍摄的图像被传输到服务器并保存。问题是: IrfanView将保存到服务器的图像识别为.png。将image001.bmp重命名为image001.png后,它是可查看的,但 它始终是800 x 600 照片还会自动保存到Android的library/pictures/camera文件夹中。此图像是一个.jpg,大小为1600 x

我正在尝试创建一个DelphiXe5 Android Datasnap应用程序(常规,而不是REST),用于上传图片

请参阅下面的代码。代码有效!安卓手机上的摄像头拍摄的图像被传输到服务器并保存。问题是:

  • IrfanView将保存到服务器的图像识别为.png。将image001.bmp重命名为image001.png后,它是可查看的,但
  • 它始终是800 x 600
  • 照片还会自动保存到Android的library/pictures/camera文件夹中。此图像是一个.jpg,大小为1600 x 1200。它不是.bmp或.png
  • 我很困惑。所有这些自动转换是在哪里发生的

    客户端代码如下所示

    procedure TfrmMain.TakePhotoFromCamerAction1FinishTaking(Image: TBitMap)
    var
      ImageStream: TMemoryStream;
      Bytes: Integer;
      FileName: String;
    begin
      ImageStream := TMemoryStream.Create;
      try
        Image.SaveToStream(ImageStream);
        ImageStream.Position := 0;
        FileName := 'Image001.bmp';
        Bytes := ClientModule1.ServerMethods1Client.UploadImage(FileName, ImageStream);
        if Bytes = -1 then
           raise exception.create('Image transfer failed!')
      finally
        ImageStream.Free
      end;
    end;
    
    function TServerMethods1.UploadImage(FileName: String; Stream: TStream): Integer;
    const
      BufSize = $F000;
    var
      Mem: TMemoryStream;
      BytesRead: Integer;
      Buffer: PByte;
    begin
    
      frmMain.LogMessage('Upload image ' + FileName);
      try
        Mem := TMemoryStream.Create;
        GetMem(Buffer, BufSize);
        try
          repeat
            BytesRead := Stream.Read(Buffer^, BufSize);
            if BytesRead > 0 then
              Mem.WriteBuffer(Buffer^, BytesRead);
          until BytesRead < BufSize;
          // here, replace with DB update
          // for now, save to file
          Mem.Seek(0, TseekOrigin.soBeginning); // necessary?
          Mem.SaveToFile(ExtractFilePath(Application.ExeName) + FileName);
          // ============================
          Result := 1; // Mem.Size doesn't work...
        finally
          FreeMem(Buffer, BufSize);
          Mem.Free;
        end;
      except
        Result := -1
      end;
    end;
    
    服务器上的方法如下所示

    procedure TfrmMain.TakePhotoFromCamerAction1FinishTaking(Image: TBitMap)
    var
      ImageStream: TMemoryStream;
      Bytes: Integer;
      FileName: String;
    begin
      ImageStream := TMemoryStream.Create;
      try
        Image.SaveToStream(ImageStream);
        ImageStream.Position := 0;
        FileName := 'Image001.bmp';
        Bytes := ClientModule1.ServerMethods1Client.UploadImage(FileName, ImageStream);
        if Bytes = -1 then
           raise exception.create('Image transfer failed!')
      finally
        ImageStream.Free
      end;
    end;
    
    function TServerMethods1.UploadImage(FileName: String; Stream: TStream): Integer;
    const
      BufSize = $F000;
    var
      Mem: TMemoryStream;
      BytesRead: Integer;
      Buffer: PByte;
    begin
    
      frmMain.LogMessage('Upload image ' + FileName);
      try
        Mem := TMemoryStream.Create;
        GetMem(Buffer, BufSize);
        try
          repeat
            BytesRead := Stream.Read(Buffer^, BufSize);
            if BytesRead > 0 then
              Mem.WriteBuffer(Buffer^, BytesRead);
          until BytesRead < BufSize;
          // here, replace with DB update
          // for now, save to file
          Mem.Seek(0, TseekOrigin.soBeginning); // necessary?
          Mem.SaveToFile(ExtractFilePath(Application.ExeName) + FileName);
          // ============================
          Result := 1; // Mem.Size doesn't work...
        finally
          FreeMem(Buffer, BufSize);
          Mem.Free;
        end;
      except
        Result := -1
      end;
    end;
    
    函数TServerMethods1.UploadImage(文件名:String;流:TStream):整数;
    常数
    BufSize=$F000;
    变量
    Mem:TMemoryStream;
    字节读取:整数;
    缓冲液:PByte;
    开始
    frmMain.LogMessage('Upload image'+文件名);
    尝试
    Mem:=TMemoryStream.Create;
    GetMem(缓冲区,BufSize);
    尝试
    重复
    BytesRead:=Stream.Read(Buffer^,BufSize);
    如果字节读取>0,则
    Mem.WriteBuffer(缓冲区^,字节读取);
    直到字节读取
    两个问题和一个注意事项:1)为什么在Android将文件保存为.jpg而不是.jpg扩展名时上载文件并提供扩展名为.bmp的文件名?2) 当您可以简单地创建一个TFileStream,使用CopyFrom(Stream),然后释放TFileStream来保存它时,为什么服务器上所有的Buffer^和TMemoryStream都是毫无意义的呢?(整个服务器端代码大约为10-12行代码)。注意:好吧,Android不支持BMP图像,因为它们通常只支持Windows。IIRC,Android本机支持PNG和JPG。你不太可能得到BMP。谢谢你的headsup wrt,BMP是Windows格式的。显然,FMX代码正在进行PNG的转换(并调整大小)。请给我看一下能与TFileStream一起工作的代码!当然<代码>扩展流:=TFileStream.Create(文件名,fmCreate);尝试OutStream.CopyFrom(Stream,Stream.Size);最后,自由的;结束不错!不幸的是,该代码只替换了我代码中的
    Mem.Seek
    Mem.savetofile
    行。(是6行,不是2行)我说的是“10-12行”,所以我认为6行比这要少很多。我发布的代码替换了对GetMem的调用、整个repeat..until循环和对FreeMem的需求,并且消除了对缓冲区和BytesRead的需求。它还删除BuffSize常量。