使用 Tcl 将 HTML5 canvas 转换为 PDF

Convert a HTML5 canvas to PDF using Tcl

我想使用 Tcl 将通过 Javascript 从 HTML5 canvas 检索到的 base64 字符串保存到 PDF 文件。

我通过 JS 从 Canvas 获得了 base 64 SDtring:let data = chart.getImage('stream').data; 同时我将这个 base64 数据保存在一个文件中用于测试。在我的 Tcl 脚本中,我加载了这个文件并尝试使用包 pdf4tcl.

来转换它
#! /bin/env tclsh

# import Tcl (optional) but makes script more portable
package require Tcl

# import pdf4tcl
lappend auto_path "C:/Users/ - deleted for privacy ^^ -"
package require pdf4tcl

# Read demo File (contains base64 encoded canvas)
set fp [open "singerGraph.txt" r]
set canvas_data [read $fp]
close $fp


# create a pdf object
pdf4tcl::new mypdf -paper a4 -margin 15mm
mypdf startPage

# this command doesnt work
# mypdf putRawImage $image_data 60 20 -height 40

# write pdf to a file
mypdf write -file mypdf.pdf
mypdf destroy

putRawImage 方法产生

 instead
    while executing
"binary format H* $row"
    (class "::pdf4tcl::pdf4tcl" method "putRawImage" line 88)
    invoked from within
"mypdf putRawImage $canvas_data 60 20 -height 40"
    (file "base64ToPdf.tcl" line 28)

但我认为无论如何这是错误的命令...

对于简单的测试,这个 base 64 可能就足够了

data =  "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oMCRUiMrIBQVkAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAADElEQVQI12NgoC4AAABQAAEiE+h1AAAAAElFTkSuQmCC";

但是我的数据以 : data:application/octet-stream;base64, 开头,但我不知道这是否重要。测试数据太长,贴在这里

有人能指引我正确的方向吗?所以我可以将这些数据转换成 PDF 甚至 PNG 现在就足够了。

您需要在解码该字符串之前去除元数据(即前缀 data:image/png;base64,)。

这是执行此操作的过程:

proc decodeImage {string} {
    if {[regexp {^data:image/(\w+);base64,(.*)$} $string type data]} {
        # DEBUG: puts "we have image data of type $type"
        return [binary decode base64 $data]
    } elseif {[regexp {^data:image/(\w+),(.*)} $string type data]} {
        # DEBUG: puts "we have image data of type $type"
        return $data
    } elseif {[regexp {^[0-9a-fA-F]+$} $string]} {
        # Looks like hexadecimal data...
        return [binary decode hex $string]
    }
    # It's in some other format. There's like a zillion of them so…
    error "unrecognised format"
}

我怀疑这还不够,你嵌入的数据应该是十六进制编码的(因此 binary format),但我不确定这可能是当它无法识别原始数据时回退。

好吧,我得到了一个

  1. 来自我的 base64 字符串的 PNG
  2. 然后将该 PNG 转换为 PDF
  3. 并将 PDF 另存为文件

由于我是 Tcl 的新手,这段代码可能很糟糕,但现在,这是一个很好的起点。

#! /bin/env tclsh

package require base64
package require Img

# import pdf4tcl
lappend auto_path "C:/Users/ *username* /Documents/Tcl-TK"
package require pdf4tcl

# Read demo File   (with removed prefix: [data:application/octet-stream;base64,])
set fp [open "singerGraph.txt" r]
set canvas_data [read $fp]
close $fp

# Create PNG Image
set data [binary decode base64 $canvas_data]
set img [image create photo imgobj -data $data -format PNG]

# Display Image
puts $img
pack [label .myLabel]
.myLabel configure -image imgobj 

# create a pdf object
pdf4tcl::new mypdf -paper a4 -margin 15mm
mypdf startPage

# add Image to PDF 
set img_handle [mypdf addRawImage [imgobj data]]
mypdf putImage $img_handle 15 15 -width 210

# write pdf to a file
mypdf write -file heureka.pdf
mypdf destroy

@DonalFellows 感谢您的帮助。我需要根据需要调整 decodeImage 功能,但你让我更进一步。