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
+62 -25
View File
@@ -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