Page 1 of 1

Image encode Base64 for use in HTML

Posted: Tue Feb 06, 2018 12:08 pm
by kvitaliy
Generates base-64 encoded from a given image file.
Encoded images is to wrap into html img tags.

Code: Select all

file$ = OpenFileRequester("Select a file","","Images (BMP,GIF,JPG,ICO,PNG) | *.bmp;*.gif;*.jpg;*.jpeg;*.png;*.ico",0)
  If file$
    If ReadFile(0, file$)
      length = Lof(0)                           
      *MemoryID = AllocateMemory(length)        
      If *MemoryID
        bytes = ReadData(0, *MemoryID, length)  
      EndIf
      CloseFile(0)
      Extension$ = GetExtensionPart(file$)
         Else
            End
    EndIf
  Else
    End
  EndIf

  Size = length * 1.35
  If Size < 64
    Size = 64
  EndIf
  
  *EncodeBuffer = AllocateMemory(Size)
  Size = Base64EncoderBuffer(*MemoryID, length, *EncodeBuffer, MemorySize(*EncodeBuffer))
  Encoded$ = PeekS(*EncodeBuffer, Size, #PB_Ascii)
  Debug Encoded$
  
  testHTML$+ "<html>"+ #CRLF$ +
             "<head>"+ #CRLF$ +
             "<title>BaseImage</title>"+ #CRLF$+
             "</head>"+ #CRLF$+
             "<body bgcolor='FFFFFF' text='#000000'>"+ #CRLF$+
             "<h1>BaseImage Demo</h1>"+ #CRLF$+
             "<h2>Created With PureBasic v.5.6x </h2>"+ #CRLF$+
             "<br /><br />"+ #CRLF$+
             "<img src='Data:image/"+Extension$+";base64," +Encoded$ + "'  />"+ #CRLF$+
             "<h3>Base 64 encoded image file wrapped in image tags</h3>"+ #CRLF$+
             "<br />"+ #CRLF$+
             "</body>"+ #CRLF$+
             "</html>"
  CreateFile(0,GetTemporaryDirectory()+"testB64.html")
  WriteString(0,testHTML$)
  CloseFile(0)
  RunProgram(GetTemporaryDirectory()+"testB64.html")
 

Re: Image encode Base64 for use in HTML

Posted: Tue Feb 06, 2018 12:40 pm
by infratec
Why not:

Code: Select all

Encoded$ = Base64Encoder(*MemoryID, length)
Makes life easier :wink:

Re: Image encode Base64 for use in HTML

Posted: Tue Feb 06, 2018 1:44 pm
by Kwai chang caine
Very useful for save a full HTML page with all his pictures in only one file, a little bit like the "MHT" format of IE :wink:
The pluggin for FF, "Save page WE" use this tips and do that perfectly...it's a real miracle, before i install him, i don't know it's possible :shock:
Thanks a lot for sharing KVITALIY 8)

Re: Image encode Base64 for use in HTML

Posted: Tue Feb 06, 2018 2:19 pm
by kvitaliy
infratec wrote:Why not:

Code: Select all

Encoded$ = Base64Encoder(*MemoryID, length)
Makes life easier :wink:
Ok!
The main thing is the principle of work. The implementation method may be different.

Re: Image encode Base64 for use in HTML

Posted: Wed Feb 14, 2018 8:13 am
by Seymour Clufley
A much more extensive tool for Base64'ing all resources called by an HTML file can be found here.

Re: Image encode Base64 for use in HTML

Posted: Sun Dec 31, 2023 1:35 am
by tikidays
Thanks for this code kvitally,

Are you able to show me how to use the encoding part of this to encode a PNG in memory to a string? Im a noob and tried and failed. I want to be able to write this string to a file Im using for my app and to include images, and back again.

Code: Select all

Procedure.s encodePNG(image.i)
  *memoryID = image
  length = SizeOf(image)
  size = length * 1.35
  If size < 64 : size = 64 : EndIf
  *encodeBuffer = AllocateMemory(size)
  size = Base64EncoderBuffer(*memoryID, length, *encodeBuffer, MemorySize(*encodeBuffer))
  encoded.s = PeekS(*encodeBuffer, size, #PB_Ascii)
  ProcedureReturn encoded
 EndProcedure
Debug gives me : size of image: 0 encoded : IE1XAwBgAAA=

Re: Image encode Base64 for use in HTML

Posted: Mon Jan 01, 2024 7:57 am
by ZX80
tikidays,

I think you need something like this:

Code: Select all

Define.i img, *mem, Base64Size
Define encoded$

img = LoadImage(#PB_Any, #PB_Compiler_Home + "Examples\Sources\Data\PureBasicLogo.bmp")
If img
  If StartDrawing(ImageOutput(img))
    *mem = DrawingBuffer()
    imgsize = DrawingBufferPitch() * ImageHeight(img) ; Wrong size !
    StopDrawing()
  EndIf
  Base64Size = Int(1.35 * imgsize)
  encoded$ = Base64Encoder(*mem, Base64Size)
  FreeImage(img)
EndIf

Debug encoded$
but...
It does not work. :(

Sorry.

Re: Image encode Base64 for use in HTML

Posted: Mon Jan 01, 2024 11:23 am
by infratec
You need EncodeImage()

This was already pointed out here:
https://www.purebasic.fr/english/viewto ... 94#p613694

Re: Image encode Base64 for use in HTML

Posted: Mon Jan 01, 2024 11:35 am
by infratec

Code: Select all

Procedure.s ImageToBase64(Image.i, Format.i=#PB_ImagePlugin_JPEG)
  
  Protected *ImgBuffer, Base64$
  
  
  If IsImage(Image)
    *ImgBuffer = EncodeImage(Image, Format)
    If *ImgBuffer
      Base64$ = Base64Encoder(*ImgBuffer, MemorySize(*ImgBuffer))
      FreeMemory(*ImgBuffer)
    EndIf
  EndIf
  
  ProcedureReturn Base64$
  
EndProcedure

Re: Image encode Base64 for use in HTML

Posted: Mon Jan 01, 2024 8:06 pm
by ZX80
infratec, it works !
Thank you so much !

Tell me, please, in order to correctly decode an image, I need to know the original size of the image ?
I just tried STARGÅTE code from here. And... I was unable to obtain the original image. It is three+ times larger in size and also distorted. Even if I manually write the original image size (buffersize = 7812). It still doesn't work properly.

Thank you in advance !

Code: Select all

Procedure.s ImageToBase64(Image.i, Format.i=#PB_ImagePlugin_JPEG)
  
  Protected *ImgBuffer, Base64$
  
  
  If IsImage(Image)
    *ImgBuffer = EncodeImage(Image, Format)
    If *ImgBuffer
      Base64$ = Base64Encoder(*ImgBuffer, MemorySize(*ImgBuffer))
      FreeMemory(*ImgBuffer)
    EndIf
  EndIf
  
  ProcedureReturn Base64$
  
EndProcedure

Procedure base64catchimage(buffer$) ; Create a new image from a base64 string.
  
  Protected buffersize = 64
  
  If Len(buffer$) > buffersize
    buffersize = Len(buffer$) * 0.7 ; buffer can by smaller.
  EndIf
  
  *output = AllocateMemory(buffersize) ; Allocate a memory block the size of the string (buffer$)
  
  Debug "buffersize =  " + Str(buffersize)
  buffersize = Base64Decoder(buffer$, *output , buffersize) ; Decode the string (buffer$) into memory (*output) with the size provided
  ; buffersize is now the real size of the decoded string, useful in CatchImage.
  
  Debug "buffersize =  " + Str(buffersize) ; why buffersize is zero ???
  buffersize = 7812
  image = CatchImage(#PB_Any, *output, buffersize) ; Output an ImageID from Base64 decoded memory
  
  FreeMemory(*output)
  
  ProcedureReturn image
  
EndProcedure


img = LoadImage(#PB_Any, #PB_Compiler_Home+"Examples\Sources\Data\PureBasicLogo.bmp")
If img
  Encoded$ = ImageToBase64(img, #PB_ImagePlugin_BMP)
  FreeImage(img)
EndIf

Debug Encoded$
; -----------------------------------------------------------------------------  
img = base64catchimage(Encoded$)
If SaveImage(img, GetTemporaryDirectory()+"testB64.bmp", #PB_ImagePlugin_BMP)
  FreeImage(img)
  RunProgram(GetTemporaryDirectory()+"testB64.bmp")
EndIf

Re: Image encode Base64 for use in HTML

Posted: Mon Jan 01, 2024 9:18 pm
by infratec
Full working example:

Code: Select all

EnableExplicit

Procedure.s ImageToBase64(Image.i, Format.i=#PB_ImagePlugin_JPEG)
  
  Protected *ImgBuffer, Base64$
  
  
  If IsImage(Image)
    *ImgBuffer = EncodeImage(Image, Format)
    If *ImgBuffer
      Base64$ = Base64Encoder(*ImgBuffer, MemorySize(*ImgBuffer))
      FreeMemory(*ImgBuffer)
    EndIf
  EndIf
  
  ProcedureReturn Base64$
  
EndProcedure


Procedure.i Base64ToImage(Base64$)
  
  Protected *Base64, *Image, Size.i, Image.i
  
  
  *Base64 = Ascii(Base64$)
  If *Base64
    *Image = AllocateMemory(MemorySize(*Base64) * 0.7, #PB_Memory_NoClear)
    If *Image
      Size = Base64DecoderBuffer(*Base64, MemorySize(*Base64), *Image, MemorySize(*Image))
      If Size > 0
        Image = CatchImage(#PB_Any, *Image, Size)
      EndIf
      FreeMemory(*Image)
    EndIf
    FreeMemory(*Base64)
  EndIf
  
  ProcedureReturn Image
  
EndProcedure


#Filename$ = "c:\tmp\base64.jpg"

Define Base64$, Image.i


UseJPEGImageEncoder()
UseJPEGImageDecoder()


CreateImage(0, 200, 200)
If StartDrawing(ImageOutput(0))
  Box(0, 0, 200, 200, #Red)
  StopDrawing()
  
  If CreateFile(1, #Filename$)
    WriteString(1, ImageToBase64(0, #PB_ImagePlugin_JPEG), #PB_Ascii)
    CloseFile(1)
  EndIf
EndIf

If FileSize(#Filename$) > 0
  If ReadFile(1, #Filename$)
    Base64$ = ReadString(1, #PB_Ascii|#PB_File_IgnoreEOL)
    CloseFile(1)
  EndIf
EndIf

If Base64$ <> ""
  Image = Base64ToImage(Base64$)
  If IsImage(Image)
    Debug "Image loaded"
    
    OpenWindow(0, 0, 0, 200, 200, "Base64Image", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    ImageGadget(0, 0, 0, 0, 0, ImageID(Image))
    
    Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
    
    FreeImage(Image)
  Else
    Debug "Image failed"
  EndIf
EndIf

DeleteFile(#Filename$)

Re: Image encode Base64 for use in HTML

Posted: Mon Jan 01, 2024 10:33 pm
by ZX80
infratec, thank you very much again !
I'll look your code in detail tomorrow.

This is a very useful piece of code to send image over a network.
Thank you !

Re: Image encode Base64 for use in HTML

Posted: Mon Jan 01, 2024 10:58 pm
by ZX80
infratec, I did a little test now and...
YES :!: Checksums are OK ! Сontent is ok.

I was a confused by the difference in file sizes between the original and decoded ones. But now I'm sure everything is fine ! I confirm !
Thank you !