首页 > 解决方案 > 为什么上传的照片比保存的小很多 - Delphi 10.3.2, firemonkey

问题描述

我有 Delphi 10.3.2 我不明白这种情况:

1)上传照片约1M

image1.Bitmap.LoadFromFile('test.jpg');

然后我保存同一张照片

image1.Bitmap.SaveToFile('test_new.jpg');

和 test_new.jpg 大约是 3M。为什么 ???

2)

我想使用 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;


标签: delphifiremonkey

解决方案


要使用 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 中的开始/结束,因为不需要这些。

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


推荐阅读