22

With Emacs' doc-view-mode I can easily shrink/zoom/etc PDFs, however, I would like to be able to do the same thing with images. Currently when I open an image I cannot adjust the zoom level to fit it to the frame. I know there is image-mode-fit-frame, however, it does not help when the image is larger than my screen.

Is there a package or mode that will allow me zoom in and out on an image?

4 Answers 4

19

Such functionality is provied by packages:

  • image-dired-thumbnail-mode

    With point in the thumbnail buffer, you can type RET (image-dired-display-thumbnail-original-image) to display a sized version of it in another window. This sizes the image to fit the window.

    It uses ImageMagick's convert command.

    You can also use image-dired-external-viewer to avoid the problem and display your images in an external image viewer such as feh.

  • eimp

    (add-hook 'image-mode-hook 'eimp-mode) 

    It uses the mogrify utility from ImageMagick to do the actual transformations.

    (kbd "+") 'eimp-increase-image-size (kbd "-") 'eimp-decrease-image-size (kbd "<") 'eimp-rotate-image-anticlockwise (kbd ">") 'eimp-rotate-image-clockwise (kbd "B +") 'eimp-blur-image (kbd "B -") 'eimp-sharpen-image (kbd "B E") 'eimp-emboss-image (kbd "B G") 'eimp-gaussian-blur-image (kbd "B R") 'eimp-radial-blur-image (kbd "C B +") 'eimp-increase-image-brightness (kbd "C B -") 'eimp-decrease-image-brightness (kbd "C C +") 'eimp-increase-image-contrast (kbd "C C -") 'eimp-decrease-image-contrast (kbd "F ^") 'eimp-flip-image (kbd "F >") 'eimp-flop-image (kbd "F <") 'eimp-flop-image (kbd "N") 'eimp-negate-image ; Commands most relevant to you: (kbd "S f") 'eimp-fit-image-to-window (kbd "S h") 'eimp-fit-image-height-to-window (kbd "S w") 'eimp-fit-image-width-to-window (kbd "<right>") 'eimp-roll-image-right (kbd "<left>") 'eimp-roll-image-left (kbd "<up>") 'eimp-roll-image-up (kbd "<down>") 'eimp-roll-image-down (kbd "<down-mouse-1>") 'eimp-mouse-resize-image (kbd "<S-down-mouse-1>") 'eimp-mouse-resize-image-preserve-aspect (kbd "C-c C-k") 'eimp-stop-all 
  • eiv - It also uses the ImageMagick package which should provide mogrify.

    Complete command list:

    • eiv-fit-image-to-window - Resize image to current window size.
    • eiv-rotate-current-image - Rotate current image at 90 degrees.
    • eiv-dec-or-inc-image - Resize image to current window size.
    • eiv-diaporama - Start a diaporama on tree.
    • eiv-viewer - The emacs-image-viewer. Allows to navigate in a tree of dir and subdir.
1
  • 6
    One should note that eimp modifies the file. It doesn't work on read-only images. Commented Oct 22, 2014 at 17:52
9

Solution

I used the source code in lisp/image-mode.el to write this up. Calling this function in any image buffer will resize it to fit to width or height depending on the image and window height/width ratios.

You do need these 2 things for this function to work:

  • Your Emacs needs to have been compiled with ImageMagick.
  • By default libjpeg loader is used to handle JPEG images. The hack shown in next part of this answer is used to force emacs to use imagemagick loader.
 (defun modi/image-transform-fit-to-window() "Resize the image to fit the width or height based on the image and window ratios. Imagemagick is required to run this function." (interactive) (let* ( (img-size (image-display-size (image-get-display-property) t)) (img-width (car img-size)) (img-height (cdr img-size)) (img-h/w-ratio (/ (float img-height) (float img-width))) (win-width (- (nth 2 (window-inside-pixel-edges)) (nth 0 (window-inside-pixel-edges)))) (win-height (- (nth 3 (window-inside-pixel-edges)) (nth 1 (window-inside-pixel-edges)))) (win-h/w-ratio (/ (float win-height) (float win-width)))) ;; Fit image by width if the h/w ratio of window is > h/w ratio of the image (if (> win-h/w-ratio img-h/w-ratio) (image-transform-fit-to-width) ;; Else fit by height (image-transform-fit-to-height)))) 

Hack to force Emacs to use ImageMagick for loading images

After following through the emacs bug reports #18797, #10746 and #10112, the following solution worked for forcing Imagemagick to load images; put it somewhere in your init.el:

I have forced Emacs to use ImageMagick only for the image files familiar to me: PNG, TIFF, JPEG, SVG; the rest are kept as default. I have chosen to allow gif files to be opened by the default loader as emacs 24.4 has improved support for viewing multi-frame images. The whole regexp is taken from lisp/image.el.

 (setq image-type-header-regexps `( ("\\`/[\t\n\r ]*\\*.*XPM.\\*/" . xpm) ("\\`P[1-6]\\\(?:\ \\(?:\\(?:#[^\r\n]*[\r\n]\\)?[[:space:]]\\)+\ \\(?:\\(?:#[^\r\n]*[\r\n]\\)?[0-9]\\)+\ \\)\\{2\\}" . pbm) ("\\`GIF8[79]a" . gif) ;; ("\\`\x89PNG\r\n\x1a\n" . png) ;; Uncomment this (and comment the below line) to enable inline PNG images in org-mode ("\\`\x89PNG\r\n\x1a\n" . imagemagick) ; PNG ("\\`[\t\n\r ]*#define \\([a-z0-9_]+\\)_width [0-9]+\n\ #define \\1_height [0-9]+\n\\(\ #define \\1_x_hot [0-9]+\n\ #define \\1_y_hot [0-9]+\n\\)?\ static \\(unsigned \\)?char \\1_bits" . xbm) ;; ("\\`\\(?:MM\0\\*\\|II\\*\0\\)" . tiff) ("\\`\\(?:MM\0\\*\\|II\\*\0\\)" . imagemagick) ; TIFF ("\\`[\t\n\r ]*%!PS" . postscript) ;; ("\\`\xff\xd8" . jpeg) ;; Uncomment this (and comment the below line) to enable inline JPEG images in org-mode ("\\`\xff\xd8" . imagemagick) ; JPEG ("\\`\377\330" . imagemagick) ; JPEG (,(let* ((incomment-re "\\(?:[^-]\\|-[^-]\\)") (comment-re (concat "\\(?:!--" incomment-re "*-->[ \t\r\n]*<\\)"))) (concat "\\(?:<\\?xml[ \t\r\n]+[^>]*>\\)?[ \t\r\n]*<" comment-re "*" "\\(?:!DOCTYPE[ \t\r\n]+[^>]*>[ \t\r\n]*<[ \t\r\n]*" comment-re "*\\)?" "[Ss][Vv][Gg]")) ;; . svg) ;; Uncomment this (and comment the below line) to enable inline SVG images in org-mode . imagemagick) ; SVG )) 

Drawback

  • Image types chosen to be loaded by ImageMagick will not show up as inline images in Org mode.

References

2

image-transform-set-scale may be what you are looking for. However it requires Emacs to be compiled with Imagemagick support.

There is also a commented out image-transform-mode in image-mode.el labeled "Not yet implemented."

1
  • I see Does Emacs use imagemagick? yes when running ./configure. So it did compile with imagemagick. Still image transform doesn't work for me. (On emacs 24.4 x86_64-unknown-linux-gnu) I also have the following in config.log: | #define HAVE_IMAGEMAGICK 1 | #define HAVE_MAGICKEXPORTIMAGEPIXELS 1 | #define HAVE_MAGICKMERGEIMAGELAYERS 1. Commented Oct 22, 2014 at 16:17
1

Here's a solution that lets you scale up and down using the same keys as are used for text scaling, C-x C-= and C-x C--

(defun scale-image () "Scale the image by the same factor specified by the text scaling." (image-transform-set-scale (expt text-scale-mode-step text-scale-mode-amount))) (defun scale-image-register-hook () "Register the image scaling hook." (add-hook 'text-scale-mode-hook 'scale-image)) (add-hook 'image-mode-hook 'scale-image-register-hook) 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.