Problem 1:
You use \pgfmathsetlengthmacro\LeftWidth{width("\ImageLeft")} outside the \foreach-loop. But with \pgfmathsetlengthmacro\LeftWidth{width("\ImageLeft")} the macro \ImageLeft is used which in turn uses \UseImageLeft which in turn uses \i while \i is defined to yield the number of an image only within the \foreach-loop.
Problem 2:
You have \pgfmathsetlengthmacro\LeftWidth{width("\ImageLeft")} which is of pattern
\pgfmathsetlengthmacro\LeftWidth{⟨expression⟩}
with
⟨expression⟩ = width("\ImageLeft")
, while
width("\ImageLeft")
in turn is of pattern
width(⟨expression⟩)
with
⟨expression⟩ = "\ImageLeft".
This means that \ImageLeft is evaluated as part of an ⟨expression⟩ twice:
The first time when the ⟨expression⟩ forming the argument of \pgfmathsetlengthmacro\LeftWidth is evaluated.
The second time when the ⟨expression⟩ forming the argument of width(...) is evaluated.
pgfmanual.pdf, section "95.2 Syntax for Mathematical Expressions: Operators" says in the explanation of the "x"-operator:
... However, as every expression is expanded with \edef before it is parsed, macros (e.g., font commands like \tt or \Huge) may need to be “protected” from this expansion (e.g., \noexpand\Huge). Ideally, you should avoid such macros anyway. Obviously, these operators should be used with great care as further calculations are unlikely to be possible with the result.
This information is not related only to the "x"-operator. This information is relevant whenever it comes to evaluating an ⟨expression⟩. It is a general rule which is applied during the evaluation of every ⟨expression⟩.
Therefore I think it is not a good idea to convey this information only while explaining a special operator.
Be that as it may:
Putting the pieces of information together, you find that \ImageLeft is evaluated via \edef twice. As the expansion-chain is \ImageLeft→\UseImageLeft→...\includegraphics..., this implies that two times attempts at evaluating \includegraphics via \edef take place.
But in case you don't use the one of the most recent TeX-distributions \includegraphics does not work out in \edef-expansion-contexts. This is because in older TeX-distributions \includegraphics is not "protected"—"protected" refers to a LaTeX-internal mechanism for preventing expansion of commands in situations where that expansion would not work out—and "relies on" performing temporary assignments, e.g., in terms of \def, while such assignments do not get carried out while \edef-evaluation is in progress. \edef triggers expansion of expandable tokens while \def is an unexpandable primitive.
So if not using one of the most recent TeX-distributions you need to take precautionary measures for preventing expanding/evaluating the command \ImageLeft (and thus also preventing expansion/evaluation of \includegraphics) with each of these \edef-evaluations. (On most recent TeX-distributions these precautionary measures neither are a nuisance nor are needed.)
You can prevent expansion/evaluation by prefixing \ImageLeft with \noexpand\noexpand\noexpand.
The first \edef-evaluation, applied on <code>\noexpand\noexpand\noexpand\ImageLeft</code>,
yields
<code>\noexpand\ImageLeft</code>.
The second \edef-evaluation will be applied on that, which in turn yields:
<code>\ImageLeft</code>.
Problem 3:
egreg pointed out that \i is already defined in LaTeX and that you probably don't want to override that definition. Therefore in the example below I used \NiceForEachElement instead of \i.
\documentclass[]{article}
\usepackage[most]{tcolorbox}
\newcommand\UseImageLeft[1]{%
\IfFileExists{#1\NiceForEachElement.jpg}%
{\includegraphics[scale=0.2]{#1\NiceForEachElement.jpg}}%
{\includegraphics[scale=0.2]{example-image.jpg}}%
}
\def\ImageLeft{\UseImageLeft{Image-}}
% Problem ===================================
%\pgfmathsetlengthmacro\LeftWidth{width("\ImageLeft")}
% =======================================
\begin{document}
\foreach \NiceForEachElement in {1,...,2}{%
\pgfmathsetlengthmacro\LeftWidth{width("\noexpand\noexpand\noexpand\ImageLeft")}%
%Activate the following line in case you wish to see on screen/console what the definition of \LeftWidth looks like now:
%\show\LeftWidth
% On any page (begin)
\begin{tcolorbox}[]%
\begin{tcbitemize}[]%
\tcbitem[] \ImageLeft
\end{tcbitemize}%
\end{tcolorbox}%
% On any page (end)
\newpage
}
\end{document}
If you wish to be able to use \ImageLeft outside the loop too, then define \ImageLeft etc to process an argument instead of processing \i/\NiceForEachElement.
Inside the loop you can pass \i/\NiceForEachElement as argument.
Outside the loop you can pass the number of the image as argument directly.
\documentclass[]{article}
\usepackage[most]{tcolorbox}
% Define the command \NiceForEachElement to ensure error-message in case it is already defined.
% This way you can ensure to a certain degree that using \niceelement as Foreach-variable
% does not override something that alerady exists.
\newcommand\NiceForEachElement{}%
\newcommand\UseImageLeft[2]{%
% #1 preceding phrase "image-"
% #2 number of image
\IfFileExists{#1#2.jpg}%
{\includegraphics[scale=0.2]{#1#2.jpg}}%
{\includegraphics[scale=0.2]{example-image.jpg}}%
}
\newcommand*\ImageLeft[1]{\UseImageLeft{Image-}{#1}}
% Problem ===================================
%\pgfmathsetlengthmacro\LeftWidth{width("\ImageLeft")}
% =======================================
\begin{document}
% outside the loop the width of Image-7.jpg or example-image.jpg:
\pgfmathsetlengthmacro\LeftWidth{width("\noexpand\noexpand\noexpand\ImageLeft{7}")}%
%Activate the following line in case you wish to see on screen/console what the definition of \LeftWidth looks like now:
%\show\LeftWidth
% inside the loop:
\foreach \NiceForEachElement in {1,...,2}{%
\pgfmathsetlengthmacro\LeftWidth{width("\noexpand\noexpand\noexpand\ImageLeft{\NiceForEachElement}")}%
%Activate the following line in case you wish to see on screen/console what the definition of \LeftWidth looks like now:
%\show\LeftWidth
% On any page (begin)
\begin{tcolorbox}[]%
\begin{tcbitemize}[]%
\tcbitem[] \ImageLeft{\NiceForEachElement}%
\end{tcbitemize}%
\end{tcolorbox}%
% On any page (end)
\newpage
}
\end{document}
\iin your command\UseImageLeftwhich has no meaning (or not the meaning you expect) outside the \foreach loop. – Ulrike Fischer Sep 06 '20 at 13:24\IfFileExists{#1\i.jpg}%. And then you are using this outside the loop in\pgfmathsetlengthmacro. Which meaning has \i then in your opinion? – Ulrike Fischer Sep 06 '20 at 13:33\iis to loop all of the pictures from 1 to 2 in this case (\foreach \i in {1,...,2}{) Please note all of the pictures are equally sized. I don't understand what exactly\pgfmathsetlengthmacrois or why I can't use it here. But I need it in the larger version of this document ... – O0123 Sep 06 '20 at 13:37\pgfmathsetlengthmacroand so\ioutside the loop. – Ulrike Fischer Sep 06 '20 at 13:38\pgfmathsetlengthmacrooutside of the loop? And what's the purpose of executing it in the loop, given that\LeftWidthis used nowhere we can see? – egreg Sep 06 '20 at 14:19\ioutside the\foreach-loop (the only place where\iis defined) is not the only problem. Another problem is\edef-evaluation pf pgfmath-expressions which takes place twice, implying two attempts at expanding\includegraphicswithin\edef-expansion-contexts while\includegraphicsis not fully expandable but also yields non-expandable tokens like\deffor defining temporary macros. – Ulrich Diez Sep 06 '20 at 14:36