答案1
CTAN 上有一个新的包:
亨德里克森的安德斯提交了
qrcode
包裹。
版本号:1.0 许可类型:lppl1.3
摘要描述:在 LaTeX 中生成二维码。
公告正文:
该软件包可在 LaTeX 中生成快速响应(QR)码,无需 pstricks 或任何其他图形包。
此包位于
http://mirror.ctan.org/macros/latex/contrib/qrcode更多信息请访问 http://www.ctan.org/pkg/qrcode
我通过 TeXLive 2014 安装了该包,使用 pdfLaTeX、xeLaTeX 和 luaLaTeX 的结果看起来正确。
代码示例:
\documentclass{article}
\usepackage[]{qrcode}
\begin{document}
\qrcode[]{Dummy code}
\end{document}
结果:
答案2
嗯,这是作弊,但我无法抗拒:
结果
文件
\documentclass{article}
\usepackage{qrcode}
% Defines \qrcode command to be used inside a tikzpicture, with two arguments
% #1 Size of the square (in tikz relative units) [optional, defaults to 10 units]
% #2 String for the QRCode
% It draws the qrcode using styles "pixel on" and "pixel off" and defines
% a node named (qrcode) of the given size, so you can refer to its anchors for
% further drawing or labelling.
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}[node distance=2mm]
\qrcode[4]{This is a test};
\node[below=of qrcode] {This is a test};
\end{tikzpicture}
%
\hfill
%
\begin{tikzpicture}[node distance=2mm]
\qrcode[6]{https://tex.stackexchange.com/a/102569/12571}
\node[below=of qrcode] {This is not an answer};
\end{tikzpicture}
\end{document}
欺骗
内容qrcode.sty
\RequirePackage{tikz}
\usetikzlibrary{fit}
\directlua{dofile("luaqrcode.lua")} % <--- Oooh!
\newcommand{\qrcode}[2][10]{%
\begin{scope}[qrcode]
\directlua{tikzQRCode("#2",#1)}%
\end{scope}
}
\tikzset{
qrcode/.style = {line width = 2sp},
pixel on/.style = {black},
pixel off/.style = {white},
pixel err/.style = {red}
}
内容luaqrcode.lua
qrencode = dofile("qrencode.lua") -- <--- Ooooh! You cheater!
local function matrix_to_tikz( tab , size)
if (size == nil) then size=10 end
pixel_width = size / #tab
pixel_cmd = string.format("\\filldraw[%%s] (%%f, %%f) +(-%f, %f) rectangle +(%f, -%f);",
pixel_width/2, pixel_width/2, pixel_width/2, pixel_width/2)
str_tab = {}
for y=1,#tab do
row = {}
for x=1,#tab do
if tab[x][y] > 0 then
style = "pixel on"
elseif tab[x][y] < 0 then
style = "pixel off"
else
style = "pixel err"
end
if style=="pixel off" then
row[x] = ""
else
row[x] = string.format(pixel_cmd, style, x*pixel_width, -y*pixel_width)
end
end
str_tab[y] = table.concat(row, "\n")
end
local extra = {}
extra[1] = string.format("\\coordinate (aux1) at (%f,-%f);", pixel_width/2, size+pixel_width/2)
extra[2] = string.format("\\coordinate (aux2) at (%f, %f);", size+pixel_width/2, -pixel_width/2)
extra[3] = "\\node[inner sep=0pt, fit=(aux1) (aux2)] (qrcode) {};"
str_tab[#tab+1] = table.concat(extra, "\n")
return table.concat(str_tab,"\n")
end
function tikzQRCode(txt, size)
local ok, tab_or_message = qrencode.qrcode(txt)
if not ok then
tex.print(tab_or_message)
else
tex.print(matrix_to_tikz(tab_or_message, size))
end
end
文件qrencode.lua
可以从这里下载:
更新:关于性能的说明
主文档的编译花费的时间比我预期的要多(几秒钟),但瓶颈不是 Lua,而是 tikz。lua 代码生成了大量需要填充的小矩形,而 tikz 需要时间来绘制所有矩形(我将 tikz 生成代码替换为 lua 中的简单“打印”语句到控制台,它几乎立即编译完成)。
为了减少编译时间,我修改了 lua 代码,以便实际上只绘制黑色像素,从而将编译时间减少一半(在我的第一个实现中,Lua 同时生成了黑色和白色像素)。
如果不使用 tikz 来绘制像素,而是\rule
使用 tex 原语,则可以显著缩短编译时间,如下所示这个答案它基本上与我的代码执行相同的操作,但没有 tikz(感谢 michal.h21 指出我的答案)。
检查库后luaqrcode
发现 QR 算法相当复杂。虽然许多值都是预先计算并存储在表中的,这可以简化纯 tex 实现,但我担心该实现的性能。