从base64编码的字符串解码文件到流。怎么做?

时间:2023-01-24 14:48:19

I have a string, recived by my app from web-browser. String contains PNG image, and encoded to base64.

我有一个字符串,由我的应用程序从网络浏览器中获取。字符串包含PNG图像,并编码为base64。

It isn't my stupid idea, convert image to base64 string )) That doing web-broser. HTML5 canvas object doing that, when need to send image to somewhere.

这不是我的愚蠢想法,将图像转换为base64字符串))这是做web-broser。 HTML5 canvas对象在做的时候,需要将图像发送到某个地方。

So, how to decode this string to image?

那么,如何将此字符串解码为图像?

In Delphi I written my web-server, that recives data.

在Delphi中,我编写了我的Web服务器,它可以传输数据。

In PHP this can be solved like that:

在PHP中,这可以像这样解决:

function base64_to_jpeg( $base64_string, $output_file ) {
    $ifp = fopen( $output_file, "wb" ); 
    fwrite( $ifp, base64_decode( $base64_string) ); 
    fclose( $ifp ); 
    return( $output_file ); 
}

$image = base64_to_jpeg( $my_base64_string, 'tmp.jpg' );

but in delphi, after decoding:

但在delphi中,解码后:

  if (sImg <> EmptyStr) then
  begin
    Coder := TIdDecoderMIME.Create(nil);
    MS := TMemoryStream.Create;
    try
      Coder.DecodeStream(sImg, MS);
      MS.SaveToFile(myDir + '1.png');
    finally
      FreeAndNil(MS);
      FreeAndNil(Coder);
    end;
  end;

I have a black square of Malevich.

我有一个黑色的马列维奇广场。

Also I tried functions from EncdDesd module of RTL,

我还尝试了RTL的EncdDesd模块中的函数,

  if (sImg <> EmptyStr) then
  begin
    MS := TMemoryStream.Create;
    SS := TStringStream.Create(sImg);
    try
      DecodeStream(SS, MS);
      MS.SaveToFile(myDir + '1.png');
    finally
      FreeAndNil(MS);
      FreeAndNil(SS);
    end;
  end;

I got the same result.

我得到了相同的结果。

I wrote web-extension for get some info from user web-browser, and web-server using TidHTTPServer. From JS I capture the web-screenshot, and remove some data from exe, after that, I send this string to the server:

我编写了web扩展来从用户web浏览器获取一些信息,使用TidHTTPServer获取web服务器。从JS我捕获web截图,并从exe中删除一些数据,之后,我将此字符串发送到服务器:

var Img = capture().toDataURL();
var Img = Img.replace('data:image/png;base64,','');

     if (FLA.AddNewURL(sN,sD,sU,sI,Img)) {
      window.close();
     } else {
      alert('can not establish connection!');
     };

...

AddNewURL: function (aName, aDesc,sURL, aOwnerId,aImg) {
    var http = new XMLHttpRequest();
    var params = 'Owner=' + aOwnerId + '&Name=' + aName + '&Desc=' + aDesc+ '&URL=' + sURL;
    if (aImg) {
      params = params +'&Img='+aImg;
    };
        http.open("POST", "http://" + this.host + ":" + this.port + "/addurl", false);
        http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
        http.send(params);
    return (http.status === 200);
},

My web-server recives this data like that:

我的网络服务器重现这样的数据:

  if (ARequestInfo.Document = '/addurl') then
  begin
    Id := ARequestInfo.Params.Values['Owner'];
    sName := ARequestInfo.Params.Values['Name'];
    sDesc := ARequestInfo.Params.Values['Desc'];
    sURL := ARequestInfo.Params.Values['URL'];
    sImg := ARequestInfo.Params.Values['Img'];
    RootLI := nil;
    LinksManager.FindByID(Id, RootLI);
    if Assigned(RootLI) then
    begin
      LI := TLinkItem.Create(nil);
      LI.name := sName;
      LI.Description := sDesc;
      LI.URL := sURL;
      if (sImg <> EmptyStr) then
      begin
        MS := TMemoryStream.Create;
        SS := TStringStream.Create(sImg);
        try
          DecodeStream(SS, MS);
          MS.SaveToFile(myDir + '1.png');
        finally
          FreeAndNil(MS);
          FreeAndNil(SS);
        end;
      end;
      RootLI.Add(LI, True);
      AResponseInfo.ResponseText := 'OK';
    end
    else
      AResponseInfo.ResponseText := 'FAIL';
  end;

After all of that I have image, that contains only black color.

毕竟我有图像,只包含黑色。

1 个解决方案

#1


0  

I solved my problem by other way. In JS I send data via headers(Ajax.setRequestHeader), and the file I send in the POST stream. After that DecodeStream, from EncdDecd is working correctly, I got the image from string.

我通过其他方式解决了我的问题。在JS中,我通过头文件(Ajax.setRequestHeader)和我在POST流中发送的文件发送数据。在DecodeStream之后,从EncdDecd正常工作,我从字符串中获取了图像。

        Id := ARequestInfo.RawHeaders.Values['OwnerId'];
        sName := ARequestInfo.RawHeaders.Values['Name'];
        sDesc := ARequestInfo.RawHeaders.Values['Desc'];
        sURL := ARequestInfo.RawHeaders.Values['URL'];
...
          if (ARequestInfo.PostStream <> nil) then //We have the image!
          begin
            MS := TMemoryStream.Create;
            MS2 := TMemoryStream.Create;
            try
              MS2.LoadFromStream(ARequestInfo.PostStream);
              DecodeStream(MS2, MS);
              MS.SaveToFile(myDir + '1.png');
            finally
              FreeAndNil(MS);
              FreeAndNil(MS2);
            end;
          end;

Also you can try mixed of alternative multipart/form-data encoding. But Indy doesn't have implemented classes for parsing recived data in this format.

您也可以尝试混合使用替代的multipart / form-data编码。但Indy没有实现以这种格式解析回收数据的类。

#1


0  

I solved my problem by other way. In JS I send data via headers(Ajax.setRequestHeader), and the file I send in the POST stream. After that DecodeStream, from EncdDecd is working correctly, I got the image from string.

我通过其他方式解决了我的问题。在JS中,我通过头文件(Ajax.setRequestHeader)和我在POST流中发送的文件发送数据。在DecodeStream之后,从EncdDecd正常工作,我从字符串中获取了图像。

        Id := ARequestInfo.RawHeaders.Values['OwnerId'];
        sName := ARequestInfo.RawHeaders.Values['Name'];
        sDesc := ARequestInfo.RawHeaders.Values['Desc'];
        sURL := ARequestInfo.RawHeaders.Values['URL'];
...
          if (ARequestInfo.PostStream <> nil) then //We have the image!
          begin
            MS := TMemoryStream.Create;
            MS2 := TMemoryStream.Create;
            try
              MS2.LoadFromStream(ARequestInfo.PostStream);
              DecodeStream(MS2, MS);
              MS.SaveToFile(myDir + '1.png');
            finally
              FreeAndNil(MS);
              FreeAndNil(MS2);
            end;
          end;

Also you can try mixed of alternative multipart/form-data encoding. But Indy doesn't have implemented classes for parsing recived data in this format.

您也可以尝试混合使用替代的multipart / form-data编码。但Indy没有实现以这种格式解析回收数据的类。