我想在 LuaTeX(或 pdfTeX)中创建一个位图(黑白),然后重新缩放。例如,可以通过以下方式制作(4x4 位图)
\makebitmap{0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0}
我其实不太在意界面。对我来说,更重要的是整体方法。
我想在 LuaTeX 中使用它,这样img.stream
对我很有用。但是使用\pdf...
命令的 PDFTeX 方法也很好。
重要限制:我不能创建任何中间文件,并且它必须离线工作。
为了清楚起见:我只对如何在 pdf/LuaTeX 中生成位图图形(png、bmp 等等)感兴趣。
背景:我开发了一个qrcode 编码 lua 库我想为它制作一个 LuaLaTeX 包。我看到三种可能的方法:
- 使用 pdf 说明(
0 0 10 10 re f
例如) - 使用
\rule
命令制作黑色部分 - 创建位图“文件”并缩放它。
我仍在尝试寻找最佳方法。
我已尝试使用 pdf 说明(上面的第 1 项),但在某些 pdf 查看器应用程序中结果很难看:
在某些缩放设置中,黑框被一些小白线分隔。我想避免它们。这就是为什么我想创建位图而不是 pdf 说明。
答案1
为此,您需要创建并添加一个 PDF 对象(\pdfobj
我猜是使用;请参阅pdftex
手册)到 PDF 中,该对象保存图像的(二进制?)表示,然后在您希望显示图像的位置引用此对象。这就是\includegraphics
PDF 输出的作用。
据他PDF 参考(31MB!),第 3.3.6 节JBIG2Decode 过滤器JBIG2 格式是专门为此类单色图像创建的。这里最好的一点是,它的对象流可以以 ASCII 格式给出,从而避免了在 TeX 中处理二进制材料的需要。
那里给出了以下示例。我认为使用 将其添加到 PDF 中应该不会有问题\pdfobj
。您“仅”需要生成图像的 JBIG2 编码,这应该可以使用 Lua 实现。
5 0 obj
<< /Type /XObject
/Subtype /Image
/Width 52
/Height 66
/ColorSpace /DeviceGray
/BitsPerComponent 1
/Length 224
/Filter [ /ASCIIHexDecode /JBIG2Decode ]
/DecodeParms [ null << /JBIG2Globals 6 0 R >> ]
>>
stream
000000013000010000001300000034000000420000000000
00000040000000000002062000010000001e000000340000
004200000000000000000200100000000231db51ce51ffac >
endstream
endobj
6 0 obj
<< /Length 126
/Filter /ASCIIHexDecode
>>
stream
0000000000010000000032000003fffdff02fefefe000000
01000000012ae225aea9a5a538b4d9999c5c8e56ef0f872
7f2b53d4e37ef795cc5506dffac >
endstream
endobj
我将尝试创建一个 LaTeX 示例文件来展示该原理。
到目前为止,我只知道如何创建对象,但还不知道如何在文档中显示图像。
\documentclass{article}
\pdfcompresslevel=0
\pdfobjcompresslevel=0
\begin{document}
\leavevmode\fbox{%
\pdfobj stream attr
{
/Filter /ASCIIHexDecode
} {
0000000000010000000032000003fffdff02fefefe000000
01000000012ae225aea9a5a538b4d9999c5c8e56ef0f872
7f2b53d4e37ef795cc5506dffac
}%
%\pdfrefobj\pdflastobj
\pdfobj stream attr {
/Type /XObject
/Subtype /Image
/Width 52
/Height 66
/ColorSpace /DeviceGray
/BitsPerComponent 1
%/Length 224
/Filter [ /ASCIIHexDecode /JBIG2Decode ]
/DecodeParms [ null << /JBIG2Globals \the\pdflastobj\space 0 R >> ]
} {
000000013000010000001300000034000000420000000000
00000040000000000002062000010000001e000000340000
004200000000000000000200100000000231db51ce51ffac
}%
\pdfrefobj\pdflastobj
}
\end{document}
答案2
我创建了简单的可视化模块luaqrcode
:
module(...,package.seeall)
qrcodelib = dofile("qrencode.lua")
local function black_box(w,h)
return "\\vrule width "..w.." height "..h
end
local function white_box(w,h)
return "\\hskip "..w
end
function generate_matrix2(s,w,h)
local ok, tab_or_message = qrcodelib.qrcode(s)
local buffer = {}
local write_nl = function(text)
table.insert(buffer,text)
end
if not ok then
print(tab_or_message)
else
write_nl("\\bgroup")
--write_nl("\\vbox\\bgroup%")
write_nl("\\baselineskip="..h)
local x = #tab_or_message[1]
local y = #tab_or_message
for i = 1, x, 1 do
local boxes = {}
for n = 1, y, 1 do
local p = tab_or_message[n][i] > 0 and black_box(w,h) or white_box(w,h)
table.insert(boxes,p)
end
write_nl("\\hbox{"..table.concat(boxes).."}")
end
write_nl("\\egroup")
end
return table.concat(buffer,"")
end
以及简单的LaTeX界面和示例文档:
\documentclass{article}
\usepackage{luacode}
\luaexec{qrcode = require("sample")}
\newcommand\qrcode[1]{%
\vbox{
\directlua{%
tex.print(qrcode.generate_matrix2("\luatexluaescapestring{#1}","3pt","3pt"))
}
}
}
\begin{document}
Now generate some qrcodes:\\
\qrcode{Prilis zlutoucky kun upel dabelske ody}
\qrcode{Příliš žluťoučký kůň úpěl ďábelské ódy}
\qrcode{Helloworld}
\end{document}
结果如下:
答案3
我不知道这是否是你想要的:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\makebitmap}{O{4} m}
{
\topskip_make_bitmap:nn { #1 } { #2 }
}
\cs_new_protected:Npn \topskip_make_bitmap:nn #1 #2
{
\tl_set:Nn \l__topskip_input_tl { #2 }
\tl_remove_all:Nn \l__topskip_input_tl { ~ }
\int_zero:N \l__topskip_cycle_int
\tl_clear:N \l__topskip_bitmap_tl
\tl_map_inline:Nn \l__topskip_input_tl
{
\int_incr:N \l__topskip_cycle_int
\tl_put_right:Nx \l__topskip_bitmap_tl
{
\str_case:nnn { ##1 }
{
{ 0 } { \topskip_zero: }
{ 1 } { \topskip_one: }
}
{ \topskip_error: }
\int_compare:nTF { \l__topskip_cycle_int = #1 } { \cr } { & }
}
\int_compare:nT { \l__topskip_cycle_int = #1 } { \int_zero:N \l__topskip_cycle_int }
}
\vbox
{
\offinterlineskip
\halign{&##\cr\l__topskip_bitmap_tl\crcr}}
}
\cs_new_protected:Npn \topskip_zero:
{ \vrule height 3pt width 0pt\kern 3pt }
\cs_new_protected:Npn \topskip_one:
{ \vrule height 3pt width 3pt depth 0pt }
\int_new:N \l__topskip_cycle_int
\seq_new:N \l__topskip_bitmap_seq
\tl_new:N \l__topskip_bitmap_tl
\ExplSyntaxOff
\begin{document}
\fbox{\makebitmap{0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0}}
\fbox{\makebitmap{1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1}}
\fbox{\makebitmap[16]{
1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1
0 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0
1 0 1 0 0 1 0 1 1 0 1 0 0 1 0 1
0 1 0 1 0 0 1 0 1 1 0 1 0 0 1 0
}}
\end{document}