Last active
April 18, 2026 20:26
-
-
Save dvruette/051b20ce5c7c2ccf75995635205a3061 to your computer and use it in GitHub Desktop.
QR code with logo in LaTeX
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| \documentclass[11pt]{article} | |
| \usepackage{qrcodewithlogo} | |
| \begin{document} | |
| % basic usage | |
| \qrcodeWithLogo[width=5cm, logo=assets/arxiv.png]{https://arxiv.org/abs/1503.03585} | |
| % adjust size and padding of logo, error correction of QR code | |
| \qrcodeWithLogo[width=5cm, padding=0, scale=0.4, level=H, logo=assets/arxiv.png]{https://arxiv.org/abs/1503.03585} | |
| % also works without logo | |
| \qrcodeWithLogo[width=5cm]{https://arxiv.org/abs/2512.10858} | |
| \end{document} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| \NeedsTeXFormat{LaTeX2e} | |
| \ProvidesPackage{qrcodewithlogo}[2026/04/17 v1.0 QR codes with centered logo overlay] | |
| \RequirePackage{tikz} | |
| \RequirePackage{graphicx} | |
| \RequirePackage{qrcode} | |
| \RequirePackage{xstring} | |
| \usetikzlibrary{calc} | |
| \makeatletter | |
| \def\qrcwl@defcap#1#2#3#4#5{% | |
| \expandafter\def\csname qrcwl@cap@#1@L\endcsname{#2}% | |
| \expandafter\def\csname qrcwl@cap@#1@M\endcsname{#3}% | |
| \expandafter\def\csname qrcwl@cap@#1@Q\endcsname{#4}% | |
| \expandafter\def\csname qrcwl@cap@#1@H\endcsname{#5}% | |
| } | |
| \qrcwl@defcap{1}{17}{14}{11}{7} | |
| \qrcwl@defcap{2}{32}{26}{20}{14} | |
| \qrcwl@defcap{3}{53}{42}{32}{24} | |
| \qrcwl@defcap{4}{78}{62}{46}{34} | |
| \qrcwl@defcap{5}{106}{84}{60}{44} | |
| \qrcwl@defcap{6}{134}{106}{74}{58} | |
| \qrcwl@defcap{7}{154}{122}{86}{64} | |
| \qrcwl@defcap{8}{192}{152}{108}{84} | |
| \qrcwl@defcap{9}{230}{180}{130}{98} | |
| \qrcwl@defcap{10}{271}{213}{151}{119} | |
| \qrcwl@defcap{11}{321}{251}{177}{137} | |
| \qrcwl@defcap{12}{367}{287}{203}{155} | |
| \qrcwl@defcap{13}{425}{331}{241}{177} | |
| \qrcwl@defcap{14}{458}{362}{258}{194} | |
| \qrcwl@defcap{15}{520}{412}{292}{220} | |
| \qrcwl@defcap{16}{586}{450}{322}{250} | |
| \qrcwl@defcap{17}{644}{504}{364}{280} | |
| \qrcwl@defcap{18}{718}{560}{394}{310} | |
| \qrcwl@defcap{19}{792}{624}{442}{338} | |
| \qrcwl@defcap{20}{858}{666}{482}{382} | |
| \qrcwl@defcap{21}{929}{711}{509}{403} | |
| \qrcwl@defcap{22}{1003}{779}{565}{439} | |
| \qrcwl@defcap{23}{1091}{857}{611}{461} | |
| \qrcwl@defcap{24}{1171}{911}{661}{511} | |
| \qrcwl@defcap{25}{1273}{997}{715}{535} | |
| \qrcwl@defcap{26}{1367}{1059}{751}{593} | |
| \qrcwl@defcap{27}{1465}{1125}{805}{625} | |
| \qrcwl@defcap{28}{1528}{1190}{868}{658} | |
| \qrcwl@defcap{29}{1628}{1264}{908}{698} | |
| \qrcwl@defcap{30}{1732}{1370}{982}{742} | |
| \qrcwl@defcap{31}{1840}{1452}{1030}{790} | |
| \qrcwl@defcap{32}{1952}{1538}{1112}{842} | |
| \qrcwl@defcap{33}{2068}{1628}{1168}{898} | |
| \qrcwl@defcap{34}{2188}{1722}{1228}{958} | |
| \qrcwl@defcap{35}{2303}{1809}{1283}{983} | |
| \qrcwl@defcap{36}{2431}{1911}{1351}{1051} | |
| \qrcwl@defcap{37}{2563}{1989}{1423}{1093} | |
| \qrcwl@defcap{38}{2699}{2099}{1499}{1139} | |
| \qrcwl@defcap{39}{2809}{2213}{1579}{1219} | |
| \qrcwl@defcap{40}{2953}{2331}{1663}{1273} | |
| \newcount\qrcwl@vcount | |
| \newcommand{\qrcwl@pickversion}[2]{% | |
| \qrcwl@vcount=1\relax | |
| \def\qrcwl@found{0}% | |
| \loop | |
| \ifnum\qrcwl@found=0 | |
| \edef\qrcwl@curcap{\csname qrcwl@cap@\the\qrcwl@vcount @#2\endcsname}% | |
| \ifnum\qrcwl@curcap<#1\relax\else | |
| \edef\qrcwl@version{\the\qrcwl@vcount}% | |
| \def\qrcwl@found{1}% | |
| \fi | |
| \fi | |
| \advance\qrcwl@vcount by 1\relax | |
| \ifnum\qrcwl@vcount<41 | |
| \repeat | |
| \ifnum\qrcwl@found=0 | |
| \PackageWarning{qrcodewithlogo}{% | |
| Content (#1 bytes) exceeds V40 at level #2; falling back to V40}% | |
| \def\qrcwl@version{40}% | |
| \fi | |
| } | |
| \pgfkeys{ | |
| /qrcwl/.is family, /qrcwl/.cd, | |
| width/.store in = \qrcwl@width, | |
| logo/.store in = \qrcwl@logo, | |
| level/.store in = \qrcwl@level, | |
| scale/.store in = \qrcwl@scale, | |
| padding/.store in = \qrcwl@padding, | |
| version/.store in = \qrcwl@version, | |
| width = 3cm, % physical size of the QR code | |
| logo = , % (optional) path to the logo to be added in the center. | |
| level = Q, % error correction level. set to: L, M, Q, H | |
| scale = 0.275, % (target) size of the logo. the actual size is quantized to the QR code grid, which depends on its version. | |
| padding = 0.175, % relative gap; logo = backdrop / (1 + padding) | |
| version = 0, % used for sizing the logo; does not affect the version of the actual QR code (version = how many pixels the QR code has). Set to 0 for best-effort version detection, manually set this to the correct version in case that fails. | |
| } | |
| \newlength{\qrcwl@qrlen} | |
| \newlength{\qrcwl@logolen} | |
| \newcommand{\qrcodeWithLogo}[2][]{% | |
| \begingroup | |
| \pgfkeys{/qrcwl/.cd, #1}% | |
| \ifnum\qrcwl@version=0\relax | |
| \StrLen{#2}[\qrcwl@bytes]% | |
| \qrcwl@pickversion{\qrcwl@bytes}{\qrcwl@level}% | |
| \fi | |
| \setlength{\qrcwl@qrlen}{\qrcwl@width}% | |
| \begin{tikzpicture} | |
| \node[inner sep=0] (qr) | |
| {\qrcode[height=\qrcwl@qrlen, | |
| level=\qrcwl@level, | |
| version=\qrcwl@version]{#2}}; | |
| \ifx\qrcwl@logo\@empty\else | |
| \pgfmathtruncatemacro{\qrcwl@N}{4*\qrcwl@version + 17}% | |
| % k = smallest odd integer >= (1 + padding) * scale * N | |
| \pgfmathtruncatemacro{\qrcwl@kceil}{% | |
| ceil((1 + \qrcwl@padding) * \qrcwl@scale * \qrcwl@N)}% | |
| \pgfmathtruncatemacro{\qrcwl@k}{% | |
| \qrcwl@kceil + mod(\qrcwl@kceil + \qrcwl@N, 2)}% | |
| % Backdrop corner offset with 0.001 bleed outward. | |
| \pgfmathsetmacro{\qrcwl@off}{% | |
| (\qrcwl@N - \qrcwl@k) / (2*\qrcwl@N) - 0.001}% | |
| % Logo scaled to fit the quantized crop, with relative padding. | |
| \pgfmathsetmacro{\qrcwl@logofrac}{% | |
| \qrcwl@k / (\qrcwl@N * (1 + \qrcwl@padding))}% | |
| \setlength{\qrcwl@logolen}{\qrcwl@logofrac\qrcwl@qrlen}% | |
| \fill[white] | |
| ($(qr.south west)!\qrcwl@off!(qr.north east)$) | |
| rectangle | |
| ($(qr.north east)!\qrcwl@off!(qr.south west)$); | |
| \node at (qr.center) | |
| {\includegraphics[width=\qrcwl@logolen, | |
| height=\qrcwl@logolen, | |
| keepaspectratio]{\qrcwl@logo}}; | |
| \fi | |
| \end{tikzpicture}% | |
| \endgroup | |
| } | |
| \makeatother | |
| \endinput |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment