fill-opacity different from SVG

The MagickWand interface is a new high-level C API interface to ImageMagick core methods. We discourage the use of the core methods and encourage the use of this API instead. Post MagickWand questions, bug reports, and suggestions to this forum.
Post Reply
rmagick
Posts: 245
Joined: 2006-03-16T17:30:48-07:00
Location: Durham, NC, USA

fill-opacity different from SVG

Post by rmagick »

Image
I'm trying to reproduce this example from the SVG spec (http://www.w3.org/TR/SVG11/masking.html) but I see a discrepency. Notice the 2nd pair of circles from the left on the bottom.

I believe this MVG script is the equivalent of the SVG:

Code: Select all

push graphic-context
 scale 0.355,0.355
 push graphic-context
  fill '#00000000FFFF'
  rectangle 100,100 1100,250
 pop graphic-context
 push graphic-context
  fill-opacity 0.5
  push graphic-context
   fill '#FFFF00000000'
   fill-opacity 1
   circle 382.5,250 432.5,250
  pop graphic-context
  push graphic-context
   fill '#000080800000'
   fill-opacity 1
   circle 417.5,250 467.5,250
  pop graphic-context
 pop graphic-context
pop graphic-context
However, that MVG script produces this pair of entirely opaque circles instead of the .5 opaque circles shown in the SVG example.
Image
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: fill-opacity different from SVG

Post by magick »

ImageMagick can produce MVG from SVG for those SVG graphic elements ImageMagick supports. For your example, type

convert msvg:opacity01.svg opacity01.mvg

You now have the MVG required to produce the image:

Code: Select all

push graphic-context
  viewbox 0 0 340 99
  affine 0.283333 0 0 0.282857 0.0 0.0
  #
  #  Example opacity01 - opacity property
  push graphic-context
    fill 'none'
    stroke 'blue'
    rectangle 1,1 1199,349
  pop graphic-context
  push graphic-context
    fill '#0000ff'
    rectangle 100,100 1100,250
  pop graphic-context
  push graphic-context
    fill 'red'
    opacity '1'
    circle 200,100 200,150
  pop graphic-context
  push graphic-context
    fill 'red'
    opacity '.8'
    circle 400,100 400,150
  pop graphic-context
  push graphic-context
    fill 'red'
    opacity '.6'
    circle 600,100 600,150
  pop graphic-context
  push graphic-context
    fill 'red'
    opacity '.4'
    circle 800,100 800,150
  pop graphic-context
  push graphic-context
    fill 'red'
    opacity '.2'
    circle 1000,100 1000,150
  pop graphic-context
  push graphic-context
    opacity '1'
  push graphic-context
    fill 'red'
    opacity '1'
    circle 182.5,250 182.5,300
  pop graphic-context
  push graphic-context
    fill 'green'
    opacity '1'
    circle 217.5,250 217.5,300
  pop graphic-context
  pop graphic-context
  push graphic-context
    opacity '.5'
  push graphic-context
    fill 'red'
    opacity '1'
    circle 382.5,250 382.5,300
  pop graphic-context
  push graphic-context
    fill 'green'
    opacity '1'
    circle 417.5,250 417.5,300
  pop graphic-context
  pop graphic-context
  push graphic-context
    opacity '1'
  push graphic-context
    fill 'red'
    opacity '.5'
    circle 582.5,250 582.5,300
  pop graphic-context
  push graphic-context
    fill 'green'
    opacity '.5'
    circle 617.5,250 617.5,300
  pop graphic-context
  pop graphic-context
  push graphic-context
    opacity '1'
  push graphic-context
    fill 'green'
    opacity '.5'
    circle 817.5,250 817.5,300
  pop graphic-context
  push graphic-context
    fill 'red'
    opacity '.5'
    circle 782.5,250 782.5,300
  pop graphic-context
  pop graphic-context
  push graphic-context
    opacity '.5'
  push graphic-context
    fill 'red'
    opacity '.5'
    circle 982.5,250 982.5,300
  pop graphic-context
  push graphic-context
    fill 'green'
    opacity '.5'
    circle 1017.5,250 1017.5,300
  pop graphic-context
  pop graphic-context
pop graphic-context
rmagick
Posts: 245
Joined: 2006-03-16T17:30:48-07:00
Location: Durham, NC, USA

Re: fill-opacity different from SVG

Post by rmagick »

Apparently I was not clear about the difference I am questioning. In the ImageMagick output the pair of red & green circles 2nd from the left on the bottom row look like they're entirely opaque, but in the SVG example they are .5 opaque.

Per your advice I downloaded the SVG example and converted it to MVG (the result is of course identical to the MVG file in your reply) and then to PNG with these commands:

Code: Select all

convert msvg:test/.test_opacity01.svg im_opacity01.mvg
convert -size 340x100 im_opacity01.mvg im_opacity01.png
The resulting PNG is:
Image
The SVG example (here) shows the circles to be .5 opaque.
Image
This is ImageMagick 6.5.4-10 2009-08-10 Q16.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: fill-opacity different from SVG

Post by magick »

We can reproduce the problem you reported and have a patch for it available within the next day or two. Thanks.
rmagick
Posts: 245
Joined: 2006-03-16T17:30:48-07:00
Location: Durham, NC, USA

Re: fill-opacity different from SVG

Post by rmagick »

Thanks!
rmagick
Posts: 245
Joined: 2006-03-16T17:30:48-07:00
Location: Durham, NC, USA

Re: fill-opacity different from SVG

Post by rmagick »

Should I be seeing the fix in 6.5.5-2? My test still demonstrates the problem.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: fill-opacity different from SVG

Post by magick »

Post the image you are generating and mention what is wrong with it. In our tests we appear to be getting correct results.
rmagick
Posts: 245
Joined: 2006-03-16T17:30:48-07:00
Location: Durham, NC, USA

Re: fill-opacity different from SVG

Post by rmagick »

We're both right. I guess your test uses the opacity primitive. Since I'm using the MagickWand API, my test uses fill-opacity. The fill-opacity primitive does not produce the desired result.

Here are two versions of the same test. This was created using the DrawSetFillOpacity in the MagickWand API: http://home.roadrunner.com/~foxhunter/f ... city01.mvg. In this version, the 2nd pair of red & green circles on the bottom row is entirely opaque but should be .5 opaque.

Here's the output:
Image.

This version is identical except I changed all uses of the fill-opacity primitive to opacity: http://home.roadrunner.com/~foxhunter/opacity01.mvg. The circles are now .5 opaque as expected. Here's the output:
Image
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: fill-opacity different from SVG

Post by magick »

Looks like we'll need to add DrawSetOpacity() to the API. Give us a day or two. Thanks.
rmagick
Posts: 245
Joined: 2006-03-16T17:30:48-07:00
Location: Durham, NC, USA

Re: fill-opacity different from SVG

Post by rmagick »

I see DrawSetOpacity in 6.5.5-5 and now I have a question. I'm confused about the difference between opacity and fill-opacity so I looked at magick/draw.c. I see that opacity changes the fill opacity as well as the stroke opacity and fill-opacity changes only the fill opacity. However it appears that the opacity value is computed differently for the two. For opacity, it's

Code: Select all

graphic_context[n]->opacity=RoundToQuantum((MagickRealType)
   QuantumRange*(1.0-((1.0-QuantumScale*graphic_context[n]->opacity)*
   factor*atof(token))));
graphic_context[n]->fill.opacity=graphic_context[n]->opacity;
For fill-opacity, it's

Code: Select all

graphic_context[n]->fill.opacity=RoundToQuantum((MagickRealType)
   QuantumRange*(1.0-factor*atof(token)));
That is, the opacity primitive modifies the current opacity value, but fill-opacity just computes a new opacity value w/o referring to the current value. This is what I'd expect just by looking at the results of my tests (above). Is this difference deliberate? I would expect them to be computed the same way.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: fill-opacity different from SVG

Post by magick »

See http://wiki.services.openoffice.org/wik ... ity_in_SVG which differentiates opacity, fill-opacity and stroke-opacity. If after reading you think ImageMagick's implementation is buggy, let us know.
Post Reply