使用 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
),但我不确定这可能是当它无法识别原始数据时回退。
好吧,我得到了一个
- 来自我的 base64 字符串的 PNG
- 然后将该 PNG 转换为 PDF
- 并将 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
功能,但你让我更进一步。
我想使用 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
),但我不确定这可能是当它无法识别原始数据时回退。
好吧,我得到了一个
- 来自我的 base64 字符串的 PNG
- 然后将该 PNG 转换为 PDF
- 并将 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
功能,但你让我更进一步。