diff --git a/README.md b/README.md index e45244e..1a5f327 100644 --- a/README.md +++ b/README.md @@ -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) - `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**. -- `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. -- `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. +- `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 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 @@ -156,6 +160,8 @@ See this example_ - `\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) - `\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 @@ -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:** ```latex -\documentclass[photoinqr,qreclevel=H,qrlogoscale=25]{businesscard-qrcode} +\documentclass[photoinqr,qreclevel=H,qrlogoscale=0.25]{businesscard-qrcode} \photo{photo.jpg} ``` **Important:** When using `photoinqr=true`: - Always use `qreclevel=H` (highest error correction ~30%) for reliable scanning - Test QR code scannability with multiple apps before printing -- Default `qrlogoscale=25` (25% width = 6.25% area) is recommended for Level H -- If scanning fails, reduce to `qrlogoscale=20` or `qrlogoscale=15` +- Default `qrlogoscale=0.25` (25% width = 6.25% area) is recommended for Level H +- If scanning fails, reduce to `qrlogoscale=0.2` or `qrlogoscale=0.15` - 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 ========= diff --git a/businesscard-qrcode.cls b/businesscard-qrcode.cls index c1957b2..496e16a 100644 --- a/businesscard-qrcode.cls +++ b/businesscard-qrcode.cls @@ -21,8 +21,12 @@ \DeclareStringOption[0.50]{textwidth} \DeclareStringOption[0.40]{qrwidth} \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[2]{qrlogoborder} % white padding around photo in QR as percentage of QR width (0-100), default 2% +\DeclareStringOption[0.25]{qrlogoscale} % photo size in QR code as fraction of QR width (1.0 = 100%), default 0.25 +\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} \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 @@ -75,6 +79,7 @@ \RequirePackage{wrapfig} \RequirePackage{graphicx} % needed for optional photo \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{pbox} \RequirePackage{varwidth} @@ -127,6 +132,7 @@ \registerData{pgpurl} \registerData{pgpfingerprint} \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{ %\frame { \begin{minipage}[c][\heightscale][c]{\imagepercents\textwidth} - \ifBCQ@photoinqr - % QR code with photo overlay in center - \ifcsdef{Xphoto}{% - \begin{tikzpicture} - \node[inner sep=0pt] (qr) {\qrcode[level=\BCQ@qreclevel,version=0,height=\textwidth]{\vcard}}; - % Photo with transparent background preserved (no fill), padding still applied - % Convert percentage values to fractions for calculations - \node[inner sep=\fpeval{\BCQ@qrlogoborder/100}\textwidth] at (qr.center) {% - \includegraphics[width=\fpeval{\BCQ@qrlogoscale/100}\textwidth]{\Xphoto}% - }; - \end{tikzpicture}% - }{% - % No photo defined, just show QR code - \qrcode[level=\BCQ@qreclevel,version=0,height=\textwidth]{\vcard}% - } - \else - % Standard QR code without overlay - \qrcode[level=\BCQ@qreclevel,version=0,height=\textwidth]{\vcard} - \fi + \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 + % QR code with photo overlay in center + \ifcsdef{Xphoto}{% + \begin{tikzpicture} + \node[inner sep=0pt] (qr2) {\qrcode[level=\BCQ@qreclevel,version=0,height=\textwidth]{\vcard}}; + % Photo with transparent background preserved (no fill), padding still applied + % qrlogoscale and qrlogoborder are now fractions (1.0 = 100%) + \node[inner sep=\BCQ@qrlogoborder\textwidth] at (qr2.center) {% + \includegraphics[width=\BCQ@qrlogoscale\textwidth]{\Xphoto}% + }; + \end{tikzpicture}% + }{% + % No photo defined, just show QR code + \qrcode[level=\BCQ@qreclevel,version=0,height=\textwidth]{\vcard}% + }% + \else + % Standard QR code without overlay + \qrcode[level=\BCQ@qreclevel,version=0,height=\textwidth]{\vcard}% + \fi + }; + \end{tikzpicture} \end{minipage} } } @@ -319,9 +332,10 @@ END:VCARD\BCQ@nl} {\bfseries\usebox{\BCQ@namebox}}% \else % 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}[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} \hfill \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 -\newcommand\drawcard{ +% drawcardcontent - assemble all blocks (name, text, qr, pgp) +\newcommand\drawcardcontent{ \ifBCQ@rightalign\begin{flushright}\fi \insertname \noindent\makebox[\linewidth]{\rule{\paperwidth}{0.4pt}} % horizontal line @@ -362,6 +376,29 @@ END:VCARD\BCQ@nl} \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 diff --git a/examples/background-color-example.pdf b/examples/background-color-example.pdf new file mode 100644 index 0000000..855f1e2 Binary files /dev/null and b/examples/background-color-example.pdf differ diff --git a/examples/background-color-example.tex b/examples/background-color-example.tex new file mode 100644 index 0000000..c1157cb --- /dev/null +++ b/examples/background-color-example.tex @@ -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} diff --git a/examples/background-image-example.pdf b/examples/background-image-example.pdf new file mode 100644 index 0000000..9ae4993 Binary files /dev/null and b/examples/background-image-example.pdf differ diff --git a/examples/background-image-example.tex b/examples/background-image-example.tex new file mode 100644 index 0000000..a9de260 --- /dev/null +++ b/examples/background-image-example.tex @@ -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} diff --git a/examples/background.png b/examples/background.png new file mode 100644 index 0000000..33b2135 Binary files /dev/null and b/examples/background.png differ diff --git a/examples/photo-in-qr-example.pdf b/examples/photo-in-qr-example.pdf index 04867df..d21dd68 100644 Binary files a/examples/photo-in-qr-example.pdf and b/examples/photo-in-qr-example.pdf differ diff --git a/examples/photo-in-qr-example.tex b/examples/photo-in-qr-example.tex index dbb3f48..3ff7e94 100644 --- a/examples/photo-in-qr-example.tex +++ b/examples/photo-in-qr-example.tex @@ -1,5 +1,5 @@ % !TeX program = xelatex -\documentclass[photoinqr,qrlogoscale=40,qreclevel=H]{businesscard-qrcode} +\documentclass[photoinqr,qrlogoscale=0.4,qreclevel=H]{businesscard-qrcode} \type{home} \givennames{Lisa\ Linda} @@ -12,7 +12,7 @@ \phone{+1 234 567 8900} \email{ldoe@example.com} \homepage{example.com} -\photo{photo.png} +%\photo{photo.png} % uncomment if photo.png exists \begin{document} \drawcard diff --git a/examples/photo-large-example.pdf b/examples/photo-large-example.pdf new file mode 100644 index 0000000..dd9114e Binary files /dev/null and b/examples/photo-large-example.pdf differ diff --git a/examples/photo-large-example.tex b/examples/photo-large-example.tex new file mode 100644 index 0000000..c5ef0cb --- /dev/null +++ b/examples/photo-large-example.tex @@ -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} diff --git a/examples/special-papersize.pdf b/examples/special-papersize.pdf index 8585349..3cd5990 100644 Binary files a/examples/special-papersize.pdf and b/examples/special-papersize.pdf differ diff --git a/examples/test-country-short.pdf b/examples/test-country-short.pdf index 9dc35af..72f915d 100644 Binary files a/examples/test-country-short.pdf and b/examples/test-country-short.pdf differ