added background with opacity to QR-Code and card; bug in card opacity

This commit is contained in:
Marc Wäckerlin
2025-11-09 09:08:09 +01:00
parent 407c7eed2d
commit 2c2fbdbe9e
13 changed files with 150 additions and 32 deletions
+30 -5
View File
@@ -97,8 +97,12 @@ Layout options are set as options to the `\documentclass`, e.g.:
- `countryformat=`: how to format the country in address. Values: `auto` (default: inline with mdash if <4 chars and city/zip exists), `inline` (always inline with mdash), `below` (always separate line) - `countryformat=`: how to format the country in address. Values: `auto` (default: inline with mdash if <4 chars and city/zip exists), `inline` (always inline with mdash), `below` (always separate line)
- `qreclevel=`: QR error correction level `L` (~7%), `M` (~15%), `Q` (~25%), or `H` (~30%), default: `Q`. Use `H` when `photoinqr=true`. - `qreclevel=`: QR error correction level `L` (~7%), `M` (~15%), `Q` (~25%), or `H` (~30%), default: `Q`. Use `H` when `photoinqr=true`.
- `photoinqr` or `nophotoinqr`: place photo in the center of the QR code (`photoinqr`) instead of next to the name, default: `nophotoinqr`. **Requires `qreclevel=H` for reliable scanning**. - `photoinqr` or `nophotoinqr`: place photo in the center of the QR code (`photoinqr`) instead of next to the name, default: `nophotoinqr`. **Requires `qreclevel=H` for reliable scanning**.
- `qrlogoscale=`: photo size in QR code as percentage of QR width (0-100), default: `25` (25% width = 6.25% area). Recommended values: Level H: 25-30%, Level Q: 20%, Level M: 15%, Level L: 10%. Higher values may reduce scannability. - `qrlogoscale=`: photo size in QR code as fraction of QR width (1.0 = 100%), default: `0.25` (25% width). Recommended values: Level H: 0.25-0.3, Level Q: 0.2, Level M: 0.15, Level L: 0.1. Higher values may reduce scannability.
- `qrlogoborder=`: transparent padding around photo in QR code as percentage of QR width (0-100), default: `2` (2%). Adds space between photo and QR modules. - `qrlogoborder=`: transparent padding around photo in QR code as fraction of QR width (1.0 = 100%), default: `0.02` (2%). Adds space between photo and QR modules.
- `photoscale=`: scale factor for photo next to name (1.0 = 100% of name height), default: `1.0`. Use values like `2.0` or `2.5` for larger photos.
- `bgscale=`: background image scale factor (1.0 = 100% of card height), default: `1.0`. Use values like `1.5` or `2.0` for zoomed/cropped backgrounds. Only affects images, not colors.
- `bgopacity=`: background image opacity/transparency (1.0 = 100% visible, 0.0 = invisible), default: `1.0`. Use lower values like `0.2` or `0.3` to fade the background so text remains readable. Only affects images, not colors.
- `qrbgopacity=`: QR code background opacity (1.0 = solid white, 0.0 = transparent), default: `1.0`. White background behind QR code ensures scannability over background images. Use `0.0` for no background or lower values like `0.8` for semi-transparent.
Data Definitions Data Definitions
@@ -156,6 +160,8 @@ See this example_
- `\google`: your account name on [google+] — only the name of the account, the url is prepended automatically - `\google`: your account name on [google+] — only the name of the account, the url is prepended automatically
- `\pgpurl`: the full url to your pgp public key (only added to the QR-Code, not shown in the text) - `\pgpurl`: the full url to your pgp public key (only added to the QR-Code, not shown in the text)
- `\pgpfingerprint`: the fingerprint of your pgp public key - `\pgpfingerprint`: the fingerprint of your pgp public key
- `\photo`: path to photo file (PNG, JPG, etc.) for display next to name or in QR code (if `photoinqr` option is set)
- `\background`: path to background image file or color name (e.g., `yellow!20`, `blue!10`). If file exists, it's used as image; otherwise treated as color.
Print the Card Print the Card
@@ -221,17 +227,36 @@ You can add an optional photo that appears next to the name or in the center of
**Photo in QR code center:** **Photo in QR code center:**
```latex ```latex
\documentclass[photoinqr,qreclevel=H,qrlogoscale=25]{businesscard-qrcode} \documentclass[photoinqr,qreclevel=H,qrlogoscale=0.25]{businesscard-qrcode}
\photo{photo.jpg} \photo{photo.jpg}
``` ```
**Important:** When using `photoinqr=true`: **Important:** When using `photoinqr=true`:
- Always use `qreclevel=H` (highest error correction ~30%) for reliable scanning - Always use `qreclevel=H` (highest error correction ~30%) for reliable scanning
- Test QR code scannability with multiple apps before printing - Test QR code scannability with multiple apps before printing
- Default `qrlogoscale=25` (25% width = 6.25% area) is recommended for Level H - Default `qrlogoscale=0.25` (25% width = 6.25% area) is recommended for Level H
- If scanning fails, reduce to `qrlogoscale=20` or `qrlogoscale=15` - If scanning fails, reduce to `qrlogoscale=0.2` or `qrlogoscale=0.15`
- PNG transparency is preserved - use images with transparent backgrounds for best results - PNG transparency is preserved - use images with transparent backgrounds for best results
**Large photo next to name:**
```latex
\documentclass[photoscale=2.5]{businesscard-qrcode}
\photo{photo.jpg}
```
**Background color:**
```latex
\documentclass{businesscard-qrcode}
\background{yellow!20}
```
**Background image:**
```latex
\documentclass[bgscale=1.5,bgopacity=0.3,qrbgopacity=1.0]{businesscard-qrcode}
\background{photo.jpg}
```
Note: Use `bgopacity` to fade the background (e.g., `0.2` or `0.3`) so text remains readable. The QR code has a white background by default (`qrbgopacity=1.0`) to ensure scannability.
Need More Need More
========= =========
+49 -12
View File
@@ -21,8 +21,12 @@
\DeclareStringOption[0.50]{textwidth} \DeclareStringOption[0.50]{textwidth}
\DeclareStringOption[0.40]{qrwidth} \DeclareStringOption[0.40]{qrwidth}
\DeclareStringOption[Q]{qreclevel} % QR code error correction level (L,M,Q,H) default Q \DeclareStringOption[Q]{qreclevel} % QR code error correction level (L,M,Q,H) default Q
\DeclareStringOption[25]{qrlogoscale} % photo size in QR code as percentage of QR width (0-100), default 25% \DeclareStringOption[0.25]{qrlogoscale} % photo size in QR code as fraction of QR width (1.0 = 100%), default 0.25
\DeclareStringOption[2]{qrlogoborder} % white padding around photo in QR as percentage of QR width (0-100), default 2% \DeclareStringOption[0.02]{qrlogoborder} % white padding around photo in QR as fraction of QR width (1.0 = 100%), default 0.02
\DeclareStringOption[1.0]{photoscale} % scale factor for photo next to name (1.0 = 100% name height), default 1.0
\DeclareStringOption[1.0]{bgscale} % background image scale (1.0 = 100% card height), default 1.0
\DeclareStringOption[1.0]{bgopacity} % background image opacity (1.0 = 100% visible, 0.0 = invisible), default 1.0
\DeclareStringOption[1.0]{qrbgopacity} % QR code background opacity (1.0 = white solid, 0.0 = transparent), default 1.0
\DeclareStringOption[de]{lang} \DeclareStringOption[de]{lang}
\DeclareBoolOption[false]{ioscrlf} % use CRLF line endings in vCard (iOS compatibility); default off to avoid pdfTeX issues \DeclareBoolOption[false]{ioscrlf} % use CRLF line endings in vCard (iOS compatibility); default off to avoid pdfTeX issues
\DeclareBoolOption[false]{photoinqr} % if true: photo goes in QR center; if false (default): photo next to name \DeclareBoolOption[false]{photoinqr} % if true: photo goes in QR center; if false (default): photo next to name
@@ -75,6 +79,7 @@
\RequirePackage{wrapfig} \RequirePackage{wrapfig}
\RequirePackage{graphicx} % needed for optional photo \RequirePackage{graphicx} % needed for optional photo
\RequirePackage{tikz} % needed for logo overlay in QR code \RequirePackage{tikz} % needed for logo overlay in QR code
\RequirePackage{eso-pic} % needed for background images without layout impact
\RequirePackage[\content,top=\padding,left=\padding,right=\padding,bottom=\padding]{geometry} \RequirePackage[\content,top=\padding,left=\padding,right=\padding,bottom=\padding]{geometry}
%\RequirePackage{pbox} %\RequirePackage{pbox}
\RequirePackage{varwidth} \RequirePackage{varwidth}
@@ -127,6 +132,7 @@
\registerData{pgpurl} \registerData{pgpurl}
\registerData{pgpfingerprint} \registerData{pgpfingerprint}
\registerData{photo} % path to photo file for display next to name \registerData{photo} % path to photo file for display next to name
\registerData{background} % path to background image file or color name
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -279,30 +285,37 @@ END:VCARD\BCQ@nl}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% insertqrcode - insert the qr-code % insertqrcode - insert the qr-code with optional white background
\newcommand\insertqrcode{ \newcommand\insertqrcode{
%\frame %\frame
{ {
\begin{minipage}[c][\heightscale][c]{\imagepercents\textwidth} \begin{minipage}[c][\heightscale][c]{\imagepercents\textwidth}
\begin{tikzpicture}
% White background behind QR code (for readability over background images)
\node[fill=white, opacity=\fpeval{\BCQ@qrbgopacity}, inner sep=0pt, outer sep=2mm, minimum size=\textwidth] (bg) at (0,0) {};
% QR code on top
\node[inner sep=0pt, outer sep=0pt] (qr) at (0,0) {%
\ifBCQ@photoinqr \ifBCQ@photoinqr
% QR code with photo overlay in center % QR code with photo overlay in center
\ifcsdef{Xphoto}{% \ifcsdef{Xphoto}{%
\begin{tikzpicture} \begin{tikzpicture}
\node[inner sep=0pt] (qr) {\qrcode[level=\BCQ@qreclevel,version=0,height=\textwidth]{\vcard}}; \node[inner sep=0pt] (qr2) {\qrcode[level=\BCQ@qreclevel,version=0,height=\textwidth]{\vcard}};
% Photo with transparent background preserved (no fill), padding still applied % Photo with transparent background preserved (no fill), padding still applied
% Convert percentage values to fractions for calculations % qrlogoscale and qrlogoborder are now fractions (1.0 = 100%)
\node[inner sep=\fpeval{\BCQ@qrlogoborder/100}\textwidth] at (qr.center) {% \node[inner sep=\BCQ@qrlogoborder\textwidth] at (qr2.center) {%
\includegraphics[width=\fpeval{\BCQ@qrlogoscale/100}\textwidth]{\Xphoto}% \includegraphics[width=\BCQ@qrlogoscale\textwidth]{\Xphoto}%
}; };
\end{tikzpicture}% \end{tikzpicture}%
}{% }{%
% No photo defined, just show QR code % No photo defined, just show QR code
\qrcode[level=\BCQ@qreclevel,version=0,height=\textwidth]{\vcard}% \qrcode[level=\BCQ@qreclevel,version=0,height=\textwidth]{\vcard}%
} }%
\else \else
% Standard QR code without overlay % Standard QR code without overlay
\qrcode[level=\BCQ@qreclevel,version=0,height=\textwidth]{\vcard} \qrcode[level=\BCQ@qreclevel,version=0,height=\textwidth]{\vcard}%
\fi \fi
};
\end{tikzpicture}
\end{minipage} \end{minipage}
} }
} }
@@ -319,9 +332,10 @@ END:VCARD\BCQ@nl}
{\bfseries\usebox{\BCQ@namebox}}% {\bfseries\usebox{\BCQ@namebox}}%
\else \else
% Photo next to name: two-column layout (photo | name) % Photo next to name: two-column layout (photo | name)
% photoscale: 1.0 = 100% name height (default), 2.0 = 200%, etc.
\begin{minipage}{\textwidth} \begin{minipage}{\textwidth}
\begin{minipage}[c]{0.30\textwidth}% photo column (increased from 0.22) \begin{minipage}[c]{0.30\textwidth}% photo column (increased from 0.22)
\includegraphics[height=\dimexpr\ht\BCQ@namebox+\dp\BCQ@namebox\relax]{\Xphoto}% scaled to name height \includegraphics[height=\fpeval{\BCQ@photoscale}\dimexpr\ht\BCQ@namebox+\dp\BCQ@namebox\relax]{\Xphoto}% scaled to photoscale * name height
\end{minipage} \end{minipage}
\hfill \hfill
\begin{minipage}[c]{0.67\textwidth}% name column (adjusted from 0.75) \begin{minipage}[c]{0.67\textwidth}% name column (adjusted from 0.75)
@@ -336,8 +350,8 @@ END:VCARD\BCQ@nl}
} }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% drawcard - assemble all blocks into the visiting card % drawcardcontent - assemble all blocks (name, text, qr, pgp)
\newcommand\drawcard{ \newcommand\drawcardcontent{
\ifBCQ@rightalign\begin{flushright}\fi \ifBCQ@rightalign\begin{flushright}\fi
\insertname \insertname
\noindent\makebox[\linewidth]{\rule{\paperwidth}{0.4pt}} % horizontal line \noindent\makebox[\linewidth]{\rule{\paperwidth}{0.4pt}} % horizontal line
@@ -362,6 +376,29 @@ END:VCARD\BCQ@nl}
\ifBCQ@rightalign\end{flushright}\fi \ifBCQ@rightalign\end{flushright}\fi
} }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% drawcard - main card with optional background
\newcommand\drawcard{
% Handle background
\ifcsdef{Xbackground}{%
\IfFileExists{\Xbackground}{%
% It's an image file: add to background using eso-pic (no layout impact)
\AddToShipoutPictureBG*{%
\AtPageCenter{%
\tikz[overlay]{\node[opacity=\fpeval{\BCQ@bgopacity}, inner sep=0pt] at (0,0) {%
\includegraphics[height=\fpeval{\BCQ@bgscale}\paperheight]{\Xbackground}%
};}%
}%
}%
}{%
% Not a file: treat as color
\pagecolor{\Xbackground}%
}%
}{}%
% Draw card content
\drawcardcontent
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% cut / crop marks % cut / crop marks
Binary file not shown.
+18
View File
@@ -0,0 +1,18 @@
% !TeX program = xelatex
\documentclass{businesscard-qrcode}
\type{home}
\givennames{Anna}
\familynames{Beispiel}
\street{Musterweg\ 7}
\city{Zürich}
\zip{8000}
\country{CH}
\phone{+41 44 123 45 67}
\email{anna@example.ch}
\homepage{example.ch}
\background{yellow!20}
\begin{document}
\drawcard
\end{document}
Binary file not shown.
+19
View File
@@ -0,0 +1,19 @@
% !TeX program = xelatex
\documentclass[bgscale=1.2,bgopacity=0.3,qrbgopacity=0.2
]{businesscard-qrcode}
\type{home}
\givennames{Petra}
\familynames{Test}
\street{Bildstrasse\ 99}
\city{Basel}
\zip{4000}
\country{CH}
\phone{+41 61 123 45 67}
\email{petra@example.ch}
\background{background.png}
\photo{photo.png}
\begin{document}
\drawcard
\end{document}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.
+2 -2
View File
@@ -1,5 +1,5 @@
% !TeX program = xelatex % !TeX program = xelatex
\documentclass[photoinqr,qrlogoscale=40,qreclevel=H]{businesscard-qrcode} \documentclass[photoinqr,qrlogoscale=0.4,qreclevel=H]{businesscard-qrcode}
\type{home} \type{home}
\givennames{Lisa\ Linda} \givennames{Lisa\ Linda}
@@ -12,7 +12,7 @@
\phone{+1 234 567 8900} \phone{+1 234 567 8900}
\email{ldoe@example.com} \email{ldoe@example.com}
\homepage{example.com} \homepage{example.com}
\photo{photo.png} %\photo{photo.png} % uncomment if photo.png exists
\begin{document} \begin{document}
\drawcard \drawcard
Binary file not shown.
+19
View File
@@ -0,0 +1,19 @@
% !TeX program = xelatex
% Note: Requires photo.png in same directory
\documentclass[photoscale=4]{businesscard-qrcode}
\type{home}
\givennames{Max}
\familynames{Muster}
\additionalnames{Big\ Photo\ Example}
\street{Beispielstrasse\ 42}
\city{Winterthur}
\zip{8400}
\country{CH}
\phone{+41 52 123 45 67}
\email{max@example.ch}
\photo{photo.png}
\begin{document}
\drawcard
\end{document}
Binary file not shown.
Binary file not shown.