Post Reply 
PNG to Base64 string
12-27-2018, 06:47 PM (This post was last modified: 12-27-2018 09:09 PM by Jacob Wall.)
Post: #8
RE: PNG to Base64 string
(12-27-2018 08:23 AM)Didier Lachieze Wrote:  Here is how I would do it :

Code:
L0:={137,80,78}; L1:={};
N:=L0(1)*256^2+L0(2)*256+L0(3);
FOR I FROM 3 DOWNTO 0 DO
  L1(0):=IP(N/64^I);
  N:=N-L1(0)*64^I;
END;

L1 will return {34,21,1,14}, but you can also do the lookup and build the Base64 string directly in the loop rather than building L1.

Interesting, this makes sense. I don't work with binary enough to have figured that one out easily. I implemented this method and compared performance to original version, there is a significant improvement. Using a fairly typical screen resulting in a ~26KB file; my times were:
  • Previously posted version: ~14.8s
  • Previous version without Step 5: ~14.7s
  • New version using Didier's method: ~5.2s

I experimented reading 3 bytes at a time with AFilesB, but that proved to be much slower than reading in the maximum number of bytes into a local variable, then processing it 3 bytes per iteration.

Here's the latest version:
Code:
WriteBase64();
Base64String();

EXPORT base64img2()
BEGIN
  LOCAL fname:="b64img2.html",htmlcontent,fsize,fiter,cur_chunk,j;
  AFiles(fname):=G0;
  htmlcontent:="<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><title>Base64 Screen Capture</title></head><body><div><img style=\"display:block; margin:0 auto;\" src=\"data:image/png;base64,"+WriteBase64(fname)+"\" alt=\"Sample Screen Capture\" /></div></body></html>";
  DelAFiles(fname);
  fsize:=DIM(htmlcontent);
  IF fsize>10000 THEN // max of 10000 items in a list
    fiter:=IP(fsize/10000);
    FOR j FROM 1 TO fiter DO
      cur_chunk:=ASC(MID(htmlcontent,(j-1)*10000+1,10000));
      AFilesB(fname,(j-1)*10000):=cur_chunk;
    END;
    IF FP(fsize/10000) THEN
      cur_chunk:=ASC(MID(htmlcontent,fiter*10000+1));
      AFilesB(fname,fiter*10000):=cur_chunk;
    END;
  ELSE
    AFilesB(fname,0):=ASC(htmlcontent);
  END;
END;

WriteBase64(fname)
BEGIN
  LOCAL fcontent,j,b64str:="",fsize,fiter;
  fsize:=AFilesB(fname);
  IF fsize>9998 THEN // lists can not be longer than 10000, 9999 divides by 3 evenly
    fiter:=IP(fsize/9999);
    FOR j FROM 1 TO fiter DO
      fcontent:=AFilesB(fname,(j-1)*9999,9999);
      b64str:=b64str+Base64String(9999,fcontent);
    END;
    IF FP(fsize/9999) THEN
      fcontent:=AFilesB(fname,fiter*9999,fsize-(fiter*9999));
      b64str:=b64str+Base64String(SIZE(fcontent),fcontent);
    END;
  ELSE
    fcontent:=AFilesB(fname,0,fsize);
    b64str:=b64str+Base64String(SIZE(fcontent),fcontent);
  END;
  RETURN b64str;
END;

Base64String(fsize,mylst)
BEGIN
  LOCAL fiter:=IP(fsize/3),L1,N,j,i,mystr:="";
  LOCAL dict:={"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9","+","/"};
  FOR j FROM 1 TO fiter DO
    N:=mylst(j*3-2)*256^2+mylst(j*3-1)*256+mylst(j*3);
    FOR i FROM 3 DOWNTO 0 DO
      L1:=IP(N/64^i);
      mystr:=mystr+dict(L1+1);
      N:=N-L1*64^i;
    END;
  END;
  IF fsize-fiter*3 THEN // fractional
    IF (fsize-fiter*3)==1 THEN
      N:=mylst(fsize)*256^2;
      FOR i FROM 3 DOWNTO 2 DO
        L1:=IP(N/64^i);
        mystr:=mystr+dict(L1+1);
        N:=N-L1*64^i;
      END;
      mystr:=mystr+"==";
    ELSE // must be 2
      N:=mylst(fsize-1)*256^2+mylst(fsize)*256;
      FOR i FROM 3 DOWNTO 1 DO
        L1:=IP(N/64^i);
        mystr:=mystr+dict(L1+1);
        N:=N-L1*64^i;
      END;
      mystr:=mystr+"=";
    END;
  END;
  RETURN mystr;
END;

EDIT: Removed duplicate <body> tag
Visit this user's website Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
PNG to Base64 string - Jacob Wall - 12-22-2018, 03:24 AM
RE: PNG to Base64 string - Jacob Wall - 12-22-2018, 08:30 PM
RE: PNG to Base64 string - Jacob Wall - 12-27-2018, 05:09 AM
RE: PNG to Base64 string - Jacob Wall - 12-27-2018, 05:27 AM
RE: PNG to Base64 string - Didier Lachieze - 12-27-2018, 08:23 AM
RE: PNG to Base64 string - Jacob Wall - 12-27-2018 06:47 PM
RE: PNG to Base64 string - ijabbott - 12-27-2018, 06:16 AM
RE: PNG to Base64 string - Jacob Wall - 12-27-2018, 06:35 PM
RE: PNG to Base64 string - chromos - 12-27-2018, 08:41 PM



User(s) browsing this thread: 1 Guest(s)