How to speed up this Code?

Just starting out? Need help? Post your questions and find answers here.
dige
Addict
Addict
Posts: 1256
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

How to speed up this Code?

Post by dige »

Hi folks,

I want that contained images in emails always be displayed.

One possibility would be to insert the images as base64 encoded. But this does not work safely either.

What works is to convert the image into a Html table.
Unfortunately this conversation is very slow. The following code needs 900ms for a small 50x50 pixel image.

How can you make this faster?

Code: Select all

Procedure.s Image_to_HTML (ImgID)
  Protected Result.s, Col
  Protected n, i
  Protected x = -1, y = -1, w, h
  
  ; XXX Sehr langsam!
  
  If IsImage(ImgID) = 0
    ProcedureReturn ""
  EndIf
  
  If StartDrawing(ImageOutput(ImgID))
  
    Result = "<table border=0 cellspacing=0 cellpadding=0 bgcolor=#FFFFFF width=" + Str(OutputWidth()) + " height=" + Str(OutputHeight()) + ">"
    
    For n = 1 To OutputHeight()-1
      
      Result + "<tr>"
      
      For i = 1 To OutputWidth()-1
        Result + "<td width=1 height=1 bgcolor=#"
        
        Col = Point(i, n)
        
        Result + "#" + 
                 RSet(Hex(Red(Col), #PB_Byte), 2, "0") +
                 RSet(Hex(Green(Col), #PB_Byte), 2, "0") + 
                 RSet(Hex(Blue(Col), #PB_Byte), 2, "0")
        
        Result + "></td>"
        
      Next
      Result + "</tr>"
      
    Next
    Result + "</table>"
  
    StopDrawing()
  EndIf
  
  ProcedureReturn Result
EndProcedure

CreateImage(0, 50, 50, 24, #White)

TimeCount = ElapsedMilliseconds()

txt.s = Image_to_HTML (ImgID)

MessageRequester( "Done", Str(ElapsedMilliseconds() - TimeCount) + "ms" )
"Daddy, I'll run faster, then it is not so far..."
User avatar
HeX0R
Addict
Addict
Posts: 992
Joined: Mon Sep 20, 2004 7:12 am
Location: Hell

Re: How to speed up this Code?

Post by HeX0R »

try this:

Code: Select all

XIncludeFile "Stringbuilder.pbi" ;https://www.purebasic.fr/english/viewtopic.php?p=558277#p558277

Procedure.s Image_to_HTML (ImgID)
  Protected Result.s, Col
  Protected n, i, ID
  Protected x = -1, y = -1, w, h
 
  ; XXX Sehr langsam!
 
  If IsImage(ImgID) = 0
    ProcedureReturn ""
  EndIf
  
  ID = StringBuilder::Init()
  
  If StartDrawing(ImageOutput(ImgID))
 		StringBuilder::Add(ID, "<table border=0 cellspacing=0 cellpadding=0 bgcolor=#FFFFFF width=" + Str(OutputWidth()) + " height=" + Str(OutputHeight()) + ">")
   
    For n = 1 To OutputHeight()-1
     
      StringBuilder::Add(ID, "<tr>")
     
      For i = 1 To OutputWidth()-1
        StringBuilder::Add(ID, "<td width=1 height=1 bgcolor=#")
       
        Col = Point(i, n)
       
        StringBuilder::Add(ID, "#" +
                   RSet(Hex(Red(Col), #PB_Byte), 2, "0") +
                   RSet(Hex(Green(Col), #PB_Byte), 2, "0") +
                   RSet(Hex(Blue(Col), #PB_Byte), 2, "0") +
                   "></td>")
       
      Next
      StringBuilder::Add(ID, "</tr>")
     
    Next
    StringBuilder::Add(ID, "</table>")
 
    StopDrawing()
  EndIf
  
  Result = StringBuilder::GetString(ID)
 	StringBuilder::DeInit(ID)
  ProcedureReturn Result
EndProcedure

CreateImage(0, 50, 50, 24, #White)

TimeCount = ElapsedMilliseconds()

txt.s = Image_to_HTML (ImgID)

MessageRequester( "Done", Str(ElapsedMilliseconds() - TimeCount) + "ms" )
dige
Addict
Addict
Posts: 1256
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: How to speed up this Code?

Post by dige »

:shock:

Thats pretty damn fast!! :D

Thx HeX0R!!!
"Daddy, I'll run faster, then it is not so far..."
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: How to speed up this Code?

Post by wilbert »

I see you already got an answer.
This was my attempt ...

Code: Select all

Procedure.s Image_to_HTML (ImgID)
  
  Protected.i c, x, y, w, h
  Protected *b
  
  If IsImage(ImgID) And StartDrawing(ImageOutput(ImgID))
    
    w = OutputWidth()
    h = OutputHeight()
    
    Protected Dim Buffer.c((w*42+9)*h+100)
    
    *b = @Buffer()
    CopyMemoryString("<table border=0 cellspacing=0 cellpadding=0 bgcolor=#FFFFFF width=", @*b)
    CopyMemoryString(Str(w))
    CopyMemoryString(" height=")
    CopyMemoryString(Str(h))
    CopyMemoryString(">")
    
    w - 1
    h - 1
    
    For y = 0 To h
      CopyMemoryString("<tr>")
      For x = 0 To w
        CopyMemoryString("<td width=1 height=1 bgcolor=#")
        c = Point(x, y)
        CopyMemoryString(RSet(Hex((c & $ff00)|(c << 16 & $ff0000)|(c >> 16 & $ff)), 6, "0"))
        CopyMemoryString("></td>")
      Next
      CopyMemoryString("</tr>")
    Next
    CopyMemoryString("</table>")
    
    StopDrawing()
    ProcedureReturn(PeekS(@Buffer()))
    
  Else
    ProcedureReturn ""  
  EndIf
  
EndProcedure
I noticed for large images, it doesn't show the WebGadget doesn't show the whole image.
Maybe there's a limit to what the WebGadget can process.

Using CSS would result in shorter output strings.
But that might be a problem for older browsers.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Mijikai
Addict
Addict
Posts: 1360
Joined: Sun Sep 11, 2016 2:17 pm

Re: How to speed up this Code?

Post by Mijikai »

Really nice examples :)
I like wilberts version the best, anyway here is my attempt :D

Code: Select all

EnableExplicit

Procedure.s ImageHtml(Image.i)
  Protected img_w.i
  Protected img_h.i
  Protected html_size.i
  Protected *html
  Protected px.i
  Protected py.i
  Protected pw.i
  Protected ph.i
  Protected *offset.Long
  Protected color.i
  Protected index.i
  Protected buffer.s
  If IsImage(Image)
    If StartDrawing(ImageOutput(Image))
      img_w = OutputWidth()
      img_h = OutputHeight()
      buffer = "<table border=0 cellspacing=0 cellpadding=0 bgcolor=#FFFFFF width=" + Str(img_w) + " height=" + Str(img_h) + ">" + #CRLF$
      html_size = (img_h * (img_w * 88)) + 2
      *html = AllocateMemory(html_size)
      pw = img_w - 1
      ph = img_h - 1
      *offset = *html
      For py = 0 To ph
        CopyMemory(?str_tr_start,*offset,8)
        *offset + 8
        For px = 0 To pw
          color = Point(px,py)
          CopyMemory(?str_color_start,*offset,60)
          *offset + 60
          *offset\l = PeekL(?str_hex_table + (Red(color) << 2))
          *offset + 4
          *offset\l = PeekL(?str_hex_table + (Green(color) << 2))
          *offset + 4
          *offset\l = PeekL(?str_hex_table + (Blue(color) << 2))
          *offset + 4
          CopyMemory(?str_color_end,*offset,12)
          *offset + 12
        Next
        CopyMemory(?str_tr_end,*offset,14)
        *offset + 14
      Next
      StopDrawing()
      buffer + PeekS(*html) + "</table>"
      FreeMemory(*html)
      ProcedureReturn buffer
    EndIf
  EndIf
  ProcedureReturn #Null$
  str_tr_start:
  !db 0x3C,0x00,0x74,0x00,0x72,0x00,0x3E,0x00
  str_tr_end:
  !db 0x3C,0x00,0x2F,0x00,0x74,0x00,0x72,0x00,0x3E,0x00,0x0D,0x00,0x0A,0x00
  str_color_start:
  !db 0x3C,0x00,0x74,0x00,0x64,0x00,0x20,0x00,0x77,0x00,0x69,0x00,0x64,0x00,0x74,0x00
  !db 0x68,0x00,0x3D,0x00,0x31,0x00,0x20,0x00,0x68,0x00,0x65,0x00,0x69,0x00,0x67,0x00
  !db 0x68,0x00,0x74,0x00,0x3D,0x00,0x31,0x00,0x20,0x00,0x62,0x00,0x67,0x00,0x63,0x00
  !db 0x6F,0x00,0x6C,0x00,0x6F,0x00,0x72,0x00,0x3D,0x00,0x23,0x00
  str_color_end:
  !db 0x3E,0x00,0x3C,0x00,0x2F,0x00,0x74,0x00,0x64,0x00,0x3E,0x00  
  str_hex_table:
  !db 0x30,0x00,0x30,0x00,0x30,0x00,0x31,0x00,0x30,0x00,0x32,0x00,0x30,0x00,0x33,0x00
  !db 0x30,0x00,0x34,0x00,0x30,0x00,0x35,0x00,0x30,0x00,0x36,0x00,0x30,0x00,0x37,0x00
  !db 0x30,0x00,0x38,0x00,0x30,0x00,0x39,0x00,0x30,0x00,0x41,0x00,0x30,0x00,0x42,0x00
  !db 0x30,0x00,0x43,0x00,0x30,0x00,0x44,0x00,0x30,0x00,0x45,0x00,0x30,0x00,0x46,0x00
  !db 0x31,0x00,0x30,0x00,0x31,0x00,0x31,0x00,0x31,0x00,0x32,0x00,0x31,0x00,0x33,0x00
  !db 0x31,0x00,0x34,0x00,0x31,0x00,0x35,0x00,0x31,0x00,0x36,0x00,0x31,0x00,0x37,0x00
  !db 0x31,0x00,0x38,0x00,0x31,0x00,0x39,0x00,0x31,0x00,0x41,0x00,0x31,0x00,0x42,0x00
  !db 0x31,0x00,0x43,0x00,0x31,0x00,0x44,0x00,0x31,0x00,0x45,0x00,0x31,0x00,0x46,0x00
  !db 0x32,0x00,0x30,0x00,0x32,0x00,0x31,0x00,0x32,0x00,0x32,0x00,0x32,0x00,0x33,0x00
  !db 0x32,0x00,0x34,0x00,0x32,0x00,0x35,0x00,0x32,0x00,0x36,0x00,0x32,0x00,0x37,0x00
  !db 0x32,0x00,0x38,0x00,0x32,0x00,0x39,0x00,0x32,0x00,0x41,0x00,0x32,0x00,0x42,0x00
  !db 0x32,0x00,0x43,0x00,0x32,0x00,0x44,0x00,0x32,0x00,0x45,0x00,0x32,0x00,0x46,0x00
  !db 0x33,0x00,0x30,0x00,0x33,0x00,0x31,0x00,0x33,0x00,0x32,0x00,0x33,0x00,0x33,0x00
  !db 0x33,0x00,0x34,0x00,0x33,0x00,0x35,0x00,0x33,0x00,0x36,0x00,0x33,0x00,0x37,0x00
  !db 0x33,0x00,0x38,0x00,0x33,0x00,0x39,0x00,0x33,0x00,0x41,0x00,0x33,0x00,0x42,0x00
  !db 0x33,0x00,0x43,0x00,0x33,0x00,0x44,0x00,0x33,0x00,0x45,0x00,0x33,0x00,0x46,0x00
  !db 0x34,0x00,0x30,0x00,0x34,0x00,0x31,0x00,0x34,0x00,0x32,0x00,0x34,0x00,0x33,0x00
  !db 0x34,0x00,0x34,0x00,0x34,0x00,0x35,0x00,0x34,0x00,0x36,0x00,0x34,0x00,0x37,0x00
  !db 0x34,0x00,0x38,0x00,0x34,0x00,0x39,0x00,0x34,0x00,0x41,0x00,0x34,0x00,0x42,0x00
  !db 0x34,0x00,0x43,0x00,0x34,0x00,0x44,0x00,0x34,0x00,0x45,0x00,0x34,0x00,0x46,0x00
  !db 0x35,0x00,0x30,0x00,0x35,0x00,0x31,0x00,0x35,0x00,0x32,0x00,0x35,0x00,0x33,0x00
  !db 0x35,0x00,0x34,0x00,0x35,0x00,0x35,0x00,0x35,0x00,0x36,0x00,0x35,0x00,0x37,0x00
  !db 0x35,0x00,0x38,0x00,0x35,0x00,0x39,0x00,0x35,0x00,0x41,0x00,0x35,0x00,0x42,0x00
  !db 0x35,0x00,0x43,0x00,0x35,0x00,0x44,0x00,0x35,0x00,0x45,0x00,0x35,0x00,0x46,0x00
  !db 0x36,0x00,0x30,0x00,0x36,0x00,0x31,0x00,0x36,0x00,0x32,0x00,0x36,0x00,0x33,0x00
  !db 0x36,0x00,0x34,0x00,0x36,0x00,0x35,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x37,0x00
  !db 0x36,0x00,0x38,0x00,0x36,0x00,0x39,0x00,0x36,0x00,0x41,0x00,0x36,0x00,0x42,0x00
  !db 0x36,0x00,0x43,0x00,0x36,0x00,0x44,0x00,0x36,0x00,0x45,0x00,0x36,0x00,0x46,0x00
  !db 0x37,0x00,0x30,0x00,0x37,0x00,0x31,0x00,0x37,0x00,0x32,0x00,0x37,0x00,0x33,0x00
  !db 0x37,0x00,0x34,0x00,0x37,0x00,0x35,0x00,0x37,0x00,0x36,0x00,0x37,0x00,0x37,0x00
  !db 0x37,0x00,0x38,0x00,0x37,0x00,0x39,0x00,0x37,0x00,0x41,0x00,0x37,0x00,0x42,0x00
  !db 0x37,0x00,0x43,0x00,0x37,0x00,0x44,0x00,0x37,0x00,0x45,0x00,0x37,0x00,0x46,0x00
  !db 0x38,0x00,0x30,0x00,0x38,0x00,0x31,0x00,0x38,0x00,0x32,0x00,0x38,0x00,0x33,0x00
  !db 0x38,0x00,0x34,0x00,0x38,0x00,0x35,0x00,0x38,0x00,0x36,0x00,0x38,0x00,0x37,0x00
  !db 0x38,0x00,0x38,0x00,0x38,0x00,0x39,0x00,0x38,0x00,0x41,0x00,0x38,0x00,0x42,0x00
  !db 0x38,0x00,0x43,0x00,0x38,0x00,0x44,0x00,0x38,0x00,0x45,0x00,0x38,0x00,0x46,0x00
  !db 0x39,0x00,0x30,0x00,0x39,0x00,0x31,0x00,0x39,0x00,0x32,0x00,0x39,0x00,0x33,0x00
  !db 0x39,0x00,0x34,0x00,0x39,0x00,0x35,0x00,0x39,0x00,0x36,0x00,0x39,0x00,0x37,0x00
  !db 0x39,0x00,0x38,0x00,0x39,0x00,0x39,0x00,0x39,0x00,0x41,0x00,0x39,0x00,0x42,0x00
  !db 0x39,0x00,0x43,0x00,0x39,0x00,0x44,0x00,0x39,0x00,0x45,0x00,0x39,0x00,0x46,0x00
  !db 0x41,0x00,0x30,0x00,0x41,0x00,0x31,0x00,0x41,0x00,0x32,0x00,0x41,0x00,0x33,0x00
  !db 0x41,0x00,0x34,0x00,0x41,0x00,0x35,0x00,0x41,0x00,0x36,0x00,0x41,0x00,0x37,0x00
  !db 0x41,0x00,0x38,0x00,0x41,0x00,0x39,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00
  !db 0x41,0x00,0x43,0x00,0x41,0x00,0x44,0x00,0x41,0x00,0x45,0x00,0x41,0x00,0x46,0x00
  !db 0x42,0x00,0x30,0x00,0x42,0x00,0x31,0x00,0x42,0x00,0x32,0x00,0x42,0x00,0x33,0x00
  !db 0x42,0x00,0x34,0x00,0x42,0x00,0x35,0x00,0x42,0x00,0x36,0x00,0x42,0x00,0x37,0x00
  !db 0x42,0x00,0x38,0x00,0x42,0x00,0x39,0x00,0x42,0x00,0x41,0x00,0x42,0x00,0x42,0x00
  !db 0x42,0x00,0x43,0x00,0x42,0x00,0x44,0x00,0x42,0x00,0x45,0x00,0x42,0x00,0x46,0x00
  !db 0x43,0x00,0x30,0x00,0x43,0x00,0x31,0x00,0x43,0x00,0x32,0x00,0x43,0x00,0x33,0x00
  !db 0x43,0x00,0x34,0x00,0x43,0x00,0x35,0x00,0x43,0x00,0x36,0x00,0x43,0x00,0x37,0x00
  !db 0x43,0x00,0x38,0x00,0x43,0x00,0x39,0x00,0x43,0x00,0x41,0x00,0x43,0x00,0x42,0x00
  !db 0x43,0x00,0x43,0x00,0x43,0x00,0x44,0x00,0x43,0x00,0x45,0x00,0x43,0x00,0x46,0x00
  !db 0x44,0x00,0x30,0x00,0x44,0x00,0x31,0x00,0x44,0x00,0x32,0x00,0x44,0x00,0x33,0x00
  !db 0x44,0x00,0x34,0x00,0x44,0x00,0x35,0x00,0x44,0x00,0x36,0x00,0x44,0x00,0x37,0x00
  !db 0x44,0x00,0x38,0x00,0x44,0x00,0x39,0x00,0x44,0x00,0x41,0x00,0x44,0x00,0x42,0x00
  !db 0x44,0x00,0x43,0x00,0x44,0x00,0x44,0x00,0x44,0x00,0x45,0x00,0x44,0x00,0x46,0x00
  !db 0x45,0x00,0x30,0x00,0x45,0x00,0x31,0x00,0x45,0x00,0x32,0x00,0x45,0x00,0x33,0x00
  !db 0x45,0x00,0x34,0x00,0x45,0x00,0x35,0x00,0x45,0x00,0x36,0x00,0x45,0x00,0x37,0x00
  !db 0x45,0x00,0x38,0x00,0x45,0x00,0x39,0x00,0x45,0x00,0x41,0x00,0x45,0x00,0x42,0x00
  !db 0x45,0x00,0x43,0x00,0x45,0x00,0x44,0x00,0x45,0x00,0x45,0x00,0x45,0x00,0x46,0x00
  !db 0x46,0x00,0x30,0x00,0x46,0x00,0x31,0x00,0x46,0x00,0x32,0x00,0x46,0x00,0x33,0x00
  !db 0x46,0x00,0x34,0x00,0x46,0x00,0x35,0x00,0x46,0x00,0x36,0x00,0x46,0x00,0x37,0x00
  !db 0x46,0x00,0x38,0x00,0x46,0x00,0x39,0x00,0x46,0x00,0x41,0x00,0x46,0x00,0x42,0x00
  !db 0x46,0x00,0x43,0x00,0x46,0x00,0x44,0x00,0x46,0x00,0x45,0x00,0x46,0x00,0x46,0x00
EndProcedure

Global time.q
Global txt.s

CreateImage(0, 50, 50, 24, #White)
time = ElapsedMilliseconds()
txt = ImageHtml(0)
MessageRequester("Done",Str(ElapsedMilliseconds() - time) + "ms" )
;Debug txt

I also changed the formating slightly so the output looks nicer.
User avatar
NicTheQuick
Addict
Addict
Posts: 1227
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: How to speed up this Code?

Post by NicTheQuick »

dige wrote:I want that contained images in emails always be displayed.
Why is that necessary? Do you want to send spam mails? If I disable images by default in my mail program I don't want to see images encoded as a HTML table either.

There are also different approaches to include images in mails. I usually create a multipart/related content-type and add an image referenced by a CID to the body.
This then can look like this (source):

Code: Select all

 To: email@email.de
 Subject: ...
 Content-Type: multipart/related;
 boundary="------------090303020209010600070908"

This is a multi-part message in MIME format.
--------------090303020209010600070908
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 7bit

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-15">
  </head>
  <body bgcolor="#ffffff" text="#000000">
    <img src="cid:part1.06090408.01060107" alt="">
  </body>
</html>

--------------090303020209010600070908
Content-Type: image/png;
 name="moz-screenshot.png"
Content-Transfer-Encoding: base64
Content-ID: <part1.06090408.01060107>
Content-Disposition: inline;
 filename="moz-screenshot.png"

[base64 image data here]

--------------090303020209010600070908--
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
User avatar
Kiffi
Addict
Addict
Posts: 1362
Joined: Tue Mar 02, 2004 1:20 pm
Location: Amphibios 9

Re: How to speed up this Code?

Post by Kiffi »

dige wrote:What works is to convert the image into a Html table.
:shock: Please do not send me any mails!

Image

:wink:
Hygge
dige
Addict
Addict
Posts: 1256
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: How to speed up this Code?

Post by dige »

NicTheQuick wrote:
dige wrote:I want that contained images in emails always be displayed.
Why is that necessary? Do you want to send spam mails? If I disable images by default in my mail program I don't want to see images encoded as a HTML table either.
Hi NicTheQuick,

I want to send embedded graphics. Unfortunately Outlook does not show them.
The conversion to Html was therefore a quick'n dirty workaround..

For sending I use SendMail_Include.pbi from ts-soft. viewtopic.php?f=12&t=50538&p=562576#p562576

Your tip made me aware that it might be because I encoded the Base64 data directly into Html and not via a cid.

Do you create the emails "by hand" or do you have a lib for that?
"Daddy, I'll run faster, then it is not so far..."
User avatar
helpy
Enthusiast
Enthusiast
Posts: 552
Joined: Sat Jun 28, 2003 12:01 am

Re: How to speed up this Code?

Post by helpy »

NicTheQuick wrote:
dige wrote:I want that contained images in emails always be displayed.
Why is that necessary? Do you want to send spam mails? If I disable images by default in my mail program I don't want to see images encoded as a HTML table either.
:thumbs-up: :!:

HTML tables with a lot of rows/columns :-(
... so much HTML code increases the size of the mail drastically!

Some Mail-Clients convert HTML-formatted text to raw text (if user want it ...).
In this case your image will not be displayed either.
Windows 10 / Windows 7
PB Last Final / Last Beta Testing
dige
Addict
Addict
Posts: 1256
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: How to speed up this Code?

Post by dige »

helpy wrote: HTML tables with a lot of rows/columns :-(
... so much HTML code increases the size of the mail drastically!

Some Mail-Clients convert HTML-formatted text to raw text (if user want it ...).
In this case your image will not be displayed either.
Hello Helpy, thank you very much for your contribution. :|
Yes, there are maybe people outside, who can read 1,000 of numbers faster,
instead instead of looking at a chart..
"Daddy, I'll run faster, then it is not so far..."
User avatar
Paul
PureBasic Expert
PureBasic Expert
Posts: 1252
Joined: Fri Apr 25, 2003 4:34 pm
Location: Canada
Contact:

Re: How to speed up this Code?

Post by Paul »

@Kiffi

Excel Rose .... LOL !!
Image Image
Post Reply