Jump to content

How to inline SVG from image src URL?


theanatoki

Recommended Posts

Hi guys

I am this code currently:

        /**
         * Find all img tags with sources matching "imgix.net" without the parameter
         * "srcset" and add the "srcset" parameter to all those images, appending a new
         * source using the "dpr=2" modifier.
         * 
         * @param $content
         *
         * @return string Content with retina-enriched image tags.
         */
        public function add_retina( $content ) {
                $pattern = '/<img((?![^>]+srcset )([^>]*)';
                $pattern .= 'src=[\'"]([^\'"]*imgix.net[^\'"]*\?[^\'"]*w=[^\'"]*)[\'"]([^>]*)*?)>/i';
                $repl    = '<img$2src="$3" data-srcset="${3}, ${3}&amp;dpr=2&fit=max&q=55 2x, ${3}&amp;dpr=3&fit=max&q=55 3x,"$4>';
                $content = preg_replace( $pattern, $repl, $content );
                $content = preg_replace( '/<img([^>]*)src="([^\'"]*imgix[^\'"]*(png|jpg|jpeg|gif))[^\'"]*/', '<img$1src="$2.svg', $content );
                return $content;
        }

This is the typical output:

<img width="790" height="1" src="https://removed.imgix.net/media/tile-wide2-banner2b.jpg.svg" data-srcset="https://removed.imgix.net/media/tile-wide2-banner2b.jpg?auto=format%2Ccompress&amp;usm=10&amp;w=790&amp;h=1, https://removed.imgix.net/media/tile-wide2-banner2b.jpg?auto=format%2Ccompress&amp;usm=10&amp;w=790&amp;h=1&amp;dpr=2&amp;fit=max&amp;q=55 2x, https://removed.imgix.net/media/tile-wide2-banner2b.jpg?auto=format%2Ccompress&amp;usm=10&amp;w=790&amp;h=1&amp;dpr=3&amp;fit=max&amp;q=55 3x," class="attachment-homepage-wide-banner size-homepage-wide-banner visible" alt="" style="height:454px;object-fit:cover;width:100%;" srcset="https://removed.imgix.net/media/tile-wide2-banner2b.jpg?auto=format%2Ccompress&amp;usm=10&amp;w=790&amp;h=1, https://removed.imgix.net/media/tile-wide2-banner2b.jpg?auto=format%2Ccompress&amp;usm=10&amp;w=790&amp;h=1&amp;dpr=2&amp;fit=max&amp;q=55 2x, https://removed.imgix.net/media/tile-wide2-banner2b.jpg?auto=format%2Ccompress&amp;usm=10&amp;w=790&amp;h=1&amp;dpr=3&amp;fit=max&amp;q=55 3x,">

What I would like is to replace the image src (the SVG) with inline e.g.:

<img width="790" height="1" src="data:image/svg+xml;utf8;urlencoded_svg_here" data-srcset="https://removed.imgix.net/media/tile-wide2-banner2b.jpg?auto=format%2Ccompress&usm=10&w=790&h=1, https://removed.imgix.net/media/tile-wide2-banner2b.jpg?auto=format%2Ccompress&usm=10&w=790&h=1&dpr=2&fit=max&q=55 2x, https://removed.imgix.net/media/tile-wide2-banner2b.jpg?auto=format%2Ccompress&usm=10&w=790&h=1&dpr=3&fit=max&q=55 3x," class="attachment-homepage-wide-banner size-homepage-wide-banner visible" alt="" style="height:454px;object-fit:cover;width:100%;" srcset="https://removed.imgix.net/media/tile-wide2-banner2b.jpg?auto=format%2Ccompress&usm=10&w=790&h=1, https://removed.imgix.net/media/tile-wide2-banner2b.jpg?auto=format%2Ccompress&usm=10&w=790&h=1&dpr=2&fit=max&q=55 2x, https://removed.imgix.net/media/tile-wide2-banner2b.jpg?auto=format%2Ccompress&usm=10&w=790&h=1&dpr=3&fit=max&q=55 3x,">

I know the function rawurlencode doesn't play all that nicely with inlining SVGs so have found a function which (theoretically) fixes this issue, below:

function svgUrlEncode($svgPath)
{
$data = \file_get_contents($svgPath);
$data = \preg_replace('/\v(?:[\v\h]+)/', ' ', $data);
$data = \str_replace('"', "'", $data);
$data = \rawurlencode($data);
$data = \str_replace('%20', ' ', $data);
$data = \str_replace('%3D', '=', $data);
$data = \str_replace('%3A', ':', $data);
$data = \str_replace('%2F', '/', $data);
return $data;
}

The SVG is housed locally on the webserver so preference would be to use this rather than fetch and parse the imgix.net hosted file. The folder structure is the same i.e. /media/tile-wide2-banner2b.jpg.svg. I have dabbled with preg_replace_callback but I am far from being proficient in PHP by any stretch of the imagination. Would anyone be able to assist in pointing me in the right direction?

Thanks!

Link to comment
Share on other sites

Figured it out. Full code below for anyone who stumbles upon this. May not be the most efficient however there's a cache layer above.

        public function add_retina( $content ) {
                $pattern = '/<img((?![^>]+srcset )([^>]*)';
                $pattern .= 'src=[\'"]([^\'"]*imgix.net[^\'"]*\?[^\'"]*w=[^\'"]*)[\'"]([^>]*)*?)>/i';
                $repl    = '<img$2src="$3" data-srcset="${3}, ${3}&amp;dpr=2&fit=max&q=55 2x, ${3}&amp;dpr=3&fit=max&q=55 3x,"$4>';
                $content = preg_replace( $pattern, $repl, $content );
                $content = preg_replace( '/<img([^>]*)src="([^\'"]*imgix[^\'"]*(png|jpg|jpeg|gif))[^\'"]*/', '<img$1src="$2.svg', $content );
                $content = preg_replace_callback ( '/([^\'"]*imgix[^\'"]*(svg))[^\'"]*/', function($matches) {
                        $matches = str_replace('https://removed.imgix.net', '/var/www/removed/public', $matches[0]);
                        $matches = explode("?", $matches);
                        $matches = $matches[0];
                        $data = \file_get_contents($matches);
                        $data = \preg_replace('/\v(?:[\v\h]+)/', ' ', $data);
                        $data = \str_replace('"', "'", $data);
                        $data = \rawurlencode($data);
                        $data = \str_replace('%27', '\'', $data);
                        $data = \str_replace('%20', ' ', $data);
                        $data = \str_replace('%3D', '=', $data);
                        $data = \str_replace('%3A', ':', $data);
                        $data = \str_replace('%2F', '/', $data);
                        $data = "data:image/svg+xml," . $data;
                return $data;
                        }, $content );
                return $content;
        }

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.