Stephan Cilliers
Stephan Cilliers

Reputation: 71

Scaled up low resolution pixel image element in SVG blurry on Safari, but not in Firefox and Chrome

This is what it looks like in Chrome and Firefox: Rendered in Firefox and Chrome

This is what it looks like in Safari: enter image description here

I have tried the commonly suggested

image {
      image-rendering: optimizeSpeed;     
      image-rendering: -moz-crisp-edges;          
      image-rendering: -o-crisp-edges;       
      image-rendering: -webkit-optimize-contrast;
      image-rendering: pixelated; 
      image-rendering: optimize-contrast;      
      -ms-interpolation-mode: nearest-neighbor;  
}

This is my SVG code:

<svg viewBox="0 0 50 50" width="500" xmlns="http://www.w3.org/2000/svg" >
  <defs>
  <style>
    image, svg, use, #character { 
      image-rendering: optimizeSpeed;     
      image-rendering: -moz-crisp-edges;          
      image-rendering: -o-crisp-edges;       
      image-rendering: -webkit-optimize-contrast;
      image-rendering: pixelated; 
      image-rendering: optimize-contrast;      
      -ms-interpolation-mode: nearest-neighbor;  
    } 
    svg { background : #1A1A1A; 
    -webkit-transform: translate3d(0,0,0)}
  </style>
    <svg width="50" height="50" viewBox="100 0 50 50">
      <image id="skeleton" preserveAspectRatio="xMinYMin slice" href="data:image/png;charset:utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAZklEQVR4nO3XQQ6AIAwEQPD/f64nE/WoLFEy84CWppSG1gAASOnJ4FVVl2S9x/JtqcBLOTpy70xCvCMzi4mZefhlhh1CXt/Zp3PwufkZ8TKNiGGzA0DaeWOn/ybLbPZlCgEAAH5nBzIvM+pVaumQAAAAAElFTkSuQmCC"></image>
    </svg>
  </defs>

  <svg id="character">
    <svg width="50" height="50" viewBox="0 0 50 50">
      <use href="#skeleton"></use>
    </svg>
  </svg>
</svg>

Upvotes: 3

Views: 3914

Answers (2)

Johannes
Johannes

Reputation: 411

As of 2024 Safari is still rendering foreignObject in SVGs blurry/ pixelated with 72dpi or less. A quick fix is to use the svg transform property on the <foreignObject> and a wrapping <g> element. Choose a high scale e.g. 1000, so even in full size the image is rendered sharp.

In my case it did render only the mask for a conic gradient blurry.

<g transform="scale(0.001)">
  <foreignObject
    transform="scale(1000)"
    x="0" 
    y="0" 
    width="100%" 
    height="100%" 
    mask="url(#mask)" 
  >
    <div xmlns="http://www.w3.org/1999/xhtml" style="width: 100%; height: 100%; background: conic-gradient(from 225deg at 19px 13px, #FE653F, #111111); background-color: #FE653F;">
    </div>
  </foreignObject>
</g>

Upvotes: 1

herrstrietzel
herrstrietzel

Reputation: 17215

Apparently, safari can't apply the image-rendering property on svg <image> elements (works fine for <img>elements).

As a workaround you might use a background-image instead:

.svgBGforeign{
  width:500px; 
  height:500px;
  background-color : #1A1A1A; 
}
.svgBG{
  width:500px; 
  height:500px;
  background-color : #1A1A1A; 
  background-image: url(data:image/png;charset:utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAZklEQVR4nO3XQQ6AIAwEQPD/f64nE/WoLFEy84CWppSG1gAASOnJ4FVVl2S9x/JtqcBLOTpy70xCvCMzi4mZefhlhh1CXt/Zp3PwufkZ8TKNiGGzA0DaeWOn/ybLbPZlCgEAAH5nBzIvM+pVaumQAAAAAElFTkSuQmCC);
  background-repeat:no-repeat;
  background-size:100%
}

.pixelated  { 
    image-rendering: -webkit-optimize-contrast;
-ms-interpolation-mode: nearest-neighbor;
    image-rendering: -moz-crisp-edges;
    image-rendering: pixelated;
    } 
<p>Foreign Object</p>
   <svg class="svgBGforeign pixelated" viewBox="0 0 50 50"  xmlns="http://www.w3.org/2000/svg" >
  <svg class="pixelated" viewBox="0 0 50 50"  xmlns="http://www.w3.org/2000/svg" >
     <foreignObject x="0" y="0" width="100%" height="100%">
       <img src="data:image/png;charset:utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAZklEQVR4nO3XQQ6AIAwEQPD/f64nE/WoLFEy84CWppSG1gAASOnJ4FVVl2S9x/JtqcBLOTpy70xCvCMzi4mZefhlhh1CXt/Zp3PwufkZ8TKNiGGzA0DaeWOn/ybLbPZlCgEAAH5nBzIvM+pVaumQAAAAAElFTkSuQmCC">
     </foreignObject>
    <circle cx="75%" cy="75%" r="5%" fill="#fff"></circle>
     </svg>
  </svg>

<p>Background image for parent svg</p>
<svg class="svgBG pixelated" viewBox="0 0 50 50"  xmlns="http://www.w3.org/2000/svg" >
    <circle cx="75%" cy="75%" r="5%" fill="#fff"></circle>
  </svg>

Upvotes: 1

Related Questions