¿Cómo colorear un icono en escala de grises sobre un fondo que no sea blanco?

¿Cómo colorear un icono en escala de grises sobre un fondo que no sea blanco?

Tengo un icono negro sobre transparente en un archivo png. Quiero usar este ícono en diferentes ubicaciones de un documento LaTeX en diferentes colores. Como beneficio adicional, sería bueno si pudiera darle a la mitad superior del ícono un color diferente al de la mitad inferior porque a veces aparece en el borde de diferentes fondos.

esta respuestamuestra cómo colorear un archivo png en escala de grises y es fácil darle a la mitad superior un color diferente al de la mitad inferior. Desafortunadamente, requiere que el logo esté sobre un fondo blanco:

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

\begin{document}
\begin{tikzpicture}
    \fill[yellow!50!white] (0,1) rectangle (2,2);
    \fill[gray!50!black]   (0,0) rectangle (2,1);

    \begin{scope}[blend group=screen]
        \node[inner sep=0,line width=0] (logo) at (1,1) [anchor=center] {\includegraphics{icon-bw}};
        \fill[blue] (logo.west) rectangle (logo.north east);
        \fill[green] (logo.south west) rectangle (logo.east);
    \end{scope}
\end{tikzpicture}
\end{document}

Se agregó un ícono de ejemplo con fondo blanco: icono-bw.png

Si uso un png de negro a transparente, todo el nodo se pinta de azul y verde.

Un icono de ejemplo con fondo transparente: icono.png

esta respuestamuestra cómo utilizar un archivo png como máscara de transparencia. Pero, ¿cómo muevo el ícono para que esté centrado en (1,1)?

\documentclass{article}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{fadings}

\begin{tikzfadingfrompicture}[name=icon]
    \begin{scope}[transparency group]
    \node (icon) [fill, draw, white] {\includegraphics[height=1cm]{icon}};
    \begin{scope}[blend mode=difference]
    \fill[white] (icon.south west) rectangle (icon.north east);
    \end{scope}
    \end{scope}
\end{tikzfadingfrompicture}

\begin{document}
\begin{tikzpicture}
    \fill[yellow!50!white] (0,1) rectangle (2,2);
    \fill[gray!50!black]   (0,0) rectangle (2,1);

    % How I intend to use it
    \begin{scope}[scope fading=icon, fit fading=false]
        \fill[blue] (0.5,1) rectangle (1.5,1.5);
        \fill[green] (0.5,0.5) rectangle (1.5,1);
    \end{scope}

    % Approach of the original answer. The icon is not positioned correctly.
    % The specified coordinate does not seem to make any difference.
    \path[scope fading=icon,fit fading=false] (1,1);
    \node[fill=yellow,minimum width=1cm,minimum height=1cm] {};
\end{tikzpicture}
\end{document}

En mi caso de uso real, el icono consta únicamente de negro y transparencia. Por lo tanto, sería aceptable que una respuesta no funcionara con tonos de grises intermedios.

Respuesta1

El patrón de desvanecimiento se centrará en (0,0) y la única forma de moverlo es mover el contenido del nodo usando cosas como \hspacey \raisebox. Mover la implementación simplemente usa el patrón en esa ubicación (fuera del borde). Como está centrado, tienes que moverlo el doble de lo que realmente se mueve.

\documentclass{article}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{fadings}

\begin{tikzfadingfrompicture}[name=icon,inner sep=0]
  \node [fill=transparent!0]
    {\hspace{2cm}\raisebox{2cm}{\includegraphics[height=2cm, width=2cm]{images/icon}}};
\end{tikzfadingfrompicture}

\begin{document}
\begin{tikzpicture}
  \fill[yellow!50!white] (0,1) rectangle (2,2);
  \fill[gray!50!black]   (0,0) rectangle (2,1);
  \begin{scope}[shift={(1,1)}]
    \path[scope fading=icon, fit fading=false];
    \node[bottom color=blue,top color=green,minimum width=2cm,minimum height=2cm]{};
  \end{scope}
\end{tikzpicture}
\end{document}

manifestación

Respuesta2

Esta respuesta difiere de la de John Kormylo principalmente en dos puntos:

  • Estoy usando fading transformdonde aplico el desvanecimiento en lugar de \hspacey \raiseboxen la definición de desvanecimiento. También tenga en cuenta que estoy usando path fadingen lugar de scope fading. No estoy seguro de qué tan grande es la diferencia, pero no logré que funcionara al pasar scope fadingni fading transformal scopeentorno.
  • Estoy invirtiendo los colores del archivo png para que se llenen las partes negras en lugar de las partes transparentes.
\documentclass{article}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{fadings}

\newcommand\IconNodeContent{%
    \includegraphics[height=1cm]{icon}%
}

\begin{tikzfadingfrompicture}[name=icon]
    % I am using \fill[white] with blend mode=difference to invert the colors
    % so that I can use my black on transparent icon without needing to convert it to white on transparent/black.
    % This has the down side that the area around the icon node is not transparent but opaque.
    % I am increasing the transparent area a little with draw thick to avoid a visible rectangle around the icon when filling it later.
    \begin{scope}[transparency group]
    \node (icon) [fill, draw, thick, white] {\IconNodeContent};
    \begin{scope}[blend mode=difference]
    \fill[white] (icon.south west) rectangle (icon.north east);
    \end{scope}
    \end{scope}
\end{tikzfadingfrompicture}

\begin{document}
\begin{tikzpicture}
    % draw background
    \fill[yellow!50!white] (0,1) rectangle (2,2);
    \fill[gray!50!black]   (0,0) rectangle (2,1);

    % create an invisible node to define size and position of icon
    \node (icon) at (1,1) [anchor=center, transparent] {\IconNodeContent};
    % draw the top half of the icon in one color, shifting the coordinates 1pt inwards to make sure no border is visible
    \fill[blue,  path fading=icon, fit fading=false, fading transform={shift=(icon.center)}] ([shift={(1pt,-1pt)}] icon.north west) rectangle ([shift={(-1pt,+0pt)}] icon.east);
    % draw the bottom half of the icon in another color, shifting the coordinates 1pt inwards to make sure no border is visible
    \fill[green, path fading=icon, fit fading=false, fading transform={shift=(icon.center)}] ([shift={(1pt,+1pt)}] icon.south west) rectangle ([shift={(-1pt,-0pt)}] icon.east);
\end{tikzpicture}
\end{document}

producción

información relacionada