[Tex/LaTex] tikz clip rounded corners

path-clippingrounded-cornerstikz-pgf

How to apply this Tikz solution (Rounded corners on only one side of a TikZ node) to have the same effect on clipping?

I want to clip things (images) using that rectangle with differently rounded corners.

The result is clipped only with rectangle. Not with rounded corners.

Thank you wery much!

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{intersections}

\begin{document}

\makeatletter

\pgfkeys{/pgf/.cd,
  rectangle corner radius north west/.initial=10pt,
  rectangle corner radius north east/.initial=10pt,
  rectangle corner radius south west/.initial=10pt,
  rectangle corner radius south east/.initial=10pt
}
\newif\ifpgf@rectanglewrc@donecorner@
\def\pgf@rectanglewithroundedcorners@docorner#1#2#3#4#5{%
  \edef\pgf@marshal{%
    \noexpand\pgfintersectionofpaths
      {%
        \noexpand\pgfpathmoveto{\noexpand\pgfpoint{\the\pgf@xa}{\the\pgf@ya}}%
        \noexpand\pgfpathlineto{\noexpand\pgfpoint{\the\pgf@x}{\the\pgf@y}}%
      }%
      {%
        \noexpand\pgfpathmoveto{\noexpand\pgfpointadd
          {\noexpand\pgfpoint{\the\pgf@xc}{\the\pgf@yc}}%
          {\noexpand\pgfpoint{#1}{#2}}}%
        \noexpand\pgfpatharc{#3}{#4}{#5}%
      }%
    }%
  \pgf@process{\pgf@marshal\pgfpointintersectionsolution{1}}%
  \pgf@process{\pgftransforminvert\pgfpointtransformed{}}%
  \pgf@rectanglewrc@donecorner@true
}
\pgfdeclareshape{rectangle with rounded corners}
{
  \inheritsavedanchors[from=rectangle] % this is nearly a rectangle
  \inheritanchor[from=rectangle]{north}
  \inheritanchor[from=rectangle]{north west}
  \inheritanchor[from=rectangle]{north east}
  \inheritanchor[from=rectangle]{center}
  \inheritanchor[from=rectangle]{west}
  \inheritanchor[from=rectangle]{east}
  \inheritanchor[from=rectangle]{mid}
  \inheritanchor[from=rectangle]{mid west}
  \inheritanchor[from=rectangle]{mid east}
  \inheritanchor[from=rectangle]{base}
  \inheritanchor[from=rectangle]{base west}
  \inheritanchor[from=rectangle]{base east}
  \inheritanchor[from=rectangle]{south}
  \inheritanchor[from=rectangle]{south west}
  \inheritanchor[from=rectangle]{south east}

  \savedmacro\cornerradiusnw{%
    \edef\cornerradiusnw{\pgfkeysvalueof{/pgf/rectangle corner radius north west}}%
  }
  \savedmacro\cornerradiusne{%
    \edef\cornerradiusne{\pgfkeysvalueof{/pgf/rectangle corner radius north east}}%
  }
  \savedmacro\cornerradiussw{%
    \edef\cornerradiussw{\pgfkeysvalueof{/pgf/rectangle corner radius south west}}%
  }
  \savedmacro\cornerradiusse{%
    \edef\cornerradiusse{\pgfkeysvalueof{/pgf/rectangle corner radius south east}}%
  }

  \backgroundpath{%
    \northeast\advance\pgf@y-\cornerradiusne\relax
    \pgfpathmoveto{}%
    \pgfpatharc{0}{90}{\cornerradiusne}%
    \northeast\pgf@ya=\pgf@y\southwest\advance\pgf@x\cornerradiusnw\relax\pgf@y=\pgf@ya
    \pgfpathlineto{}%
    \pgfpatharc{90}{180}{\cornerradiusnw}%
    \southwest\advance\pgf@y\cornerradiussw\relax
    \pgfpathlineto{}%
    \pgfpatharc{180}{270}{\cornerradiussw}%
    \northeast\pgf@xa=\pgf@x\advance\pgf@xa-\cornerradiussw\southwest\pgf@x=\pgf@xa
    \pgfpathlineto{}%
    \pgfpatharc{270}{360}{\cornerradiusse}%
    \northeast\advance\pgf@y-\cornerradiusse\relax
    \pgfpathlineto{}%

  }

  \anchor{before north east}{\northeast\advance\pgf@y-\cornerradiusne}
  \anchor{after north east}{\northeast\advance\pgf@x-\cornerradiusne}
  \anchor{before north west}{\southwest\pgf@xa=\pgf@x\advance\pgf@xa\cornerradiusnw
    \northeast\pgf@x=\pgf@xa}
  \anchor{after north west}{\northeast\pgf@ya=\pgf@y\advance\pgf@ya-\cornerradiusnw
    \southwest\pgf@y=\pgf@ya}
  \anchor{before south west}{\southwest\advance\pgf@y\cornerradiussw}
  \anchor{after south west}{\southwest\advance\pgf@x\cornerradiussw}
  \anchor{before south east}{\northeast\pgf@xa=\pgf@x\advance\pgf@xa-\cornerradiusse
    \southwest\pgf@x=\pgf@xa}
  \anchor{after south east}{\southwest\pgf@ya=\pgf@y\advance\pgf@ya\cornerradiusse
    \northeast\pgf@y=\pgf@ya}

  \anchorborder{%
    \pgf@xb=\pgf@x% xb/yb is target
    \pgf@yb=\pgf@y%
    \southwest%
    \pgf@xa=\pgf@x% xa/ya is se
    \pgf@ya=\pgf@y%
    \northeast%
    \advance\pgf@x by-\pgf@xa%
    \advance\pgf@y by-\pgf@ya%
    \pgf@xc=.5\pgf@x% x/y is half width/height
    \pgf@yc=.5\pgf@y%
    \advance\pgf@xa by\pgf@xc% xa/ya becomes center
    \advance\pgf@ya by\pgf@yc%
    \edef\pgf@marshal{%
      \noexpand\pgfpointborderrectangle
      {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}}
      {\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}%
    }%
    \pgf@process{\pgf@marshal}%
    \advance\pgf@x by\pgf@xa% 
    \advance\pgf@y by\pgf@ya%
    \pgfextract@process\borderpoint{}%
    %
    \pgf@rectanglewrc@donecorner@false
    %
    % do southwest corner
    \southwest\pgf@xc=\pgf@x\pgf@yc=\pgf@y
    \advance\pgf@xc\cornerradiussw\relax\advance\pgf@yc\cornerradiussw\relax 
    \borderpoint
    \ifdim\pgf@x<\pgf@xc\relax\ifdim\pgf@y<\pgf@yc\relax
      \pgf@rectanglewithroundedcorners@docorner{-\cornerradiussw}{0pt}{180}{270}{\cornerradiussw}%
    \fi\fi
    %
    % do southeast corner
    \ifpgf@rectanglewrc@donecorner@\else
      \southwest\pgf@yc=\pgf@y\relax\northeast\pgf@xc=\pgf@x\relax
      \advance\pgf@xc-\cornerradiusse\relax\advance\pgf@yc\cornerradiusse\relax
      \borderpoint
      \ifdim\pgf@x>\pgf@xc\relax\ifdim\pgf@y<\pgf@yc\relax
       \pgf@rectanglewithroundedcorners@docorner{0pt}{-\cornerradiusse}{270}{360}{\cornerradiusse}%
      \fi\fi
    \fi
    %
    % do northeast corner
    \ifpgf@rectanglewrc@donecorner@\else
      \northeast\pgf@xc=\pgf@x\relax\pgf@yc=\pgf@y\relax
      \advance\pgf@xc-\cornerradiusne\relax\advance\pgf@yc-\cornerradiusne\relax
      \borderpoint
      \ifdim\pgf@x>\pgf@xc\relax\ifdim\pgf@y>\pgf@yc\relax
       \pgf@rectanglewithroundedcorners@docorner{\cornerradiusne}{0pt}{0}{90}{\cornerradiusne}%
      \fi\fi
    \fi
    %
    % do northwest corner
    \ifpgf@rectanglewrc@donecorner@\else
      \northeast\pgf@yc=\pgf@y\relax\southwest\pgf@xc=\pgf@x\relax
      \advance\pgf@xc\cornerradiusnw\relax\advance\pgf@yc-\cornerradiusnw\relax
      \borderpoint
      \ifdim\pgf@x<\pgf@xc\relax\ifdim\pgf@y>\pgf@yc\relax
       \pgf@rectanglewithroundedcorners@docorner{0pt}{\cornerradiusnw}{90}{180}{\cornerradiusnw}%
      \fi\fi
    \fi
  }
}

\makeatother

\begin{tikzpicture}
\clip [rectangle with rounded corners, rectangle corner radius south west=none,rectangle corner radius south east=none,rectangle corner radius north west=10,rectangle corner radius north east=10] (0,0) rectangle coordinate (clipname) (100,100);
\node [text width=100, inner sep=0pt] (mainpicnode) at (clipname)
{this i want to be clipped (originally its an image here)};
\end{tikzpicture}

\end{document}

Best Answer

I think your approach was too complicated. You can simply use paths to clip things in TikZ. I'll show it through some examples, but also you can find the complete code at the end of the answer.

  1. If you want to use only some part of an image, then include the image in a node you want to clip inside the tikzpicture, and draw the clipping path before it. When drawind the clipping path you can use the rounded corners option before any coordinate to change the corner of it. (You can omit the draw lines simply by using path instead of draw.)

    \begin{tikzpicture}
        \draw[clip] (2cm, 0.5cm)
            [rounded corners=5pt] -- (2cm, 2.5cm)
            [rounded corners=10pt] -- (4cm, 2.5cm)
            [rounded corners=0.5cm] -- (4cm, 0.5cm)
            [sharp corners] -- cycle;
    
        \node[anchor=south west,%
            inner sep=0,%
            outer sep=0pt] (image) at (0, 0) {\includegraphics[width=6cm, height=3cm]{clip.png}};
    \end{tikzpicture}
    
  2. If you want to cut out a part from the image first you have to specify the width and height of the tikzpicture, and make sure it is the same as the included image's width and height. Then when you draw the clipping path first include the whole image in it, then continue the same path with your desired cutout. You can use the rounded corners option in both the “bounding path” and in the cutout.

    \begin{tikzpicture}[x=6cm, y=3cm]
        \path[clip] [rounded corners=10pt] (0, 0) -- (1, 0) -- (1, 1) -- (0, 1) -- cycle
        (2cm, 0.5cm) [rounded corners=5pt] -- (2cm, 2.5cm)
        [rounded corners=10pt] -- (4cm, 2.5cm)
        [rounded corners=0.5cm] -- (4cm, 0.5cm)
        [sharp corners] -- cycle;
    
        \node[anchor=south west,%
            inner sep=0,%
            outer sep=0pt] (image) at (0, 0) {\includegraphics[width=6cm, height=3cm]{clip.png}};
    \end{tikzpicture}
    

You can find the shown and more examples in the complete code below. (You can download the image I used in the example here.)

\documentclass[a4paper, 11pt]{article}

\usepackage[a4paper,
    tmargin=2cm,%
    rmargin=2cm,%
    bmargin=2cm,%
    lmargin=2cm,
    vscale=1,%
    hscale=1]{geometry}

\usepackage{tikz}

% only used for the example
\newlength{\skiplength}
\setlength{\skiplength}{1cm}
\setlength{\parskip}{\skiplength}
\setlength{\parindent}{0pt}

\begin{document}

\includegraphics[width=6cm, height=3cm]{clip.png}

\begin{tikzpicture}
    \draw (2cm, 0.5cm)
        [rounded corners=5pt] -- (3cm, 2.5cm)
        [rounded corners=20pt] -- (4cm, 0.5cm)
        [sharp corners] -- cycle;
\end{tikzpicture}
\hspace{\skiplength}
\begin{tikzpicture}
    \draw[clip] (2cm, 0.5cm)
        [rounded corners=5pt] -- (3cm, 2.5cm)
        [rounded corners=20pt] -- (4cm, 0.5cm)
        [sharp corners] -- cycle;

    \node[anchor=south west,%
        inner sep=0,%
        outer sep=0pt] (image) at (0, 0) {\includegraphics[width=6cm, height=3cm]{clip.png}};
\end{tikzpicture}
\hspace{\skiplength}
\begin{tikzpicture}
    \path[clip] (2cm, 0.5cm)
        [rounded corners=5pt] -- (3cm, 2.5cm)
        [rounded corners=20pt] -- (4cm, 0.5cm)
        [sharp corners] -- cycle;

    \node[anchor=south west,%
        inner sep=0,%
        outer sep=0pt] (image) at (0, 0) {\includegraphics[width=6cm, height=3cm]{clip.png}};
\end{tikzpicture}
\hspace{\skiplength}
\begin{tikzpicture}[x=6cm, y=3cm]
    \draw[clip] (0, 0) -- (1, 0) -- (1, 1) -- (0, 1) -- cycle
        (2cm, 0.5cm) [rounded corners=5pt] -- (3cm, 2.5cm)
        [rounded corners=20pt] -- (4cm, 0.5cm)
        [sharp corners] -- cycle;

    \node[anchor=south west,%
        inner sep=0,%
        outer sep=0pt] (image) at (0, 0) {\includegraphics[width=6cm, height=3cm]{clip.png}};
\end{tikzpicture}

\begin{tikzpicture}[x=6cm, y=3cm]
    \path[clip] (0, 0) -- (1, 0) -- (1, 1) -- (0, 1) -- cycle
        (2cm, 0.5cm) [rounded corners=5pt] -- (3cm, 2.5cm)
        [rounded corners=20pt] -- (4cm, 0.5cm)
        [sharp corners] -- cycle;

    \node[anchor=south west,%
        inner sep=0,%
        outer sep=0pt] (image) at (0, 0) {\includegraphics[width=6cm, height=3cm]{clip.png}};
\end{tikzpicture}
\hspace{\skiplength}
\begin{tikzpicture}[x=6cm, y=3cm]
    \path[clip] (0, 0) -- (1, 0) [rounded corners=0.5cm] -- (1, 1) [sharp corners] -- (0, 1) [rounded corners=2cm] -- cycle
        (2cm, 0.5cm) [rounded corners=5pt] -- (3cm, 2.5cm)
        [rounded corners=20pt] -- (4cm, 0.5cm)
        [sharp corners] -- cycle;

    \node[anchor=south west,%
        inner sep=0,%
        outer sep=0pt] (image) at (0, 0) {\includegraphics[width=6cm, height=3cm]{clip.png}};
\end{tikzpicture}

\begin{tikzpicture}
    \draw (2cm, 0.5cm)
        [rounded corners=5pt] -- (2cm, 2.5cm)
        [rounded corners=10pt] -- (4cm, 2.5cm)
        [rounded corners=0.5cm] -- (4cm, 0.5cm)
        [sharp corners] -- cycle;
\end{tikzpicture}
\hspace{\skiplength}
\begin{tikzpicture}
    \draw[clip] (2cm, 0.5cm)
        [rounded corners=5pt] -- (2cm, 2.5cm)
        [rounded corners=10pt] -- (4cm, 2.5cm)
        [rounded corners=0.5cm] -- (4cm, 0.5cm)
        [sharp corners] -- cycle;

    \node[anchor=south west,%
        inner sep=0,%
        outer sep=0pt] (image) at (0, 0) {\includegraphics[width=6cm, height=3cm]{clip.png}};
\end{tikzpicture}
\hspace{\skiplength}
\begin{tikzpicture}
    \path[clip] (2cm, 0.5cm)
        [rounded corners=5pt] -- (2cm, 2.5cm)
        [rounded corners=10pt] -- (4cm, 2.5cm)
        [rounded corners=0.5cm] -- (4cm, 0.5cm)
        [sharp corners] -- cycle;

    \node[anchor=south west,%
        inner sep=0,%
        outer sep=0pt] (image) at (0, 0) {\includegraphics[width=6cm, height=3cm]{clip.png}};
\end{tikzpicture}
\hspace{\skiplength}
\begin{tikzpicture}[x=6cm, y=3cm]
    \draw[clip] (0, 0) -- (1, 0) -- (1, 1) -- (0, 1) -- cycle
    (2cm, 0.5cm) [rounded corners=5pt] -- (2cm, 2.5cm)
    [rounded corners=10pt] -- (4cm, 2.5cm)
    [rounded corners=0.5cm] -- (4cm, 0.5cm)
    [sharp corners] -- cycle;

    \node[anchor=south west,%
        inner sep=0,%
        outer sep=0pt] (image) at (0, 0) {\includegraphics[width=6cm, height=3cm]{clip.png}};
\end{tikzpicture}

\begin{tikzpicture}[x=6cm, y=3cm]
    \path[clip] (0, 0) -- (1, 0) -- (1, 1) -- (0, 1) -- cycle
    (2cm, 0.5cm) [rounded corners=5pt] -- (2cm, 2.5cm)
    [rounded corners=10pt] -- (4cm, 2.5cm)
    [rounded corners=0.5cm] -- (4cm, 0.5cm)
    [sharp corners] -- cycle;

    \node[anchor=south west,%
        inner sep=0,%
        outer sep=0pt] (image) at (0, 0) {\includegraphics[width=6cm, height=3cm]{clip.png}};
\end{tikzpicture}
\hspace{\skiplength}
\begin{tikzpicture}[x=6cm, y=3cm]
    \path[clip] [rounded corners=10pt] (0, 0) -- (1, 0) -- (1, 1) -- (0, 1) -- cycle
    (2cm, 0.5cm) [rounded corners=5pt] -- (2cm, 2.5cm)
    [rounded corners=10pt] -- (4cm, 2.5cm)
    [rounded corners=0.5cm] -- (4cm, 0.5cm)
    [sharp corners] -- cycle;

    \node[anchor=south west,%
        inner sep=0,%
        outer sep=0pt] (image) at (0, 0) {\includegraphics[width=6cm, height=3cm]{clip.png}};
\end{tikzpicture}

\end{document}
Related Question