3

Because a picture is worth a thousand words, here it is:

enter image description here

If you prefer words, I'd like to do some resize and crop on a picture relative to a given "box dimension". To do so I'd like to do three things:

  1. put the picture inside the box, and extend it as much as possible : I can do it easily using the \includegraphics[width=..., height=...,keepaspectratio]
  2. do the contrary : change the size of the image such that she can fill the whole box, but such that the picture stay as small as possible
  3. in the same idea, do the same thing as the point 2, but crop the picture so that only the part of the picture that fit inside the box is visible. I should be able to choose easily an anchor on the box and an anchor on the picture so that I can choose where the image is put in the box.

I'm pretty sure that I can do 3 if I've 2 by using tikz crop (maybe there is a better way to proceed ?), but I don't know how to efficiently do 2. I tried to look into the package adjustbox, but I can't find anything that help me, and because this function is so useful, it would be strange that no one before me tried to write something for that...

Any idea ? Thank you !

  • 3
    you can trim and scale with \includegraphics – percusse Oct 18 '17 at 0:44
  • @percusse: Well, I don't see how to automatically scale to the good dimension using includegraphics... For example, how would you use scale so that at the end the picture can contain a box of size 3cm x 4cm ? – tobiasBora Oct 18 '17 at 0:47
  • That's up to you no? How can the program know what you would like to fit ? – percusse Oct 18 '17 at 0:58
  • You can do everything with \includegraphics (which is loaded with tikz) inside a node and it will fit whatever you specify (plus inner sep). You can load the picture into a savebox to measure the unscaled, uncropped width and height. – John Kormylo Oct 18 '17 at 1:20
  • @tobiasBora: Are you specifically wanting this using tikz? You can do this using \fbox and \includegraphics... – Werner Oct 18 '17 at 2:02
1

After lot's of pain, I finally came up with this solution. If you find a better/shorter way to proceed, at any point, please let me now !

\documentclass[]{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\graphicspath{{photos/}} % on change la racine

% === Pictures ===
% \includeFitInsidePicture{<max width>}{<max height>}{<name>}
% Create the biggest picture whose size is at most <max width>
% and <max height>.
\newcommand{\includeFitInsidePicture}[3]{%
  \includegraphics[width=#1,height=#2,keepaspectratio]{#3}%
}

\makeatletter
\newsavebox{\mybox}
% \includeFitOutsidePicture{<min width>}{<max width>}{<name>}
% Create the smallest picture whose size is at least <min width>
% and <min height>.
\newcommand{\includeFitOutsidePicture}[3]{%
  \begingroup%
  \sbox{\mybox}{\includegraphics{#3}}%
  \dimen0=#1\relax%
  \dimen1=#2\relax%
  \dimen2=\wd\mybox\relax%
  \dimen3=\ht\mybox\relax%
  \dimen0=\dimexpr 1pt*\dimen0/\dimen1\relax%
  \dimen1=\dimexpr 1pt*\dimen2/\dimen3\relax%
  \ifnum\dimen0>\dimen1\relax%
  \includegraphics[width=#1]{#3}%
  \else%
  \includegraphics[height=#2]{#3}%
  \fi%
  \endgroup%
}
\makeatother

% \addCropPicture{<width>}{<height>}{<anchor box>}{<anchor picture>}{<name>}
% Create the smallest picture whose size is at least <min width>
% and <min height>, and crop the region outside the box such that the anchor
% of the picture <ancher picture> touch the anchor of the box <anchor box>.
% Most of the time you want <anchor box>=<anchor picture>
\newcommand{\addCropPicture}[5]{%
  \begin{tikzpicture}[inner sep=0pt]
    \edef\q{(mnode.#3)}
    \node[minimum width=#1, minimum height=#2,inner sep=0pt](mnode) at (0,0) {};
    \clip (mnode.south west) rectangle (mnode.north east);
    \node[anchor=#4,inner sep=0pt](picture) at \q
    {\includeFitOutsidePicture{#1}{#2}{#5}};
    % \node[draw,minimum width=#1, minimum height=#2,inner sep=0pt] at (0,0) {};
  \end{tikzpicture}%
}

\begin{document}
% Draw a box to show the bounding box size
\tikz\draw (0,0) rectangle (5cm,5cm) node[pos=.5] {Reference box};
% Fit outside
\includeFitOutsidePicture{5cm}{5cm}{simpson.jpg}\fbox{Fit outside}

% Fit inside
\includeFitInsidePicture{5cm}{5cm}{simpson.jpg}\fbox{Fit inside}

% Crop in different ways
\vspace{1cm}Crop using three different anchors:

\addCropPicture{5cm}{5cm}{north west}{north west}{simpson.jpg}
\addCropPicture{5cm}{5cm}{north}{north}{simpson.jpg}
\addCropPicture{5cm}{5cm}{north east}{north east}{simpson.jpg}

\end{document}

Output:

enter image description here

1

The following example uses adjustbox to trim-and-clip content (an image) in a number of ways. Most notably, trim=<llx> <lly> <urx> <ury> trims the content where <ll-> is measured from the lower-left corner and <ur-> is measured from the upper-right corner of the object. One can use \Width, \Height, \Depth and \Totalheight in length calculations (\dimexprs) to measure exact trimming location.

enter image description here

\documentclass{article}

\usepackage[landscape]{geometry}% Just for this example

\usepackage[export]{adjustbox}

\begin{document}

\setlength{\fboxsep}{0pt}\setlength{\fboxrule}{2pt}%
\fbox{\rule{5cm}{0pt}\rule{0pt}{5cm}} % Reference box
%
\includegraphics[height=5cm]{example-image}% Fit outside

\hspace{\fboxrule}%
\includegraphics[width=5cm]{example-image}% Fit inside

\bigskip

% Trimming using three different "anchors"
\adjustbox{trim=0pt 0pt \dimexpr\Width-5cm\relax{} 0pt,clip}{\includegraphics[height=5cm]{example-image}}
\adjustbox{trim=\dimexpr.5\Width-25mm\relax{} 0pt \dimexpr.5\Width-25mm\relax{} 0pt,clip}{\includegraphics[height=5cm]{example-image}}
\adjustbox{trim=\dimexpr\Width-5cm\relax{} 0pt 0pt 0pt,clip}{\includegraphics[height=5cm]{example-image}}

\end{document}
  • Thank you for your help, but there is a problem. You code works here because the picture is "in landscape" and the reference box is a square. However, if you try that with another picture in portrait mode like example-image-10x16, you will see that here the two roles are reversed, and therefore the three different anchors give the same output. And in order to know in which case you are, you need to check the dimensions... And I don't know how to avoid the ugly 10 lines of code in my function \includeFitOutsidePicture. – tobiasBora Oct 20 '17 at 1:14
  • But your code is interesting to see that adjustbox can be used to avoid tikz, so I'll try to adapt your code to my need ! Thank you for the adjustbox demo. – tobiasBora Oct 20 '17 at 1:14
  • @tobiasBora: Indeed. With knowledge of the image and constraint dimensions it is fairly straight forward. adjustbox also provides max width and max height keys that you can use which will be used to perform checks to supersede other dimensional settings. That should help with your conditional adjustments. – Werner Oct 20 '17 at 1:43
  • @tobiasBora: You only asked how to do these things (trimming/clipping) without giving a use-case for it, nor how different dimensional shapes (images, portrait or landscape) should be handled. Hence the somewhat abbreviated answer. – Werner Oct 20 '17 at 1:44
  • I don't see why you say that I didn't say that in the question, I said "change the size of the image such that she can fill the whole box, but such that the picture stay as small as possible". In your example, the "Fit outside" picture does not fill the whole box. I tried before max width/max height, but it was suppose to work only if the original picture was smaller than the wanted size. So I gave up, and now you just gave me the idea to use in the content \includegraphics[5cm,5cm,keepaspectratio]{}, and because the picture is now smaller, minsizebox will work ! – tobiasBora Oct 20 '17 at 2:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.