Support transparency for ImageMagick images.
* src/image.c (imagemagick_load_image): Implement transparency. * doc/lispref/display.texi (ImageMagick Images): ImageMagick now supports the :background property.
This commit is contained in:
parent
05ecb49739
commit
1b9b4cf4c1
5 changed files with 76 additions and 57 deletions
|
@ -1,3 +1,8 @@
|
|||
2012-06-11 Chong Yidong <cyd@gnu.org>
|
||||
|
||||
* display.texi (ImageMagick Images): ImageMagick now supports the
|
||||
:background property.
|
||||
|
||||
2012-06-10 Dmitry Antipov <dmantipov@yandex.ru>
|
||||
|
||||
* internals.texi (Garbage Collection): Typo fix.
|
||||
|
|
|
@ -4603,6 +4603,12 @@ JPEG files, add @code{JPG} to this list.
|
|||
image descriptor properties:
|
||||
|
||||
@table @code
|
||||
@item :background @var{background}
|
||||
@var{background}, if non-@code{nil}, should be a string specifying a
|
||||
color, which is used as the image's background color if the image
|
||||
supports transparency. If the value is @code{nil}, it defaults to the
|
||||
frame's background color.
|
||||
|
||||
@item :width, :height
|
||||
The @code{:width} and @code{:height} keywords are used for scaling the
|
||||
image. If only one of them is specified, the other one will be
|
||||
|
|
3
etc/NEWS
3
etc/NEWS
|
@ -80,6 +80,9 @@ ImageMagick types are treated as images. The function
|
|||
`imagemagick-filter-types' returns the list of types that will be
|
||||
treated as images.
|
||||
|
||||
*** Images displayed via ImageMagick now support transparency and the
|
||||
:background image spec property.
|
||||
|
||||
** String values for `initial-buffer-choice' also apply to emacsclient
|
||||
frames, if emacsclient is only told to open a new frame without
|
||||
specifying any file to visit or expression to evaluate.
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2012-06-11 Chong Yidong <cyd@gnu.org>
|
||||
|
||||
* image.c (imagemagick_load_image): Implement transparency.
|
||||
|
||||
2012-06-10 Andreas Schwab <schwab@linux-m68k.org>
|
||||
|
||||
* regex.c (at_begline_loc_p): Also recognize `(?N:' and correctly
|
||||
|
|
115
src/image.c
115
src/image.c
|
@ -7599,19 +7599,14 @@ imagemagick_load_image (struct frame *f, struct image *img,
|
|||
unsigned char *contents, unsigned int size,
|
||||
char *filename)
|
||||
{
|
||||
size_t width;
|
||||
size_t height;
|
||||
|
||||
size_t width, height;
|
||||
MagickBooleanType status;
|
||||
|
||||
XImagePtr ximg;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
MagickWand *image_wand;
|
||||
MagickWand *ping_wand;
|
||||
int x, y;
|
||||
MagickWand *image_wand;
|
||||
MagickWand *ping_wand;
|
||||
PixelIterator *iterator;
|
||||
PixelWand **pixels;
|
||||
PixelWand **pixels, *bg_wand = NULL;
|
||||
MagickPixelPacket pixel;
|
||||
Lisp_Object image;
|
||||
Lisp_Object value;
|
||||
|
@ -7620,10 +7615,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
|
|||
int desired_width, desired_height;
|
||||
double rotation;
|
||||
int pixelwidth;
|
||||
ImageInfo *image_info;
|
||||
ExceptionInfo *exception;
|
||||
Image * im_image;
|
||||
|
||||
|
||||
/* Handle image index for image types who can contain more than one image.
|
||||
Interface :index is same as for GIF. First we "ping" the image to see how
|
||||
|
@ -7637,14 +7628,9 @@ imagemagick_load_image (struct frame *f, struct image *img,
|
|||
ping_wand = NewMagickWand ();
|
||||
/* MagickSetResolution (ping_wand, 2, 2); (Bug#10112) */
|
||||
|
||||
if (filename != NULL)
|
||||
{
|
||||
status = MagickPingImage (ping_wand, filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MagickPingImageBlob (ping_wand, contents, size);
|
||||
}
|
||||
status = filename
|
||||
? MagickPingImage (ping_wand, filename)
|
||||
: MagickPingImageBlob (ping_wand, contents, size);
|
||||
|
||||
if (status == MagickFalse)
|
||||
{
|
||||
|
@ -7653,7 +7639,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (! (0 <= ino && ino < MagickGetNumberImages (ping_wand)))
|
||||
if (ino < 0 || ino >= MagickGetNumberImages (ping_wand))
|
||||
{
|
||||
image_error ("Invalid image number `%s' in image `%s'",
|
||||
image, img->spec);
|
||||
|
@ -7670,39 +7656,46 @@ imagemagick_load_image (struct frame *f, struct image *img,
|
|||
DestroyMagickWand (ping_wand);
|
||||
|
||||
/* Now we know how many images are inside the file. If it's not a
|
||||
bundle, the number is one. */
|
||||
bundle, the number is one. Load the image data. */
|
||||
|
||||
if (filename != NULL)
|
||||
image_wand = NewMagickWand ();
|
||||
|
||||
if ((filename
|
||||
? MagickReadImage (image_wand, filename)
|
||||
: MagickReadImageBlob (image_wand, contents, size))
|
||||
== MagickFalse)
|
||||
{
|
||||
image_info = CloneImageInfo ((ImageInfo *) NULL);
|
||||
(void) strcpy (image_info->filename, filename);
|
||||
image_info->number_scenes = 1;
|
||||
image_info->scene = ino;
|
||||
exception = AcquireExceptionInfo ();
|
||||
|
||||
im_image = ReadImage (image_info, exception);
|
||||
DestroyExceptionInfo (exception);
|
||||
|
||||
if (im_image == NULL)
|
||||
goto imagemagick_no_wand;
|
||||
image_wand = NewMagickWandFromImage (im_image);
|
||||
DestroyImage (im_image);
|
||||
}
|
||||
else
|
||||
{
|
||||
image_wand = NewMagickWand ();
|
||||
if (MagickReadImageBlob (image_wand, contents, size) == MagickFalse)
|
||||
{
|
||||
imagemagick_error (image_wand);
|
||||
goto imagemagick_error;
|
||||
}
|
||||
imagemagick_error (image_wand);
|
||||
goto imagemagick_error;
|
||||
}
|
||||
|
||||
/* Retrieve the frame's background color, for use later. */
|
||||
{
|
||||
XColor bgcolor;
|
||||
Lisp_Object specified_bg;
|
||||
|
||||
specified_bg = image_spec_value (img->spec, QCbackground, NULL);
|
||||
if (!STRINGP (specified_bg)
|
||||
|| !x_defined_color (f, SSDATA (specified_bg), &bgcolor, 0))
|
||||
{
|
||||
#ifndef HAVE_NS
|
||||
bgcolor.pixel = FRAME_BACKGROUND_PIXEL (f);
|
||||
x_query_color (f, &bgcolor);
|
||||
#else
|
||||
ns_query_color (FRAME_BACKGROUND_COLOR (f), &bgcolor, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
bg_wand = NewPixelWand ();
|
||||
PixelSetRed (bg_wand, (double) bgcolor.red / 65535);
|
||||
PixelSetGreen (bg_wand, (double) bgcolor.green / 65535);
|
||||
PixelSetBlue (bg_wand, (double) bgcolor.blue / 65535);
|
||||
}
|
||||
|
||||
/* If width and/or height is set in the display spec assume we want
|
||||
to scale to those values. If either h or w is unspecified, the
|
||||
unspecified should be calculated from the specified to preserve
|
||||
aspect ratio. */
|
||||
|
||||
value = image_spec_value (img->spec, QCwidth, NULL);
|
||||
desired_width = (INTEGERP (value) ? XFASTINT (value) : -1);
|
||||
value = image_spec_value (img->spec, QCheight, NULL);
|
||||
|
@ -7768,13 +7761,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
|
|||
value = image_spec_value (img->spec, QCrotation, NULL);
|
||||
if (FLOATP (value))
|
||||
{
|
||||
PixelWand* background = NewPixelWand ();
|
||||
PixelSetColor (background, "#ffffff");/*TODO remove hardcode*/
|
||||
|
||||
rotation = extract_float (value);
|
||||
|
||||
status = MagickRotateImage (image_wand, background, rotation);
|
||||
DestroyPixelWand (background);
|
||||
status = MagickRotateImage (image_wand, bg_wand, rotation);
|
||||
if (status == MagickFalse)
|
||||
{
|
||||
image_error ("Imagemagick image rotate failed", Qnil, Qnil);
|
||||
|
@ -7788,6 +7776,18 @@ imagemagick_load_image (struct frame *f, struct image *img,
|
|||
height = MagickGetImageHeight (image_wand);
|
||||
width = MagickGetImageWidth (image_wand);
|
||||
|
||||
/* Set the canvas background color to the frame or specified
|
||||
background, and flatten the image. Note: as of ImageMagick
|
||||
6.6.0, SVG image transparency is not handled properly
|
||||
(e.g. etc/images/splash.svg shows a white background always). */
|
||||
{
|
||||
MagickWand *new_wand;
|
||||
MagickSetImageBackgroundColor (image_wand, bg_wand);
|
||||
new_wand = MagickMergeImageLayers (image_wand, MergeLayer);
|
||||
DestroyMagickWand (image_wand);
|
||||
image_wand = new_wand;
|
||||
}
|
||||
|
||||
if (! (width <= INT_MAX && height <= INT_MAX
|
||||
&& check_image_size (f, width, height)))
|
||||
{
|
||||
|
@ -7895,7 +7895,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
|
|||
width, height,
|
||||
exportdepth,
|
||||
pixelwidth,
|
||||
/*&(img->pixmap));*/
|
||||
ximg->data);
|
||||
#else
|
||||
image_error ("You don't have MagickExportImagePixels, upgrade ImageMagick!",
|
||||
|
@ -7910,7 +7909,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
|
|||
free_color_table ();
|
||||
#endif /* COLOR_TABLE_SUPPORT */
|
||||
|
||||
|
||||
img->width = width;
|
||||
img->height = height;
|
||||
|
||||
|
@ -7919,9 +7917,10 @@ imagemagick_load_image (struct frame *f, struct image *img,
|
|||
x_put_x_image (f, ximg, img->pixmap, width, height);
|
||||
x_destroy_x_image (ximg);
|
||||
|
||||
|
||||
/* Final cleanup. image_wand should be the only resource left. */
|
||||
DestroyMagickWand (image_wand);
|
||||
if (bg_wand) DestroyPixelWand (bg_wand);
|
||||
|
||||
/* `MagickWandTerminus' terminates the imagemagick environment. */
|
||||
MagickWandTerminus ();
|
||||
|
||||
|
@ -7929,6 +7928,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
|
|||
|
||||
imagemagick_error:
|
||||
DestroyMagickWand (image_wand);
|
||||
if (bg_wand) DestroyPixelWand (bg_wand);
|
||||
|
||||
imagemagick_no_wand:
|
||||
MagickWandTerminus ();
|
||||
/* TODO more cleanup. */
|
||||
|
|
Loading…
Add table
Reference in a new issue