为什么上传的照片比保存的小得多-Delphi 10.3.2,firemonkey

为什么上传的照片比保存的小得多-Delphi 10.3.2,firemonkey,delphi,firemonkey,Delphi,Firemonkey,我有Delphi 10.3.2 我不理解这种情况: (一) 上传照片约1米 image1.Bitmap.LoadFromFile('test.jpg'); 然后我保存同一张照片 image1.Bitmap.SaveToFile('test_new.jpg'); 而test_new.jpg大约有300万台。为什么 (二) 我想使用IdHTTP和POST请求从TImage(test1.jpg-1MB)对象向服务器发送一张照片。 我使用函数Base64_Encoding_stream对图像进行编码

我有Delphi 10.3.2 我不理解这种情况:

(一) 上传照片约1米

image1.Bitmap.LoadFromFile('test.jpg');
然后我保存同一张照片

image1.Bitmap.SaveToFile('test_new.jpg');
而test_new.jpg大约有300万台。为什么

(二)

我想使用IdHTTP和POST请求从TImage(test1.jpg-1MB)对象向服务器发送一张照片。 我使用函数Base64_Encoding_stream对图像进行编码。 编码后的图像大小(字符串)函数为20 MB?为什么原始文件有1MB

function Base64_Encoding_stream(_image:Timage): string;
var
  base64: TIdEncoderMIME;
  output: string;
  stream_image : TStream;
begin
    try
      begin
        base64 := TIdEncoderMIME.Create(nil);
        stream_image := TMemoryStream.Create;
        _image.Bitmap.SaveToStream(stream_image);
        stream_image.Position := 0;
        output := TIdEncoderMIME.EncodeStream(stream_image);
        stream_image.Free;
        base64.Free;
        if not(output = '') then
        begin
          Result := output;
        end
        else
        begin
          Result := 'Error';
        end;
      end;
    except
      begin
        Result := 'Error'
      end;
    end;
 end;


....

img_encoded := Base64_Encoding_stream(Image1);

.....

procedure Send(_json:String );
var
  lHTTP             : TIdHTTP;
  PostData          : TStringList;
begin
  PostData := TStringList.Create;
  lHTTP := TIdHTTP.Create(nil);
  try
      PostData.Add('dane='  + _json );
      lHTTP.Request.UserAgent   :=   'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0';
      lHTTP.Request.Connection  := 'keep-alive';
      lHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
      lHTTP.Request.Charset     := 'utf-8';
      lHTTP.Request.Method      := 'POST';

    _dane := lHTTP.Post('http://......./add_photo.php',PostData);

  finally
    lHTTP.Free;
    PostData.Free;
end;



要使用base64发布原始文件,基本上可以使用自己的代码。您只需更改base64编码例程中使用的流,如下所示:

function Base64_Encoding_stream(const filename: string): string;
var
  stream_image : TStream;
begin
  try
    // create read-only stream to access the file data
    stream_image := TFileStream.Create(filename, fmOpenRead or fmShareDenyWrite);
    // the stream position will be ‘0’, so no need to set that
    Try
      Result := TIdEncoderMIME.EncodeStream(stream_image);
    Finally
      stream_image.Free;
    End;
    if length(result) = 0 then
    begin
      Result := 'Error';
    end;
  except
    Result := 'Error'
  end;
end;
此外,我还使用了一些try/finally部分对代码进行了重构,以确保出现错误时不会出现内存泄漏。我删除了try/except中的begin/end,因为它们不是必需的


还删除了本地字符串变量,以避免双字符串分配和不必要的
TIdEncoderMIME
base64对象构造。

我不相信
image1.Bitmap.LoadFromFile('test.jpg')”将实际起作用。为什么文件的大小是原来的三倍?最好的猜测是,加载一个8位位图,然后将其保存回24位位图。@KenBourassa OP使用的是FireMonkey。FMX
TBitmap
。VCL
TBitmap
仅支持BMP图像。@KenBourassa我选中了。输入照片有24位,输出照片有一位too@Olaf我不会为此使用JSON,MIME(通过
内容类型:multipart/form data
)更有意义,因为它可以同时携带文本和二进制,这是web浏览器在提交上传webforms时使用的格式,而
TIdHTTP
通过其
TIdHTTP.Post(TIdMultipartFormDataStream)
方法对该格式具有本机支持。无论哪种方式,请将您的问题显示在
TIdHTTP
代码中。@olaf关于“SaveToFile”大小:最好的猜测是您的内存中有一个位图,该位图在保存过程中被编码为jpeg,生成的jpeg大小取决于jpeg的质量和用于创建jpeg的压缩引擎。我自己也注意到,当加载到位图,然后重新转换为jpeg时,来自相机的jpeg通常会变得更大。因此,最好使用实际的JPEG文件并将其作为流发送。谢谢。我还有一个问题。如何将位图缩小到特定大小是最好的方法。新手机以高分辨率拍照。这张照片是我得到的位图。我想发送1344x635图片大小,而不是发送4032x1908大小。我尝试使用bitmap.resize方法,但效果很差。还有一件事。使用IdHTTP发送数据时,是否值得/可以使用压缩,例如GZIP?如何将上传照片的时间减到最少?@olaf抱歉,我不知道有什么更好的图像大小调整程序。@olaf压缩取决于服务器能做什么以及您有什么LIB。而且jpeg压缩效果不好,所以增益很小。@nolaspeaker我从OP复制了代码,但没有注意到这一点。我更新了答案,不使用构造的base64对象,因为
TIdEncoderMIME.EncodeStream
是一个类方法,因此不需要创建“TIdEncoderMIME”的对象。