Ich möchte auf ein Bild zeichnen, welches ich mit \includeimage eingebettet habe:
\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}
Nehmen wir an, das Bild hat eine Größe von 800 x 600 Pixeln. Das Problem dabei ist, dass x und y in Breite und Höhe zwischen 0 und 1 skalieren. Ich möchte auf dem Bild zeichnen und dabei seine Pixel als Koordinatenreferenz verwenden, und zwar so, dass
\draw[color=red] (0,0) rectangle (1,1);
kann ersetzt werden durch
\draw[color=red] (0,0) rectangle (800,600);
Mein Problem besteht nun darin, die x- und y-Werte im Bereich zu skalieren. Ich dachte, die folgende Anweisung würde funktionieren:
\begin{scope}[x={($(image.south east)/800$)},y={($(image.north west)/600$)}]
aber es wird der folgende Fehler ausgegeben:
Package tikz Error: + or - expected.
Ich habe Kapitel 13.5 im TikZ/PGF-Handbuch nachgeschlagen, aber es scheint, als ob es auf diese Weise mit der image.direction-Anweisung nicht funktioniert.
Wie kann ich meinen Umfang richtig skalieren?
Antwort1
Bearbeiten:In der ersten Version meiner Antwort habe ich – wie @Jake in seinem Kommentar anmerkte – den Kern der Frage nicht verstanden. Hier ist also die korrigierte Lösung, inspiriert von @Jakes Antwort:
\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}
Der Hauptunterschied besteht darin, dass stattdessen neue Längen box0
und Möglichkeiten verwendet werden, die diese bieten. Dadurch ist der obige Code etwas kürzer, führt aber zum gleichen Ergebnis:
Nachtrag:Beachten Sie, was @jfbu in seinem Kommentar sagt: „… \box0
ist manchmal etwas gefährlich, insbesondere wenn Sie die Verwendung von \wd0
oder verzögern \ht0
. Es ist sicherer , … zu \newsavebox\mybox
verwenden . Obwohl ich bisher keine schlechten Erfahrungen mit gemacht habe , ist es also besser, auf der sicheren Seite zu bleiben und LateX zu verwenden und das obige MWE wie folgt umzuschreiben:\sbox\mybox
\wd\mybox
box0
\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}
Die Bot-Lösung hat einen wichtigen Vorteil: Das Bild wird nur einmal verarbeitet (beim Speichern in der Savebox und dann als \usebox\mybox
oder gemäß dem ersten Beispiel als verwendet \usebox0
. Dies reduziert möglicherweise die Kompilierungszeit (wie auch @jfbu in seinem Kommentar angibt).
Antwort2
Sie versuchen das Richtige, aber die Syntax für die Koordinatenberechnung ist etwas eingeschränkt: Sie erwartet, dass der Faktor für die Streckung des Vektors am Anfang des Ausdrucks erscheint. Sie könnten also verwenden
\begin{scope}[x={($1/800*(image.south east)$)},y={($1/600*(image.north west)$)}]
Es stellt sich jedoch heraus, dass dieser Ansatz offenbar einige Präzisionsprobleme aufweist, da das resultierende Koordinatensystem nicht genau mit dem Bild übereinstimmt.
Stattdessen möchten Sie vielleicht den Ansatz von cfr verwenden.https://tex.stackexchange.com/a/269850/2552, was bei mir problemlos funktioniert (aber mehr Tipparbeit erfordert):
\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}