适用于 Android 的 chrome 中的模糊 SVG 图像

Posted

技术标签:

【中文标题】适用于 Android 的 chrome 中的模糊 SVG 图像【英文标题】:Blurry SVG images in chrome for Android 【发布时间】:2012-11-07 14:31:54 【问题描述】:

为了摆脱手机中不同像素密度的地狱,我在我的 css 中使用 SVG 文件作为背景图像。

Chrome for android 似乎可以很好地呈现 inline-svg,但如果 svg 则失败

在css中使用background-image和一个普通的url 在 css 中使用 background-image 和一个数据 uri 与image 元素一起使用

android 4 的股票浏览器运行良好。 (以及我尝试过的所有其他手机)

您可以访问this fiddle 并查看。放大以查看差异。

有人知道为什么 chrome 在这里使用一些预渲染的位图吗?

【问题讨论】:

嗯,很奇怪,只有 inline-svg 元素是锐利的。 很高兴知道,所以这不是我的眼睛 :) 我在 Nexus 7 上遇到了一个问题,所有 SVG 看起来都很好,除了蓝色背景上的会议标题。它模糊到看起来就像白雾一样。 summit.usu.edu 这是一个 img 元素。什么是“内联 svg”? 我也遇到了这个错误。它在铬问题跟踪器中提到:code.google.com/p/chromium/issues/detail?id=161982 它被列为已修复,将于 2013 年初更新 chrome 时推出。我正在使用 android 4.2.2 和 chrome 18.0.1025469 测试新的 nexus 4,但它仍然损坏。 +1 - 使用 SVG 作为背景图像时遇到同样的问题。奇怪的是,如果我放大和缩小,有时 SVG 会呈现清晰。其余时间看起来很糟糕。 【参考方案1】:

正如其他答案在这个问题和其他类似问题中指出的那样,SVG 的渲染在 chrome 和本机 android 网络浏览器中存在问题。这是一个已知的 chrome / native 浏览器问题。

在几天内查看了许多解决方案后,我偶然发现了这种解决方法。诀窍是在 SVG 文件中嵌入文本,这可以是单个透明字符。

例如,将这个(或类似的)添加到您的 SVG 文件中。

<text transform="matrix(1 0 0 1 7.1079 13.5215)" opacity="0" font-family="'MyriadPro-Regular'" font-size="12">a</text>

在不调查实际的 chrome 源或进程的情况下,我只能假设通过嵌入文本会强制 SVG 在放大时针对高 dpi 设备进行重新渲染。

无论背景图像元素如何使用、旋转、固定位置等,此解决方案(在我已经能够在 Android/Chrome 上测试的浏览器上)都有效。甚至在缩放下似乎也很清晰。

享受吧!

【讨论】:

这正是解决方案!就像魔法一样。另一件事,我的 Ionic 应用程序上有 snap.svg 库。该动画也不适用于Android。 SVG 现在很清楚你的 hack 了。但是动画仍然没有显示...【参考方案2】:

这是一个已知问题https://code.google.com/p/chromium/issues/detail?id=161982

当 SVG 被渲染为图像(或背景图像)时,它最初被渲染为 CSS 像素密度,这使得它在 1 CSS 像素!= 1 设备像素的设备上变得模糊,其中包括大多数高端 Android 手机。

该问题已在 Chrome 25(撰写本文时的当前版本)中得到修复,但是当您放大视口时图像再次变得模糊。

此问题已在 Chrome 26(当前为 Chrome Beta,可在 Play 商店中获得)中得到修复,SVG 图像和背景仍然清晰。

【讨论】:

+1 - “它最初被渲染为 CSS 像素密度,在 1 CSS px != 1 device px 的设备上变得模糊”。很好的解释;这正是我看到的行为,导致图像看起来比光栅图形(PNG、JPEG、BMP 等)差得多。【参考方案3】:

对我来说,我花了很长时间才发现的解决方案是我的元素 css:

border-radius: 4px;

这解决了我的问题,但是我无法在我一直在工作的网站上重新创建它,但这是我试图在移动设备上重新创建问题的小提琴:

http://jsfiddle.net/rc8Hh/31/

祝你好运,我建议检查是否存在可能影响元素绘制的类。

【讨论】:

【参考方案4】:

如果您要插入 SVG 文件,该文件将被(取决于主机,例如 Wikipedia)预渲染。因此,在加载时,图像将呈现给定的大小。内联 SVG(直接编码到页面)将在页面重新调整大小时重新调整大小。但是,我不确定移动浏览器,因为它们不会调整页面中元素的大小,它们只是“缩放”

所以基本上你正在做的是将 SVG 绘制到画布上(双关语!)然后缩放画布。内联有直接的 SVG...所以更好....

【讨论】:

【参考方案5】:

就我而言,我发现罪魁祸首是过滤器属性

<g filter="url(#filter0_d)">

通过删除 filter 属性,SVG 被渲染为矢量而不是位图。

<g>

为了更好的衡量,我也删除了&lt;filter&gt; 标签

<filter id="filter0_d" x="-261" y="50"   filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset/>
<feGaussianBlur stdDeviation="12.5"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>

【讨论】:

以上是关于适用于 Android 的 chrome 中的模糊 SVG 图像的主要内容,如果未能解决你的问题,请参考以下文章

适用于 Android 的 Material Components 中的切换按钮

无法从 Flutter Web 读取 Firestore 中的数据(适用于 iOS 和 android)

android通知适用于循环中的一个对象[重复]

适用于 Android 的 phonegap 中的 WebSocket HTML5

适用于 Android 和 iOS 的 React Native 中的警报功能

没有方法签名: .android() 适用于参数类型。 build.gradle(应用程序)中的异常