11
1

Wie kann ich einfache Beschriftungen und Markierungen auf mit dem graphicx-Paket importierte Bilder zeichnen.

Selbstverständlich kann man relativ einfach eine Node erstellen, die das Bild beinhaltet, zum Beispiel

\node{\includegraphics{<Dateiname>}};

und dann einfach Koordinten wie üblich mit (<x>, <y>) oder (<Winkel>: <Radius>) anwählen, aber jedesmal wenn die Grafik neuskaliert wird oder innerhalb des TikZ-Pictures verschoben wird, muss man die Koordinaten neu eingeben.

Gibt es da einen Trick, das komfortabler zu machen?

Inspiriert von Drawing on an image with TikZ, Frage auf TeX.sx von Benutzer nacho4d.

gefragt 05 Aug '13, 01:52

Qrrbrbirlbel's gravatar image

Qrrbrbirlbel
2.9k3815
Akzeptiert-Rate: 53%

bearbeitet 13 Aug '13, 19:27


Im Folgenden verwende ich das Bild PRODPIC-1461.jpg, das ich auf www.tvfilmprops.co.uk gefunden habe.

Mithilfe der TikZ-Optionen shift, x und y lassen sich Koordinaten verwenden, die in einem lokalen Koordinatensystem existieren, das mit dem eingefügtem Bild skaliert wird. So lässt sich mit dem Code

\begin{tikzpicture}
    \node[anchor=south west,inner sep=0] (Bild) at (0,0)
                                                    {\includegraphics{Bild.jpg}};
    \begin{scope}[x=(Bild.south east),y=(Bild.north west)]
        \draw[red,ultra thick,rounded corners] (0.5,0.25) rectangle (0.75,0.25);
    \end{scope}
\end{tikzpicture}

bereits sehr einfach auf dem Bild zeichnen. Dadurch, dass man den Südwest-Anchor auf den Koordinatenursprung setzt kann man nun einfach den Südost-Anchor sowie den Northwest-Anchor als Koordinaten für die x- und die y-Vektoren verwenden.

Die Koordinate (0, 0) ist dann in der unteren linken Ecke des Bildes, die Koordinate (1, 1) in der oberen rechten Ecke des Bildes. Die Mitte des Bildes liegt bei (0.5, 0,5). Dies funktioniert auch, wenn das Bild rotiert wird.

Nodescope

Um das Ganze etwas komfortabler zu machen habe ich im Code unten die Umgebung nodescope so wie das Coordinate System nodescope hinzugefügt.

Die Umgebung nodescope versteht vier Argumente:

  1. optional: Optionen für die Node, die für das Bild verwendet wird;
  2. optional: Optionen für die optionalen Optionen von \incudegraphics;
  3. obligatorisch: Pfad/Dateinamen zum Bild;
  4. optional: Optionen für das integrierte Scope.

Mit dem nodescope cs: können bereits inkludierte Bilder referenziert werden. Das Argument besteht hier im Prinzip aus zwei Teilen:

  1. Der erste Teil referenziert den Namen des Nodes mit dem geladenen Bild (ja, das geht im Prinzip mit jeder Node).
  2. Der zweite Teil nach dem : ist eine normale TikZ-Koordinate, die theoretisch die gleiche Koordinate ergeben soll, als wenn es direkt in der nodescope-Umgebung verwendet wurde.

Es darf jeweils kein Leerzeichen vor den Doppelpunkten vorkommen!

Die Transformationen von PGF sind etwas trickreich. Ich hoffe, das funktioniert auch für jede erdenkliche Transformation.

Hinweise

Die vordefinierten Optionen für every nodescope node sind mit Bedacht gewählt. Das Setzen von outer sep und inner sep auf Null führt dazu, dass nur und wirklich nur das Bild als Referenz für die Koordinaten verwendet wird (und das TikZ-Picture auch nicht größer wird als das Bild selbst). Möchte man einen Rahmen um das Bild malen und dazu direkt den Node mit dem Bild verwenden, führt das ebenfalls zu einer leichten Änderung an den Koordinaten (wie man an dem Gitter erkennen kann).

Die overlay-Option in every nodescope grid node führt dazu, dass die Nodes zur Beschriftung des Gitters das TikZ-Picture nicht weiter beeinflussen. Das Gitter, das mit der nodescope grid-Option aktiviert werden kann, ist im Prinzip eh nur als eine draft-Option gedacht.

Man kann sich selbstverständlich weitere Optionen vorstellen, die

  • das Gitter beeinflussen (mehr Linien, andere Einteilung);
  • die Skalierung der Koordinaten einschränkt oder aufhebt (man kann bereits jetzt (0.5, 2cm) verwenden, was eine Koordinate entspricht die 2cm „über“ (also Richtung north-Anchor) dem south-Anchor liegt; das kann man auch mit ([y=1cm] 0.5, 2) erreichen; genauso ist mit ([y={(0pt,1cm)}] 0.5, 1) der Original-TikZ-Vektor für die y-Richtung ausgewählt);
  • eine renodescope-Option, die quasi ein scope option für das nodescope cs: wäre.

Code

\documentclass[
  tikz,
  border=15pt,
%  convert={outext=.png,density=300,size=600},
  convert=false,
  ]{standalone}
\makeatletter
\newif\ifpgf@nodescope@grid
\tikzset{
  nodescope grid/.is if=pgf@nodescope@grid,
  every nodescope grid node/.style={
    shape=rectangle,
    font=\small\ttfamily,
    inner sep=+0pt,
    outer sep=+1pt,
    fill=white,
    overlay},
  every nodescope node/.style={
    shape=rectangle,
    inner sep=+0pt,
    outer sep=+0pt,
    draw=none,
    fill=none}}
\def\tikz@nodescope@env{%
  \pgfutil@ifnextchar[\tikz@@nodescope@env{\tikz@@@nodescope@env{}[]}}
\def\tikz@@nodescope@env[#1]{%
  \pgfutil@ifnextchar[{\tikz@@@nodescope@env{#1}}{\tikz@@@nodescope@env{#1}[]}}
\def\tikz@@@nodescope@env#1[#2]#3{%
  \pgfutil@ifnextchar[{\tikz@@@@nodescope@env{#1}{#2}{#3}}{\tikz@@@@nodescope@env{#1}{#2}{#3}[]}}
\def\tikz@@@@nodescope@env#1#2#3[#4]{%
  \tikz@scope@env[#4]
    \node[every nodescope node/.try, #1, alias=tikz@last@nodescope]{\includegraphics[#2]{#3}};%
    \pgftransformresetnontranslations
    \pgftransformshift{\pgfpointanchor{tikz@last@nodescope}{south west}}%
    \pgfsetxvec{\pgfpointdiff{\pgfpointanchor{tikz@last@nodescope}{south west}}{\pgfpointanchor{tikz@last@nodescope}{south east}}}%
    \pgfsetyvec{\pgfpointdiff{\pgfpointanchor{tikz@last@nodescope}{south west}}{\pgfpointanchor{tikz@last@nodescope}{north west}}}%
    \ifpgf@nodescope@grid
      \draw[help lines,xstep=.1,ystep=.1] (0,0) grid (1,1);
      \foreach \x in {0,1,...,10}{
        \node[every nodescope grid node/.try, left, rotate=90] at (\x/10,0) {\ifnum\x=10\relax1.0\else0.\x\fi};
        \node[every nodescope grid node/.try, left] at (0,\x/10) {\ifnum\x=10\relax1.0\else0.\x\fi};
      }
    \fi
}
\tikzaddtikzonlycommandshortcutlet\tikz@orignodescope\nodescope
\tikzaddtikzonlycommandshortcutlet\tikz@origendnodescope\endnodescope
\tikzaddtikzonlycommandshortcutlet\tikz@origstartnodescope\startnodescope
\tikzaddtikzonlycommandshortcutlet\tikz@origstopnodescope\stopnodescope
\tikzaddtikzonlycommandshortcutlet\nodescope\tikz@nodescope@env
\tikzaddtikzonlycommandshortcutlet\endnodescope\endscope
\tikzaddtikzonlycommandshortcutlet\startnodescope\nodescope
\tikzaddtikzonlycommandshortcutlet\stopnodescope\endnodescope
\pgfutil@g@addto@macro\tikz@uninstallcommands{%
  \let\nodescope\tikz@orignodescope
  \let\endnodescope\tikz@origendnodescope
  \let\startnodescope\tikz@origstartnodescope
  \let\stopnodescope\tikz@origstopnodescope
}
\tikzdeclarecoordinatesystem{nodescope}{%
  \edef\pgf@temp{#1}%
  \expandafter\pgfutil@ifnextchar\expandafter x\expandafter\tikz@nodescope@split\expandafter\tikz@nodescope@split\pgf@temp\pgf@stop
}
\def\tikz@nodescope@split#1:#2\pgf@stop{%
  \begingroup
    \edef\pgf@temp{#1}%
    \pgftransformresetnontranslations
    \pgfsetxvec{\pgfpointdiff{\pgfpointanchor{#1}{south west}}{\pgfpointanchor{#1}{south east}}}%
    \pgfsetyvec{\pgfpointdiff{\pgfpointanchor{#1}{south west}}{\pgfpointanchor{#1}{north west}}}%
    \tikz@scan@one@point\tikz@nodescope@shift(#2)\relax
  \endgroup
}
\def\tikz@nodescope@shift#1{%
  \pgf@process{\pgfpointadd{#1}{\pgfpointanchor{\pgf@temp}{south west}}}%
}
\makeatother
\begin{document}
\begin{tikzpicture}\sffamily
  \begin{nodescope}[draw, line width=2mm, rounded corners, inner sep=+.5\pgflinewidth, outer sep=+.5\pgflinewidth, name=alterPC]
                   [width=.9\textwidth]{PRODPIC-1461.jpg}
                   [nodescope grid]
    \tikzset{
      nodes={fill=white,rounded corners, fill opacity=.5, text opacity=1},
      every path/.append style={ultra thick, rounded corners}}
    \draw[red, rotate around={-15:(0.265,0.3)}] (0.03, 0.15) rectangle node[rotate=-15] {Tastatur} (0.5,0.45);
  \end{nodescope}
  \node[white] at (nodescope cs: alterPC: 0.7, 0.8) {Lampe};
\end{tikzpicture}
\end{document}

Resultat

alt text

Permanenter link

beantwortet 05 Aug '13, 02:11

Qrrbrbirlbel's gravatar image

Qrrbrbirlbel
2.9k3815
Akzeptiert-Rate: 53%

bearbeitet 06 Aug '13, 16:37

Sehr gut! Während ich Netzwerk-Zeichnungen schon mit TikZ mache, kann ich auf diese Weise nun Fotos der Serverschränke aufnehmen und die einzelnen Server, Router und Switche mit TikZ beschriften.

(06 Aug '13, 16:54) stefan ♦♦

+100 weil ich von diesem lehrreichen Frage+Antwort-Beitrag begeistert bin! Nun kann ich Bitmaps mit TikZ-Annotationen ergänzen.

(06 Aug '13, 21:39) Felix

Ich benutze das \usepackage{onimage}. Ich habe eine gute Erklärung bei tex.stackexchange gefunden. Auf der Seite kann man noch einige andere Erklärungen finden, als ich hier übersetze.

Ich benutze das gleiche Bild wie @Qrrbrbirlbel.

Erklärungen

Das Package kann als onimage.dtx-Datei hier heruntergeladen werden: http://bazaar.launchpad.net/~tex-sx/tex-sx/development/view/head:/onimage.dtx. Nachdem man sie mit pdflatex kompiliert hat, erhält man eine onimage.sty-Datei. (Bei mir hat es am besten mit TexWorks funktioniert.)

Bei Windows im Ordner C:\localtexmf\tex\latex einen neuen Ordner mit der Bezeichnung onimage erstellen und die onimage.sty-Datei dort hinein kopieren. Falls der Ordner C:\localtexmf\tex\latex noch nicht existiert, einfach einen erstellen. Zusätzlich unter MikTeX Settings (oder auch MikTeX Options) die Registerkarte Roots auswählen und Add.. anklicken und den Ordner C:\localtexmf auswählen, Okay anklicken und zum Schluß Übernehmen anklicken.

Bei Mac wird die onimage.sty-Datei in den Ordner ~/Library/texmf/tex/latex kopiert. Wenn der Ordner nicht vorhanden ist, gilt das gleiche wie bei Windows, einfach einen anlegen. Um den Ordner zu finden, im Finder mit der Maus in die Menüleiste Gehe zu auswählen und dann Gehe zum Ordner oder einfach mit der Tastenkombination shift+cmd+g.

Mit den Koordinaten verhält es sich bei onimage genauso wie bei der Antwort von Qrrbrbirlbel. Unten links ist (0,0) und oben rechts befindet sich (1,1).

Statt \begin{tikzpicture}und \end{tikzpicture} wird \begin{tikzonimage} und \end{tikzonimage} verwendet.

Nach \begin{tikzonimage} folgt dann [width=0.9\textwidth] zum Skalieren des Bildes und der Dateiname {PRODPIC-1461.jpg}. Wird zur ersten Orientierung das Gitternetz gewünscht, wird hinter den Dateinamen dieses [tsx/show help lines] gesetzt.

Code

\documentclass{article}
\usepackage{onimage}

\begin{document}

\tikzset{every path/.append style={ultra thick, rounded corners}}

\begin{tikzonimage} [width=.9\textwidth]{PRODPIC-1461.jpg}[tsx/show help lines]\sffamily
    \draw[red, rotate around={-15:(0.265,0.3)}] (0.03, 0.15) rectangle 
    node[fill=white,rounded corners, fill opacity=.5, text opacity=1,rotate=-15] {Tastatur} (0.5,0.45);
    \node[white] at (0.7, 0.8) {Lampe};
\end{tikzonimage}

\end{document}

Resultat

alt text

Permanenter link

beantwortet 22 Aug '13, 00:07

Bettina's gravatar image

Bettina
665181923
Akzeptiert-Rate: 25%

bearbeitet 01 Okt '13, 01:35

Die Lösung ist wirklich klasse! Und einfach nachzuvollziehen. Schade nur, daß es kein Handbuch für onimage.sty gibt :(

(23 Jul '14, 09:37) cis

@cis gibt es doch: wird erzeugt, wenn Du pdflatex onimage.dtx laufen lässt. Sie ist zwar nur zwei Seiten lang und enthält kleinere Schreibfehler (wie \begin{\tikzonimage}), ist aber da

(23 Jul '14, 09:45) cgnieder

Ah stimmt - ach Mann, ich hab nur tex onimage.dtx ausgeführt :(

(23 Jul '14, 11:02) cis

Was ist egtl. onimage.sty für ein Paket, wieso ist das keine offizieller Bestandteil einer TL-Distribution?

(23 Jul '14, 12:04) cis

@cis es ist offenbar entstanden als Idee nach einer Antwort auf TeX.sx Wahrscheinlich fand Clemens (@caramdir auf TeX.sx) das Paket noch nicht ausgereift genug, um es auf CTAN zu veröffentlichen. (Ich hab auch solche...) Man müsste ihn fragen.

(23 Jul '14, 12:09) cgnieder
1

Habe ich das richtig verstanden, dass der lange Code oben sich über onimage.sty durch den kurzen Code von Bettina ersetzen lässt?

(24 Jul '14, 14:09) tt33tt
1

@tt33tt: Ja, das scheint mir eine richtige Feststellung - bei Interesse schau einmal hier - ich habe das Bsp. von @bettina noch etwas weitergeführt.

(24 Jul '14, 14:18) cis
Ergebnis 5 von 7 show 2 more comments

Verblüffenderweise braucht man dafür keine Zusatzpakete oder -syntax: TikZ selbst stellt alles bereit, was dafür nötig ist.
Die folgende -bestechend einfache- Methode (von hier) beruht darauf, dass man die Einheitslängen für x bzw. y als Bildbreite bzw. -höhe festlegt: x={(image.south east)}, y={(image.north west)}
Damit erhält man auch leicht ein Hilfskoordinatensystem.

alt text

\documentclass[tikz, margin=10mm]{standalone}
\begin{document}
\begin{tikzpicture}
\node[anchor=south west,inner sep=0] (image) at (0,0) {\includegraphics[width=0.9\textwidth]{example-image.jpg}};
\begin{scope}[x={(image.south east)},y={(image.north west)}]
% Help CoSy
\draw[help lines,xstep=.1,ystep=.1] (0,0) grid (1,1);
\foreach \x in {0,1,...,9} { \node [anchor=north] at (\x/10,0) {0.\x}; }
\foreach \y in {0,1,...,9} { \node [anchor=east] at (0,\y/10) {0.\y}; }

\draw[red, thick, rounded corners] (0.2,0.9) rectangle (0.35,0.75);
\end{scope}
\end{tikzpicture}
\end{document}
Permanenter link

beantwortet 14 Sep '20, 20:44

cis's gravatar image

cis
9.5k94459491
Akzeptiert-Rate: 29%

bearbeitet 14 Sep '20, 20:45

1

Soweit ich sehe ist das letztlich das, was in der akzeptierten Antwort von Qrrbrbirlbel bereits als aller erstes erwähnt und an einem Code-Ausschnitt gezeigt wird.

(15 Sep '20, 07:53) saputello

Das habe ich dann übersehen. Dann wundert mich, warum er ein kompliziertes Paket geschrieben hat, wenn ich mir den Paketinhalt mit 3 Zeilen selbst erzeugen kann.

(15 Sep '20, 18:53) cis
Deine Antwort
Vorschau umschalten

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs fügen Sie einfach zwei Leerzeichen an die Stelle an der die neue Linie sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Frage-Themen:

×731
×54
×21

gestellte Frage: 05 Aug '13, 01:52

Frage wurde gesehen: 33,877 Mal

zuletzt geändert: 15 Sep '20, 18:53