PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Sunday, September 18, 2022

[FIXED] How to resize SVG with PHP?

 September 18, 2022     image-resizing, imagick, php, svg     No comments   

Issue

I am trying to resize (increase size) a SVG inside a PHP script and save it as a new SVG. Given SVG is generated by another script. It contains image and texts.

I have tried with imagick, but the generated svg is broken, and doesn't include any of the contents.

This is how I have done:

$image = new Imagick();
$image->setResolution(2000,2000);
$image->readImage('/pathe/to/my/svg.svg');
$image->scaleImage(1000,1000);
file_put_contents('/pathe/to/my/new.svg', $image->getImageBlob());

Solution

Consider that "SVG" stands for "Scalable Vector Grafics".

  1. Imagick is a library for manipulating pixel-oriented grafics and as such unfit for vector grafic formats like SVG.

  2. SVGs are by their nature scalable. In most cases you will not need to rewrite them to change their size. If you display SVGs inside a webpage (via <img> or <object> tags, or as a CSS background-image, it will be displayed at the size defined for these elements, and if there is size information stored in the SVG file, that will be simply ignored. (Note that a lot of SVG files contain no display size information at all.)

  3. The only case you may need to set size information in the SVG file is if you display it as a standalone file (for example if you have a link pointing to the .svg itself).

    In this case, you can take advantage of the fact that SVG is a XML file:

    $dom = new DOMDocument('1.0', 'utf-8');
    $dom->load('/pathe/to/my/svg.svg');
    $svg = $dom->documentElement;
    
    if ( ! $svg->hasAttribute('viewBox') ) { // viewBox is needed to establish
                                             // userspace coordinates
         $pattern = '/^(\d*\.\d+|\d+)(px)?$/'; // positive number, px unit optional
    
         $interpretable =  preg_match( $pattern, $svg->getAttribute('width'), $width ) &&
                           preg_match( $pattern, $svg->getAttribute('height'), $height );
    
         if ( $interpretable ) {
            $view_box = implode(' ', [0, 0, $width[0], $height[0]]);
            $svg->setAttribute('viewBox', $view_box);
        } else { // this gets sticky
             throw new Exception("viewBox is dependent on environment");
        }
    }
    
    $svg->setAttribute('width', '1000');
    $svg->setAttribute('height', '1000');
    $dom->save('/pathe/to/my/new.svg');
    

    There are some tricky cases if the element has no viewBox attribute and the width and height have non-px units. Handling them requires a deeper understanding of SVG. It would be best to assure that the SVG files produced by the "other script" always have a viewBox. Then the conditional section can be left out.

    The term "resolution" is inapplicable for vector grafics. Width and height can be dimensionless numbers (representing pixel for the purpose of rendering into an output device, for example the screen), or any valid CSS length unit: em, ex, px, pt, pc, cm, mm, in, and percentages.



Answered By - ccprog
Answer Checked By - Senaida (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing