Como desenhar imagens incorporadas com \includeimage no TikZ com precisão de pixel?

Como desenhar imagens incorporadas com \includeimage no TikZ com precisão de pixel?

Quero desenhar em uma imagem que incorporei usando \includeimage:

\documentclass[tikz]{standalone}
\begin{document}
  \begin{tikzpicture}
    \node[anchor=south west,inner sep=0] (image) at (0,0) {\includegraphics{example-image}};
    \begin{scope}[x={(image.south east)},y={(image.north west)}]
      \draw[color=red] (0,0) rectangle (1,1);
    \end{scope}
  \end{tikzpicture}
\end{document}

Digamos que a imagem tenha um tamanho de 800x600 pixels. O problema aqui é que xey escala entre 0 e 1 em largura e altura. Eu gostaria de desenhar na imagem usando seus pixels como referência de coordenadas, de uma forma que

\draw[color=red] (0,0) rectangle (1,1);

pode ser substituído por

\draw[color=red] (0,0) rectangle (800,600);

Meu problema agora é dimensionar x e y no escopo. Achei que a seguinte afirmação funcionaria:

\begin{scope}[x={($(image.south east)/800$)},y={($(image.north west)/600$)}]

mas gera o seguinte erro:

Package tikz Error: + or - expected.

Procurei o capítulo 13.5 no manual TikZ/PGF, mas parece que não está funcionando com a instrução image.direction dessa forma.

Como posso dimensionar meu escopo da maneira certa?

Responder1

Editar:Na primeira versão da minha resposta - como apontou @Jake em seu comentário - não entendi o objetivo da pergunta ... então aqui está a solução corrigida, inspirada na resposta de @Jake:

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

\begin{document}
    \begin{figure}
\centering
\sbox0{\includegraphics[width=0.5\textwidth]{example-image}}%
\begin{tikzpicture}[x=\wd0/800, y=\ht0/600]
\node[anchor=south west,inner sep=0pt] at (0,0){\usebox0};
\draw[blue] (200,100) rectangle + (500,300);
\draw[red,thick] (0,0) rectangle + (800,600);
\end{tikzpicture}
    \end{figure}
\end{document}

A principal diferença é que em vez disso são utilizados novos comprimentos box0e possibilidades que oferecem. Com este código acima é um pouco mais curto, mas dá resultado igual:

insira a descrição da imagem aqui

Termo aditivo:Observe-se, como diz @jfbu em seu comentário: "... \box0às vezes é um pouco perigoso, especialmente se você atrasar o uso de \wd0or \ht0. É mais seguro fazer \newsavebox\myboxe usar \sbox\mybox, \wd\mybox... ". Portanto, embora até agora eu não tenha tido experiências ruins com o box0, é melhor ficar no lado seguro do uso do LateX e reescrever acima do MWE em:

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

\newsavebox\mybo

% for show only a figure
\usepackage[active,floats,tightpage]{preview}
\PreviewBorder{1em}

\begin{document}   
    \begin{figure}[h]
\centering
\sbox\mybox{\includegraphics[width=0.5\textwidth]{example-image}}%
\begin{tikzpicture}[x=\wd\mybox/800, y=\ht\mybox/600]
    \node[anchor=south west,inner sep=0pt] at (0,0) {\usebox\mybox};
    \draw[blue,very thin] (200,100) rectangle + (500,300);
    \draw[red,thick] (0,0) rectangle + (800,600);
\end{tikzpicture}
    \end{figure}
\end{document}

A solução de bots tem uma vantagem importante: a imagem é processada apenas (ao armazenar na caixa de salvamento e depois usada como \usebox\myboxou de acordo com o primeiro exemplo como \usebox0. Isso reduz potencialmente o tempo de compilação (como também afirmou @jfbu em seu comentário).

Responder2

Você está tentando a coisa certa, mas a sintaxe de cálculo de coordenadas é um pouco limitada: ela espera que o fator para esticar o vetor apareça no início da expressão. Então você poderia usar

\begin{scope}[x={($1/800*(image.south east)$)},y={($1/600*(image.north west)$)}]

No entanto, verifica-se que aparentemente esta abordagem tem alguns problemas de precisão, com o sistema de coordenadas resultante não correspondendo exatamente à imagem.

Então, em vez disso, você pode querer usar a abordagem do CFR dehttps://tex.stackexchange.com/a/269850/2552, que funciona sem problemas para mim (mas envolve mais digitação):

\documentclass[tikz, demo]{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}

\newlength\iwidth
\newlength\iheight
\settoheight\iheight{\includegraphics{example-image}}
\settowidth\iwidth{\includegraphics{example-image}}

  \begin{tikzpicture}[x=\iwidth/800, y=\iheight/600]
    \node[anchor=south west,inner sep=0] (image) at (0,0) {\includegraphics{example-image}};
      \draw[color=red] (0, 0) rectangle (800, 600);
  \end{tikzpicture}
\end{document}

informação relacionada