从Android photo上传到Datasnap服务器的图像具有不同的图像类型和尺寸
我正在尝试创建一个DelphiXe5 Android Datasnap应用程序(常规,而不是REST),用于上传图片 请参阅下面的代码。代码有效!安卓手机上的摄像头拍摄的图像被传输到服务器并保存。问题是:从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
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常量。