20

Consider the following macro:

\newcommand{\sxfigure}[4]{
\includegraphics[width=#1*#3 cm, height=#2*#3 cm]{#4}
}

#1 and #2 is some value to determine the width and height of the figure, #3 is to control the zoom ratio. However, the above code doesn't work. Could someone provide a solution? I have tried the following, still not work. Could some point out the mistake?

\usepackage{pgf}
\newcommand{\sxmultiply}[2]{\pgfmathparse{#1*#2}\pgfmathresult}
\newcommand{\sxfigure}[5]{
\begin{figure}
\begin{center}
\includegraphics[width=$\sxmultiply{#3}{#5}$ cm, height=$\sxmultiply{#4}{#5}$ cm]{#1}
\end{center}
\caption{#2}
\end{figure}
}
18

The fp package is an easy-to-use arithmetic bundle that could help here:

enter image description here

\documentclass{article}
\usepackage{graphicx}% http://ctan.org/pkg/graphicx
\usepackage[nomessages]{fp}% http://ctan.org/pkg/fp
\newcommand{\sxfigure}[4]{%
  \FPeval\widthdim{#1*#3}% Calculate width dimension
  \FPeval\heightdim{#2*#3}% Calculate height dimension
  \includegraphics[width=\widthdim cm, height=\heightdim cm]{#4}%
}
\begin{document}
\sxfigure{1}{2}{1.5}{example-image-a} \quad
\sxfigure{1}{2}{1.7}{example-image-a}
\end{document}

However, I would opt for an improved syntax using a key-value approach for exactly the reason mentioned in the first paragraph of the xkeyval documentation:

Using keys in macro definition has the advantage that the 9 arguments maximum can easily be avoided and that it reduces confusion in the syntax of your macro when compared to using a lot of (optional) arguments. Compare for instance the following possible syntaxes of the macro \mybox which might for instance use its arguments to draw some box containing text

\mybox[5pt][20pt]{some text}[red][white][blue]
\mybox[text=red,background=white,frame=blue,left=5pt,right=20pt]{some text}

Notice that, to be able to specify the frame color in the first example, the other colors need to be specified as well. This is not necessary in the second example and these colors can get preset values. The same thing holds for the margins.

  • 1
    Thanks a lot! I wonder how can someone answer my question so quickly and so detailed. – Xing Shi Dec 21 '12 at 5:19
17

How about this, using the calc package

\newcommand{\sxfigure}[5]{%
    %   #1: width
    %   #2: height
    %   #3: zoom ratio
    %   #4: image
    %   #5: caption
\begin{figure}[!htb]
  \centering
  \includegraphics[width={#1*#3}, height={#2*#3}]{#4}
\caption{#5}
\end{figure}
}

screenshot

Note that I've used the mwe just for the images.

\documentclass{article}
\usepackage{graphicx}
\usepackage{calc}
\usepackage{mwe}

\newcommand{\sxfigure}[5]{%
    %   #1: width
    %   #2: height
    %   #3: zoom ratio
    %   #4: image
    %   #5: caption
\begin{figure}[!htb]
  \centering
  \includegraphics[width={#1*#3}, height={#2*#3}]{#4}
\caption{#5}
\end{figure}
}

\begin{document}

\sxfigure{1cm}{1cm}{2}{example-image-a}{my caption}

\sxfigure{1cm}{1cm}{4}{example-image-b}{my other caption}

\end{document}

Presumably you might want to \label these images too, so perhaps the following would be better

\newcommand{\sxfigure}[6]{%
    %   #1: width
    %   #2: height
    %   #3: zoom ratio
    %   #4: image
    %   #5: caption
    %   #6: label
\begin{figure}[!htb]
  \centering
  \includegraphics[width={#1*#3}, height={#2*#3}]{#4}
\caption{#5}
\label{#6}
\end{figure}
}

Note that I have used \centering as detailed in Should I use center or centering for figures and tables?

14

In your case, as you use #3 (and #5 in the second example) only to scale (the factor gets multiplied in both the width and the height key), you could just use:

\newcommand{\sxfigure}[4]{
    \includegraphics[width=#1, height=#2, scale=#3]{#4}
}

and use it like

\sxfigure{<width length>}{<height length>}{<scale factor>}{<file>}

The calc package can do simple multiplication, though using pgf enables all sorts of calculations, for example:

\sxfigure[angle=30]{
    image width = 1.1^3*3cm,
    image height = exp(3)*3cm
}{example-image}

Code

\documentclass{article}
\usepackage{graphicx}
\usepackage{pgf}
\newlength{\includewidth}
\newlength{\includeheight}
\pgfset{
    image width/.code={
        \pgfmathsetlength\includewidth{#1}
    },
    image height/.code={
        \pgfmathsetlength\includeheight{#1}
    },
}
\newcommand{\sxfigure}[3][]{% #1 = \includegraphics key-value stuff
                            % #2 = width and height assignments
                            % #3 = the file
    \pgfset{#2}%
    \includegraphics[width=\includewidth, height=\includeheight,#1]{#3}%
}%

\newcommand{\sxFigure}[4][]{% #1 = \includegraphics key-value stuff
                            % #2 = width
                            % #3 = height
                            % #4 = the file
    \pgfmathsetlength\includewidth{#2}%
    \pgfmathsetlength\includeheight{#3}%
    \includegraphics[width=\includewidth, height=\includeheight,#1]{#4}%
}%
\begin{document}
    \sxfigure[angle=30]{image width = 2.5*3cm, image height = 3*3cm}{example-image}

    \sxFigure[angle=30]{2.5*3cm}{3*3cm}{example-image}
\end{document}

Output

enter image description here

4

e-TeX's \dimexpr can be used:

\newcommand{\sxfigure}[4]{%
  \includegraphics[width=#3\dimexpr#1cm\relax, height=#3\dimexpr#2cm\relax]{#4}%
}
  • Oh no, anything but \dimexpr! – Mateus Araújo Apr 11 '17 at 11:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.