59

I have a photograph that I'm loading into my LaTeX document.

I'd like the photograph to have rounded corners and no visible border.

I'd prefer not to edit the original photograph.

Any thoughts on how to do this?

Peter Grill
  • 223,288
Richard
  • 5,723

7 Answers7

41

One way would be to use tikz to create a node with the image, and draw a rectangle with rounded corners using white color to clip the image. Here is the original image and one with the white rectangle drawn over it:

enter image description here

Notes:

  • The value of \ClipSep defined the amount of clipping so this can be adjusted as desired.

Code:

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

\newcommand*{\ClipSep}{0.4cm}%

\begin{document} \includegraphics[width=5.0cm]{images/EiffelTall.jpg} % \begin{tikzpicture} \node [inner sep=0pt] at (0,0) {\includegraphics[width=5.0cm]{images/EiffelTall.jpg}}; \draw [white, rounded corners=\ClipSep, line width=\ClipSep] (current bounding box.north west) -- (current bounding box.north east) -- (current bounding box.south east) -- (current bounding box.south west) -- cycle ; \end{tikzpicture} \end{document}

Peter Grill
  • 223,288
  • If you'd want to put this image with rounded corners in a fixed width environment (at the margin, for example), and so the effective image width was exactly \linewidth... how could that be achieved? I mean, with your code the image width is the actual original width plus the one of the white tikz rectangle. – Pablo B. Nov 21 '14 at 21:43
  • @PabloB.: Not sure I fully understand, but I think what you want is \noindent before the \begin{tikzpicture}, and use \includegraphics[width=\linewidth,keepaspectratio]. If that does not solve your issue, I would suggest you post a new question with a MWE including \documentclass and the appropriate packages that sets up the problem. – Peter Grill Nov 21 '14 at 21:47
  • The thing is that the white rectangle adds extra width to the original image, so in order to get the real width, you'd need to do something similar to \includegraphics[width=\myfactor*\linewidth,keepaspectratio] notice myfactor correction. Should I post a new question? – Pablo B. Nov 21 '14 at 21:57
  • @PabloB.: Yes you should post a new question as it is really not related to rounded corners. – Peter Grill Nov 21 '14 at 23:26
38

Another possibility if you want to fix the dimensions of the pictures :

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

\begin{document}
\begin{tikzpicture} 

\begin{scope}
    \clip [rounded corners=.5cm] (0,0) rectangle coordinate (centerpoint) (5,7.5cm); 
    \node [inner sep=0pt] at (centerpoint) {\includegraphics[width=6.0cm]{EiffelTall.jpg}}; 
\end{scope}

\begin{scope}[xshift=7cm]
    \clip [rounded corners=.5cm] (0,0) rectangle coordinate (centerpoint) ++(5cm,7.5cm); 
    \node [inner sep=0pt] at (centerpoint) {\includegraphics[width=10.0cm]{EiffelTall.jpg}};
\end{scope}

\end{tikzpicture}
\end{document} 

enter image description here

Alain Matthes
  • 95,075
  • Could you please explain why ++ works or is needed in the second example? I am trying to gain a solid understanding by grasping your answer along with Paul Gaborit's answer here: http://tex.stackexchange.com/a/76216/13552 These methods are much better than "the white box" methods because they don't require a white background. – Jonathan Komar Feb 03 '16 at 13:42
  • @macmadness86 You can remove ++ . It's not necessary – Alain Matthes Feb 04 '16 at 15:19
9

I borrowed an image from Herbert's answer without his permission.

User defined data:

\def\M{3}% columns
\def\N{3}% rows
\def\scale{1}% scale
\def\filename{herbert}% filename

% Specify the cropping area.
\def\L{-2}
\def\B{-1.5}
\def\R{2}
\def\T{3}

Steps:

  1. Specify the number of columns and rows. The greater values, the more accurate coordinates. Avoid changing these values after completing the 3rd step, unless you are happy to redo the 3rd step.
  2. Specify the scaling factor. It does not depend on other steps.
  3. Specify the cropping area. You might need a trial and error approach to find it.
  4. Compile the following code with either xelatex or latex-dvips-ps2pdf. See the result, if the cropping region does not suit your requirement, do the 3rd and 4th again.

Hopefully, the given comments in the code are self-explanatory.

\documentclass[pstricks,border=12pt]{standalone}

\def\M{3}% columns
\def\N{3}% rows
\def\scale{1}% scale
\def\filename{herbert}% filename


\usepackage{graphicx}
\newsavebox\IBox
\savebox\IBox{\includegraphics[scale=\scale]{\filename}}


\usepackage{pstricks}
\psset
{
  xunit=0.5\dimexpr\wd\IBox/\M\relax,
  yunit=0.5\dimexpr\ht\IBox/\N\relax,
}



\begin{document}

% The following figure shows an image with a grid enabled.
% Use the grid to find the cropping area.
\begin{pspicture}[showgrid=true](-\M,-\N)(\M,\N)
    \rput(0,0){\usebox\IBox}
\end{pspicture}


% Specify the cropping area.

\def\L{-2}
\def\B{-1.5}
\def\R{2}
\def\T{3}

\begin{pspicture}[showgrid=false](\L,\B)(\R,\T)
    \begin{psclip}{\psframe[linestyle=none,framearc=0.5,dimen=middle](\L,\B)(\R,\T)}
    \rput(0,0){\usebox\IBox}
    \end{psclip}
\end{pspicture}
\end{document}

Output:

Original image with a grid.

enter image description here

Cropped image.

enter image description here

5

I'm surprised that nobody presented the solution of tikz, but when you don't know the size of the node. The idea is to print it one using phantom to get the size, and then use the tikz clip function.

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

\newcommand*{\bord}{1mm}
\begin{document}
\begin{tikzpicture}
  \def\ig{%
   \includegraphics[width=7cm,height=7cm,keepaspectratio]{example-image-10x16}}
 \node [inner sep=0pt](mypicture) at (0,0) {\phantom{\ig}};
 \clip[rounded corners=5mm] ($(mypicture.south west)+(\bord,\bord)$) rectangle ($(mypicture.north east)-(\bord,\bord)$);
 \node[inner sep=0pt](mypicture) at (0,0) {\ig};
\end{tikzpicture}
\end{document}

file:///tmp/Spectacle.f17590.png

tobiasBora
  • 8,684
  • Works nicely and a rounded frame can be added easily with: \draw[gray, rounded corners=5mm, line width=2pt] ($(mypicture.south west)+(\bord,\bord)$) rectangle ($(mypicture.north east)-(\bord,\bord)$); right before \end{tikzpicture} – mxmlnkn Apr 29 '18 at 20:58
  • Great solution! Would you mind updating the answer to describe \bord ? I'm using this solution without it. – ɲeuroburɳ Jun 15 '22 at 19:02
  • @ɲeuroburɳ \bord is just a shortcut for 1mm that I defined above: \newcommand*{\bord}{1mm}. I use it to avoid changing 1mm in multiple places (another option is to write directly a macro for that) – tobiasBora Jun 16 '22 at 11:34
4

When we are using OpTeX then we need not to use TikZ. The \clipinoval macro is provided.

\def\photo#1#2{\setbox0=\hbox{\picw=#1\inspic{#2}}
   \clipinoval .5\wd0 .5\ht0 \wd0 \ht0 {\box0}}

\photo{70mm}{eiffeltower.jpg}

\bye

eiffel

The \clipinoval macro used default diameter of corners 5mm but you can set another value using \roundess parameter.

wipet
  • 74,238
1

Just in case anyone comes back to this, I used this stack exchange thread combined with Peter Grill's answer to create a .tex file that you can include into your own LaTEX project (with \include{yourFileNameHere.tex}. You can then call \shadowImage[]{image} like you would \includegraphics[]{image} and it will create an image with rounded corners and a centered drop shadow. An example is shown below:

enter image description here

\usepackage{tikz}
\usetikzlibrary{shadows,calc}

% code adapted from https://tex.stackexchange.com/a/11483/3954

% some parameters for customization \def\shadowshift{3pt,-3pt} \def\shadowradius{6pt}

\colorlet{innercolor}{black!10} \colorlet{outercolor}{gray!0}

% this draws a shadow under a rectangle node \newcommand\drawshadow[1]{ \begin{pgfonlayer}{shadow} \shade[outercolor,inner color=innercolor,outer color=outercolor] ($(#1.south west)+(\shadowshift)+(\shadowradius/2,\shadowradius/2)$) circle (\shadowradius); \shade[outercolor,inner color=innercolor,outer color=outercolor] ($(#1.north west)+(\shadowshift)+(\shadowradius/2,-\shadowradius/2)$) circle (\shadowradius); \shade[outercolor,inner color=innercolor,outer color=outercolor] ($(#1.south east)+(\shadowshift)+(-\shadowradius/2,\shadowradius/2)$) circle (\shadowradius); \shade[outercolor,inner color=innercolor,outer color=outercolor] ($(#1.north east)+(\shadowshift)+(-\shadowradius/2,-\shadowradius/2)$) circle (\shadowradius); \shade[top color=innercolor,bottom color=outercolor] ($(#1.south west)+(\shadowshift)+(\shadowradius/2,-\shadowradius/2)$) rectangle ($(#1.south east)+(\shadowshift)+(-\shadowradius/2,\shadowradius/2)$); \shade[left color=innercolor,right color=outercolor] ($(#1.south east)+(\shadowshift)+(-\shadowradius/2,\shadowradius/2)$) rectangle ($(#1.north east)+(\shadowshift)+(\shadowradius/2,-\shadowradius/2)$); \shade[bottom color=innercolor,top color=outercolor] ($(#1.north west)+(\shadowshift)+(\shadowradius/2,-\shadowradius/2)$) rectangle ($(#1.north east)+(\shadowshift)+(-\shadowradius/2,\shadowradius/2)$); \shade[outercolor,right color=innercolor,left color=outercolor] ($(#1.south west)+(\shadowshift)+(-\shadowradius/2,\shadowradius/2)$) rectangle ($(#1.north west)+(\shadowshift)+(\shadowradius/2,-\shadowradius/2)$); \filldraw ($(#1.south west)+(\shadowshift)+(\shadowradius/2,\shadowradius/2)$) rectangle ($(#1.north east)+(\shadowshift)-(\shadowradius/2,\shadowradius/2)$); % \shade[outercolor,right color=black!40,left color=black!40] ($(#1.north west)+(-\shadowradius/12,\shadowradius/12)$) rectangle ($(#1.south east)+(\shadowradius/12,-\shadowradius/12)$);%Frame \end{pgfonlayer} }

% create a shadow layer, so that we don't need to worry about overdrawing other things \pgfdeclarelayer{shadow} \pgfsetlayers{shadow,main}

\newsavebox\mybox \newlength\mylen

\newcommand\shadowimage[2][]{ \setbox0=\hbox{\includegraphics[#1]{#2}} \setlength\mylen{\wd0} \ifnum\mylen<\ht0 \setlength\mylen{\ht0} \fi \divide \mylen by 50 \def\shadowshift{0,0} \def\shadowradius{\the\dimexpr\mylen+\mylen+\mylen\relax} \begin{tikzpicture} \begin{scope} \clip [rounded corners=\shadowradius * 0.8] (0,0) rectangle coordinate (centerpoint) (\the\wd0, \the\ht0); \node[anchor=south west,inner sep=0] (image) at (0,0) {\includegraphics[#1]{#2}}; \end{scope} \drawshadow{image} \end{tikzpicture} }

Malek
  • 41
-2

If you just want round corners there are an easy solution: just use GIMP. Take your picture, go on filter -> decoration -> round corners and there you can make round corners and put a shadow beneath and a lot more.

I know it is not a really "LaTeX-solution", but it is the most easy thing to do. If you need to use Tikz everytime you will make round corners, it would take a lot of time. Especially if you use other commands on the picture already (minipage and so on). You can save a lot of time with using such simple methods as GIMP - so you can use it on more LaTeXic things.