如何在 TikZ 中以像素精度繪製嵌入 \includeimage 的影像?

如何在 TikZ 中以像素精度繪製嵌入 \includeimage 的影像?

我想在使用 \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}

假設影像的大小為 800x600 像素。這裡的問題是 x 和 y 的寬度和高度在 0 和 1 之間縮放。我想使用它的像素作為座標參考在圖像上繪製,以這樣的方式

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

可以替換為

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

我現在的問題是縮放範圍內的 x 和 y。我認為以下聲明會起作用:

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

但它會引發以下錯誤:

Package tikz Error: + or - expected.

我查閱了 TikZ/PGF 手冊中的第 13.5 章,但似乎它不能以這種方式使用 image.direction 語句。

如何以正確的方式擴展我的範圍?

答案1

編輯:在我答案的第一個版本中——正如 @Jake 在他的評論中指出的——我錯過了問題中的要點……所以這裡是更正的解決方案,受到 @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}

主要區別在於,使用了新的長度box0及其提供的可能性。上面的程式碼稍微短一些,但給出了相同的結果:

在此輸入影像描述

附錄:請注意,正如 @jfbu 在他的評論中所說:「...\box0有時有點危險,特別是如果您延遲使用\wd0\ht0。這樣做\newsavebox\mybox和使用\sbox\mybox,更安全\wd\mybox」。因此,雖然到目前為止我還沒有使用過不好的經驗box0,但最好還是保持 LateX 使用的安全,並將上面的 MWE 重寫為:

\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}

機器人解決方案具有重要的優勢:僅處理圖像(當存儲在保存箱中時,而不是用作\usebox\mybox或根據第一個示例作為 )\usebox0。 )。

答案2

您正在嘗試正確的事情,但坐標計算語法有點受限:它期望拉伸向量的因子出現在表達式的開頭。所以你可以使用

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

然而,事實證明這種方法顯然存在一些精確度問題,生成的座標系與影像不完全匹配。

因此,您可能想使用 cfr 的方法https://tex.stackexchange.com/a/269850/2552,這對我來說沒有問題(但涉及更多打字):

\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}

相關內容