SVG 1.1 section 5.7 says that when an 'image' element references a raster image the implicit 'viewBox' has a value of "0 0 raster-image-width raster-image-height".
This makes it difficult to cut out parts of raster images, such as an image that contains a multiple of sub-images, e.g like in this example Since this implicit viewbox can't be controlled you are forced to use other less intuitive methods (which are often more expensive) of getting the part of the raster image you want. E.g. clip, mask, pattern, clip-path to cut out a part of the image. In the www-svg discussion thread a question asked was why not use 'clip' to do this instead. One problem is that 'clip' only affects elements that establish viewports, and thus you'd need to use such an element as a wrapper, e.g an 'svg' element.
Currently the situation is that the author controls the viewport (destination) rectangle directly, but the viewbox (source) rectangle only indirectly for rendering an 'image' element.
If the 'image' element references a raster image and has a 'viewBox' attribute, then the 'viewBox' defines which part of the raster image to draw into the viewport (destination) rectangle.
The 'image' element indicates that the contents of a complete file are to be rendered into a given rectangle within the current user coordinate system. The 'image' element can refer to raster image files such as PNG or JPEG or to files with MIME type of "image/svg+xml". Conforming SVG viewers need to support at least PNG, JPEG and SVG format files.
The result of processing an 'image' is always a four-channel RGBA result. When an 'image' element references a raster image file such as PNG or JPEG files which only has three channels (RGB), then the effect is as if the object were converted into a 4-channel RGBA image with the alpha channel uniformly set to 1. For a single-channel raster image, the effect is as if the object were converted into a 4-channel RGBA image, where the single channel from the referenced object is used to compute the three color channels and the alpha channel is uniformly set to 1.
An 'image' element establishes a new viewport for the referenced file as described in Establishing a new viewport. The bounds for the new viewport are defined by attributes x, y, width and height. The placement and scaling of the referenced image are controlled by the preserveAspectRatio attribute on the 'image' element.
When an 'image' element references an SVG image the preserveAspectRatio attribute as well as the clip and overflow properties on the root element in the referenced SVG image are ignored (in the same manner as the x, y, width and height attributes are ignored). Instead, the preserveAspectRatio attribute on the referencing 'image' element defines how the SVG image content is fitted into the viewport and the clip and overflow properties on the 'image' element define how the SVG image content is clipped (or not) relative to the viewport.
The value of the 'viewBox' attribute to use when
evaluating the preserveAspectRatio attribute is
defined by the referenced content. For content that clearly
identifies a viewBox (e.g. an SVG file with the 'viewBox' attribute on the
outermost svg element) that value should be used.
For most
raster content (PNG, JPEG) the bounds of the image should be
used (i.e. the 'image'
element has an implicit 'viewBox' of "0 0 raster-image-width
raster-image-height").
For most
raster content (PNG, JPEG) the bounds of the image should be
used (i.e. the 'image'
element has an implicit 'viewBox' of "0 0 raster-image-width
raster-image-height"), however if a 'viewBox' is specified it
overrides the implicit 'viewBox'. When a 'viewBox' for raster content
is specified, any negative values for in the 'viewBox' will be clamped to zero,
and values larger than the native dimensions of the raster image will be clamped to the native width and height respectively.
Where no value is readily available
(e.g. an SVG file with no 'viewBox' attribute on the
outermost 'svg' element) the preserveAspectRatio attribute is
ignored, and only the translate due to the 'x' & 'y' attributes of the viewport is
used to display the content.
For example, if the image element referenced a PNG or JPEG
and preserveAspectRatio="xMinYMin
meet", then the aspect ratio of the raster would be
preserved (which means that the scale factor from image's
coordinates to current user space coordinates would be the same
for both X and Y), the raster would be sized as large as
possible while ensuring that the entire raster fits within the
viewport, and the top/left of the raster would be aligned with
the top/left of the viewport as defined by the attributes 'x', 'y', 'width' and 'height' on the 'image' element. If the value
of preserveAspectRatio was 'none'
then aspect ratio of the image would not be preserved. The
image would be fitted such that the top/left corner of the
raster exactly aligns with coordinate (x, y) and the bottom/right corner of
the raster exactly aligns with coordinate (x+width,y+height).
The resource referenced by the 'image' element represents a
separate document which generates its own parse tree and
document object model (if the resource is XML). Thus, there is
no inheritance of properties into the image.
Unlike 'use', the 'image' element cannot reference
elements within an SVG file.
Live svg test | Reference image | Legacy behaviour (Batik 1.7) |
---|---|---|
struct-image-1xx-f.svg. | ||
struct-image-1x1-f.svg. |
In some scenarios it may help if it's possible to define the 'viewBox' as percentage values relative to the native dimensions of the raster image.