aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.imagemagick49
-rw-r--r--lisp/image-mode.el71
-rw-r--r--src/image.c38
3 files changed, 98 insertions, 60 deletions
diff --git a/README.imagemagick b/README.imagemagick
index e9d6a4166ea..80c665e0cef 100644
--- a/README.imagemagick
+++ b/README.imagemagick
@@ -27,11 +27,21 @@ jpegs.
27 the bundle. This feature is not the primary usecase for the 27 the bundle. This feature is not the primary usecase for the
28 imagemagick patch though. 28 imagemagick patch though.
29 29
30- optimize number of pages calculation for bundles as suggested by
31 imagemagick forum: "set the density to something low like 2 and use
32 MagickPingImage()"
33
30- zooming the image like what is done for fonts in face-remap.el would 34- zooming the image like what is done for fonts in face-remap.el would
31 be a useful and demo friendly addition. 35 be a useful and demo friendly addition. Some work has been done on
36 image-mode.el to acihieve this.
32 37
33- figure out what to do with the experimental features noted below. 38- look for optimizations for handling images with low depth
39
40- it would be neat if the graphicsmagick fork of imagemagick could
41 optionaly be used.
34 42
43
44
35* TODO 45* TODO
36#B _ complete documentation drafts below 46#B _ complete documentation drafts below
37 47
@@ -120,41 +130,6 @@ as TIFF or DJVM, to view.
120The image-metadata function can be used to retrieve the total number 130The image-metadata function can be used to retrieve the total number
121of images in an image bundle. This is simmilar to how GIF files work. 131of images in an image bundle. This is simmilar to how GIF files work.
122 132
123* experimental
124
125- :crop is used to specify a croping area: (width height x y). This
126is similar to the slice image specification, but has a different
127purpose. :crop removes the croped areas from memory, so its memory
128efficient if you only need to view a certain part of the image. The
129slice specification can be used to pick diferent parts of the same
130image, so its more disk and display efficient. :crop works well, but
131it would still be better to find a way to have :splice do the same
132thing.
133
134- :geometry takes a geometry string as defined by ImageMagick:
135
136scale%
137scale-x%xscale-y%
138width
139xheight
140widthxheight
141widthxheight^
142widthxheight!
143widthxheight>
144widthxheight<
145area@
146{size}{offset}
147{size}{+-}x{+-}y
148
149See the ImageMagick manual for more information.
150
151- :crop is used to specify a croping area, with the "{size}{offset}" syntax.
152
153:geometry and :crop with a string argument, are both particular to
154ImageMagick, whereas the lisp interface is more general. Currently it
155seems like the lisp interface is good enough, so the string argument
156interface will probably be removed.
157
158* Changelog entry 133* Changelog entry
1592010-06-12 Joakim Verona <joakim@verona.se> 1342010-06-12 Joakim Verona <joakim@verona.se>
160 * image.c: Add support for ImageMagick. When HAVE_IMAGEMAGICK is 135 * image.c: Add support for ImageMagick. When HAVE_IMAGEMAGICK is
diff --git a/lisp/image-mode.el b/lisp/image-mode.el
index 585d82e9beb..a278c47a555 100644
--- a/lisp/image-mode.el
+++ b/lisp/image-mode.el
@@ -471,7 +471,10 @@ was inserted."
471 (buffer-substring-no-properties (point-min) (point-max))) 471 (buffer-substring-no-properties (point-min) (point-max)))
472 filename)) 472 filename))
473 (type (image-type file-or-data nil data-p)) 473 (type (image-type file-or-data nil data-p))
474 (image (create-animated-image file-or-data type data-p)) 474 (image0 (create-animated-image file-or-data type data-p))
475 (image (append image0
476 (image-transform-properties image0)
477 ))
475 (props 478 (props
476 `(display ,image 479 `(display ,image
477 intangible ,image 480 intangible ,image
@@ -534,6 +537,72 @@ the image file and `image-mode' showing the image as an image."
534 (when (not (string= image-type (bookmark-prop-get bmk 'image-type))) 537 (when (not (string= image-type (bookmark-prop-get bmk 'image-type)))
535 (image-toggle-display)))) 538 (image-toggle-display))))
536 539
540
541(defvar image-transform-minor-mode-map
542 (let ((map (make-sparse-keymap)))
543; (define-key map [(control ?+)] 'image-scale-in)
544; (define-key map [(control ?-)] 'image-scale-out)
545; (define-key map [(control ?=)] 'image-scale-none)
546;; (define-key map "c f h" 'image-scale-fit-height)
547;; (define-key map "c ]" 'image-rotate-right)
548 map)
549 "Minor mode keymap for transforming the view of images Image mode.")
550
551(define-minor-mode image-transform-mode
552 "minor mode for scaleing and rotation"
553 nil "image-transform"
554 image-transform-minor-mode-map)
555
556;;these are supposed to be buffer local
557;(defvar image-transform-height 100);;nil should mean 100%
558;;the interface could rather be:
559(defvar image-transform-resize
560 nil
561 "values: fit-height number=scale nil=scale100% TODO fit-width fit-page"
562 )
563
564;;TODO 0 90 180 270 degrees are the only reasonable angles here
565;;otherwise combining with rescaling will get very awkward
566(defvar image-transform-rotation 0.0)
567
568;;then it would be nice with a bunch of globals like:
569;; image-transform-always-resize values: 'fit-height nil=100% number=scale TODO 'fit-width 'fit-page
570;; image-transform-always-rotate value: angle
571
572(defun image-transform-properties (display)
573 (let*
574 ((size (image-size display t))
575 (height
576 (cond
577 ((and (numberp image-transform-resize) (eq 100 image-transform-resize))
578 nil)
579 ((numberp image-transform-resize)
580 (* image-transform-resize (cdr size)))
581 ((eq image-transform-resize 'fit-height)
582 (nth 3 (window-inside-pixel-edges)))
583 )))
584 `(,@(if height (list :height height))
585 ,@(if (not (equal 0.0 image-transform-rotation))
586 (list :rotation image-transform-rotation))
587 )))
588
589(defun image-transform-set-scale (scale)
590 (interactive "nscale:")
591 (image-transform-set-resize (float scale)))
592
593(defun image-transform-fit-to-height ()
594 (interactive)
595 (image-transform-set-resize 'fit-height))
596
597(defun image-transform-set-resize (resize)
598 (setq image-transform-resize resize)
599 (image-toggle-display-image))
600
601(defun image-transform-set-rotation (rotation)
602 (interactive "nrotation:")
603 (setq image-transform-rotation (float rotation))
604 (image-toggle-display-image))
605
537(provide 'image-mode) 606(provide 'image-mode)
538 607
539;; arch-tag: b5b2b7e6-26a7-4b79-96e3-1546b5c4c6cb 608;; arch-tag: b5b2b7e6-26a7-4b79-96e3-1546b5c4c6cb
diff --git a/src/image.c b/src/image.c
index 7c6f5645097..217f9221841 100644
--- a/src/image.c
+++ b/src/image.c
@@ -7592,6 +7592,10 @@ enum imagemagick_keyword_index
7592 IMAGEMAGICK_HEURISTIC_MASK, 7592 IMAGEMAGICK_HEURISTIC_MASK,
7593 IMAGEMAGICK_MASK, 7593 IMAGEMAGICK_MASK,
7594 IMAGEMAGICK_BACKGROUND, 7594 IMAGEMAGICK_BACKGROUND,
7595 IMAGEMAGICK_HEIGHT,
7596 IMAGEMAGICK_WIDTH,
7597 IMAGEMAGICK_ROTATION,
7598 IMAGEMAGICK_CROP,
7595 IMAGEMAGICK_LAST 7599 IMAGEMAGICK_LAST
7596 }; 7600 };
7597 7601
@@ -7609,7 +7613,11 @@ static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
7609 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 7613 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7610 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 7614 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7611 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, 7615 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7612 {":background", IMAGE_STRING_OR_NIL_VALUE, 0} 7616 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
7617 {":height", IMAGE_INTEGER_VALUE, 0},
7618 {":width", IMAGE_INTEGER_VALUE, 0},
7619 {":rotation", IMAGE_NUMBER_VALUE, 0},
7620 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
7613 }; 7621 };
7614/* Free X resources of imagemagick image IMG which is used on frame F. */ 7622/* Free X resources of imagemagick image IMG which is used on frame F. */
7615 7623
@@ -7733,14 +7741,15 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */
7733 MagickSetIteratorIndex(image_wand, ino); 7741 MagickSetIteratorIndex(image_wand, ino);
7734 7742
7735 /* If width and/or height is set in the display spec assume we want 7743 /* If width and/or height is set in the display spec assume we want
7736 to scale to those. */ 7744 to scale to those values. if either h or w is unspecified, the
7745 unspecified should be calculated from the specified to preserve
7746 aspect ratio. */
7737 7747
7738 value = image_spec_value (img->spec, QCwidth, NULL); 7748 value = image_spec_value (img->spec, QCwidth, NULL);
7739 desired_width = (INTEGERP (value) ? XFASTINT (value) : -1); 7749 desired_width = (INTEGERP (value) ? XFASTINT (value) : -1);
7740 value = image_spec_value (img->spec, QCheight, NULL); 7750 value = image_spec_value (img->spec, QCheight, NULL);
7741 desired_height = (INTEGERP (value) ? XFASTINT (value) : -1); 7751 desired_height = (INTEGERP (value) ? XFASTINT (value) : -1);
7742 /* TODO if h or w is left out, it should be calculated to preserve aspect ratio */ 7752
7743 /* get original w and h, these will be recalculated before final blit*/
7744 height = MagickGetImageHeight (image_wand); 7753 height = MagickGetImageHeight (image_wand);
7745 width = MagickGetImageWidth (image_wand); 7754 width = MagickGetImageWidth (image_wand);
7746 7755
@@ -7796,15 +7805,6 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */
7796 MagickCropImage(image_wand, w,h, x,y); 7805 MagickCropImage(image_wand, w,h, x,y);
7797 } 7806 }
7798 7807
7799 if (STRINGP (crop) && STRINGP (geometry))
7800 {
7801 printf("MagickTransformImage %s %s\n", SDATA(crop), SDATA(geometry));
7802 image_wand = MagickTransformImage (image_wand, SDATA (crop),
7803 SDATA (geometry));
7804 /* TODO differ between image_wand and transform_wand. */
7805 }
7806
7807
7808 /* Furthermore :rotation. we need background color and angle for 7808 /* Furthermore :rotation. we need background color and angle for
7809 rotation. */ 7809 rotation. */
7810 /* 7810 /*
@@ -7830,8 +7830,8 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */
7830 } 7830 }
7831 } 7831 }
7832 7832
7833 /* Finaly we are done manipulating the image, 7833 /* Finaly we are done manipulating the image, figure out resulting
7834 figure out resulting width, height, and then transfer ownerwship to Emacs. 7834 width, height, and then transfer ownerwship to Emacs.
7835 */ 7835 */
7836 height = MagickGetImageHeight (image_wand); 7836 height = MagickGetImageHeight (image_wand);
7837 width = MagickGetImageWidth (image_wand); 7837 width = MagickGetImageWidth (image_wand);
@@ -7866,9 +7866,7 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */
7866 7866
7867 /* Copy imagegmagick image to x with primitive yet robust pixel 7867 /* Copy imagegmagick image to x with primitive yet robust pixel
7868 pusher loop. This has been tested a lot with many different 7868 pusher loop. This has been tested a lot with many different
7869 images, it doesnt work too well with image archive formats though! 7869 images.
7870
7871 Also seems slow.
7872 */ 7870 */
7873 7871
7874 /* Copy pixels from the imagemagick image structure to the x image map. */ 7872 /* Copy pixels from the imagemagick image structure to the x image map. */
@@ -7901,10 +7899,6 @@ imagemagick_load_image (/* Pointer to emacs frame structure. */
7901 if (imagemagick_rendermethod == 1) 7899 if (imagemagick_rendermethod == 1)
7902 { 7900 {
7903 /* Try if magicexportimage is any faster than pixelpushing. */ 7901 /* Try if magicexportimage is any faster than pixelpushing. */
7904 /* printf("ximg: bitmap_unit:%d format:%d byte_order:%d depth:%d
7905 bits_per_pixel:%d\n", */
7906 /* ximg->bitmap_unit,ximg->format,ximg->byte_order,
7907 ximg->depth,ximg->bits_per_pixel); */
7908 int imagedepth = 24;/*MagickGetImageDepth(image_wand);*/ 7902 int imagedepth = 24;/*MagickGetImageDepth(image_wand);*/
7909 char* exportdepth = imagedepth <= 8 ? "I" : "BGRP";/*"RGBP";*/ 7903 char* exportdepth = imagedepth <= 8 ? "I" : "BGRP";/*"RGBP";*/
7910 /* Try to create a x pixmap to hold the imagemagick pixmap. */ 7904 /* Try to create a x pixmap to hold the imagemagick pixmap. */