ChatGPT解决这个技术问题 Extra ChatGPT

Does SVG support embedding of bitmap images?

Is an SVG image purely vectorial or can we combine bitmap images into an SVG image ? How about transforms applied on the bitmap images (perspective, mappings, etc.) ?

Edit: Images may be included in an SVG by link reference. See http://www.w3.org/TR/SVG/struct.html#ImageElement. My question was in fact if bitmap images may be included inside the svg so that the svg image would be self contained. Otherwise, whenever the svg image is displayed the link must be followed and the image downloaded. Apparently .svg files are simply xml files.


b
bignose

Yes, you can reference any image from the image element. And you can use data URIs to make the SVG self-contained. An example:

<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">

    ...
    <image
        width="100" height="100"
        xlink:href="data:image/png;base64,IMAGE_DATA"
        />
    ...
</svg>

The svg element attribute xmlns:xlink declares xlink as a namespace prefix and says where the definition is. That then allows the SVG reader to know what xlink:href means.

The IMAGE_DATA is where you'd add the image data as base64-encoded text. Vector graphics editors that support SVG usually have an option for saving with images embedded. Otherwise there are plenty of tools around for encoding a byte stream to and from base64.

Here's a full example from the SVG testsuite.


@Aleksandar that's a separate question, and I'm sure you can find an answer for it on this site (encoding something to base64 is not svg-specific).
@Erik - Suppose i have same image repeated thousand time in same svg file. Can i place base64 data at one place and let image refer to that data from there?
@Erik - Never mind i got my answer from here - stackoverflow.com/questions/16685014/…. Answer talks about grouping there. :)
Don't forget to declare the namespace xlink as is : xmlns:xlink="http://www.w3.org/1999/xlink" some browser/viewer may not see your image without it
FYI: according to my experience the Chrome browser displays this image even if you don't specify widthand height in the svg image tag. However Firefox and IE don't display the image if you omit these attributes. So make sure you specify them!
d
davestewart

I posted a fiddle here, showing data, remote and local images embedded in SVG, inside an HTML page:

http://jsfiddle.net/MxHPq/

<!DOCTYPE html>
<html>
<head>
    <title>SVG embedded bitmaps in HTML</title>
    <style>

        body{
            background-color:#999;
            color:#666;
            padding:10px;
        }

        h1{
            font-weight:normal;
            font-size:24px;
            margin-top:20px;
            color:#000;
        }

        h2{
            font-weight:normal;
            font-size:20px;
            margin-top:20px;
        }

        p{
            color:#FFF;
            }

        svg{
            margin:20px;
            display:block;
            height:100px;
        }

    </style>
</head>

<body>
    <h1>SVG embedded bitmaps in HTML</h1>
    <p>The trick appears to be ensuring the image has the correct width and height atttributes</p>

    <h2>Example 1: Embedded data</h2>
    <svg id="example1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <image x="0" y="0" width="5" height="5" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="/>
    </svg>

    <h2>Example 2: Remote image</h2>
    <svg id="example2" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <image x="0" y="0" width="275" height="95" xlink:href="http://www.google.co.uk/images/srpr/logo3w.png" />
    </svg>

    <h2>Example 3: Local image</h2>
    <svg id="example3" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <image x="0" y="0" width="136" height="23" xlink:href="/img/logo.png" />
    </svg>


</body>
</html>

G
GarethOwen

You could use a Data URI to supply the image data, for example:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

<image width="20" height="20" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="/>

</svg>

The image will go through all normal svg transformations.

But this technique has disadvantages, for example the image will not be cached by the browser


if data URI is required by SVG, then this is presumably no disadvantage - I'll edit my answer
Embedded images (data URIs) will be cached with the document they're in, see e.g stackoverflow.com/questions/4791807/data-uris-and-caching
Exactly - if the svg document changes, the embedded bitmap will be reloaded, even when it is the same. If we link to an http URL, this can be cached separately to the svg document.
Good point. In my comment to Nick's answer you'll see the rational of embedding the bitmap image in the svg image. Though you are right, the encoding is bad and inefficient. It should be a separate binary encoded file moved along with the svg image.
N
Nick

You can use a data: URL to embed a Base64 encoded version of an image. But it's not very efficient and wouldn't recommend embedding large images. Any reason linking to another file is not feasible?


It depends on the use case. The use case I'm considering is where an svg file is copied and internet access is not always available (i.e. business card). IT also allows to keep the use of the card private. With a linked image, the owner of the image could track all displays of its cards which may be interesting for him but not for the card holder. Self contained svg image make sense.
That's true if you use an absolute URL pointing to somewhere on the Internet. But it's easy to use a relative URL so that if the SVG file is local, the image will be too. If you also have the requirement that it has to be one single redistributable file, then that changes things again.
There are use cases for where you want an SVG graphic to be self contained - that is, ONE file that contains the whole image. Having to transport/store multiple files to ensure an image is rendered isn't a good thing when handling images on file systems - things can get out of sync or dropped too easily.
m
mightyplow

It is also possible to include bitmaps. I think you also can use transformations on that.


Indeed. I just found this link : w3.org/TR/SVG/struct.html#ImageElement. Unfortunately it doesn't answer my concern which I noticed is not stated in the question. I'll edit the question.
A
Alex Szücs

If you want to use that image multiple times inside SVG (Ref.):

<image id="img" xlink:href="data:image/png;base64,BASE64_DATA" />

<use href="#img" />
<use href="#img" />