2017-06-10 151 views
0

我正在尝试设置一个Daltonian过滤器(即模拟各种类型的色盲),但是,我为此使用的SVG完全失败。 Firefox以背景颜色显示所有内容(尽管呈现所有内容,但绝对不可见),并且Chrome正常显示页面。SVG过滤器根本不起作用

由于我在转化值从数据库中读取,通过该Perl脚本生成的SVG:

#!/usr/bin/perl -wT -I /srv/www1/cgi-lib 

use strict; 
use DBI; 
use helpers qw(aindex); 

my $dbname = 'DBI:mysql:<dbname>'; 
my $dbuser = '<dbuser>'; 
my $passwd = '<dbpass>'; 

my $p_http_ver = $ENV{'SERVER_PROTOCOL'}; 

my $p_debug = 0; 

if($p_debug) 
    { 
    print "Content-Type: text/plain; charset=utf-8\n\n"; 
    } 

sub get_params 
    { 
my ($l_script, $l_paramstr) = split(/\?/, $ENV{'REQUEST_URI'}); 

    return undef if(!defined $l_paramstr); 

my @l_paramlist = split(/[&;]/, $l_paramstr); 
my $l_this; 
my %l_params = (); 

    foreach $l_this (@l_paramlist) 
    { 
my ($l_var, $l_value) = split(/=/, $l_this); 

    next if(!defined $l_value); 

    $l_value =~ s/\+/ /g; 
    $l_value =~ s/%([0-9a-fA-F]{2})/pack("C", hex($1))/eg; 

    $l_params{$l_var} = $l_value; 
    } 

    return \%l_params; 
    } 

my $params = get_params(); 
my %matrix = (); 
my @valid_modes = ('normal', 'protanopia', 'protanomaly', 'deuteranopia', 'deuteranomaly', 'tritanopia', 'tritanomaly', 'achromatopsia', 'achromatomaly'); 

foreach (@valid_modes) 
    { 
# Fill in the normal matrix: Default for database failures! 
    $matrix{$_} = [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]; 
    } 

my $p_mode = ${$params}{'mode'}; 
$p_mode = 'normal' if(!defined $p_mode); 
$p_mode = 'normal' if(aindex(@valid_modes, $p_mode) == -1); 

print "Content-Type: image/svg+xml; charset=utf-8\n"; 
print "Expires: -60s\n"; 
print "Pragma: no-cache\n" if($p_http_ver eq 'HTTP/1.0'); 
print "Cache-Control: no-cache, no-store, must-revalidate\n" if($p_http_ver eq 'HTTP/1.1'); 

# Empty line to end the header section... 
print "\n"; 

my $dbh = DBI->connect($dbname, $dbuser, $passwd, { PrintError => 0, AutoCommit => 0 }); 
if($dbh) 
    { 
my $l_sth; 
my @l_row; 
my $l_i; 

    $l_sth = $dbh->prepare(qq{select * from dalton}); 
    $l_sth->execute(); 

    while(@l_row = $l_sth->fetchrow_array) 
    { 
    for($l_i = 0; $l_i < @l_row - 1; $l_i++) 
     { 
     ${$matrix{$l_row[0]}}[$l_i] = $l_row[$l_i + 1]; 
     } 
    } 

    $l_sth->finish(); 

    $dbh->disconnect(); 
    } 

print <<"EOT"; 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg> 
<defs> 
EOT 

my $filter; 

foreach $filter (@valid_modes) 
    { 
my $l_i = 0; 

    print "<filter id=\"$filter\">\n"; 
    print "<feColorMatrix type=\"matrix\" values=\""; 
    for($l_i = 0; $l_i < @{$matrix{$filter}}; $l_i++) 
    { 
    print " " if($l_i); 
    print ${$matrix{$filter}}[$l_i]; 
    if($l_i % 4 == 3) 
     { 
     print " 0.000"; 
     print "," if($l_i < @{$matrix{$filter}} - 1); 
     } 
    } 
    print "\" />\n"; 
    print "</filter>\n"; 
    } 

print <<"EOT"; 
</defs> 
</svg> 
EOT 

用于该过滤器连接到body元件以下:

body { 
    filter: url('/cgi-bin/svg/dalton.pl#normal'); /* substitute any other ID for "normal" here if required */ 
    } 

在浏览器中独立调用脚本时,我得到了文档结构(SVG没有CSS),并在validator.w3.org验证它也没有发现任何错误。 但是,一旦我将它包含在我的XHTML文档的CSS中,事情就开始变得不合时宜(不,-webkit-filter不会让Chrome在Chrome中工作)。

这里可能会出现什么问题?现在我没有看到树木的森林。

编辑:脚本生成以下的输出:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg> 
<defs> 
<filter id="normal"> 
<feColorMatrix type="matrix" values="1.000 0.000 0.000 0.000 0.000, 0.000 1.000 0.000 0.000 0.000, 0.000 0.000 1.000 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" /> 
</filter> 
<filter id="protanopia"> 
<feColorMatrix type="matrix" values="0.567 0.433 0.000 0.000 0.000, 0.558 0.442 0.000 0.000 0.000, 0.000 0.242 0.758 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" /> 
</filter> 
<filter id="protanomaly"> 
<feColorMatrix type="matrix" values="0.817 0.183 0.000 0.000 0.000, 0.333 0.667 0.000 0.000 0.000, 0.000 0.125 0.875 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" /> 
</filter> 
<filter id="deuteranopia"> 
<feColorMatrix type="matrix" values="0.625 0.375 0.000 0.000 0.000, 0.700 0.300 0.000 0.000 0.000, 0.000 0.300 0.700 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" /> 
</filter> 
<filter id="deuteranomaly"> 
<feColorMatrix type="matrix" values="0.800 0.200 0.000 0.000 0.000, 0.258 0.742 0.000 0.000 0.000, 0.000 0.142 0.858 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" /> 
</filter> 
<filter id="tritanopia"> 
<feColorMatrix type="matrix" values="0.950 0.050 0.000 0.000 0.000, 0.000 0.433 0.567 0.000 0.000, 0.000 0.475 0.525 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" /> 
</filter> 
<filter id="tritanomaly"> 
<feColorMatrix type="matrix" values="0.967 0.033 0.000 0.000 0.000, 0.000 0.733 0.267 0.000 0.000, 0.000 0.183 0.817 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" /> 
</filter> 
<filter id="achromatopsia"> 
<feColorMatrix type="matrix" values="0.299 0.587 0.114 0.000 0.000, 0.299 0.587 0.114 0.000 0.000, 0.299 0.587 0.114 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" /> 
</filter> 
<filter id="achromatomaly"> 
<feColorMatrix type="matrix" values="0.618 0.320 0.062 0.000 0.000, 0.163 0.775 0.062 0.000 0.000, 0.163 0.320 0.516 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" /> 
</filter> 
</defs> 
</svg> 
+0

我附上了它。 – Robidu

回答

1

你的根SVG元素没有命名空间。你需要你的根元素是

<svg xmlns="http://www.w3.org/2000/svg"> 
+0

谢谢。这实际上解决了这个问题,现在至少Chrome的行为应该是这样。 Firefox仍然完全以背景色显示页面,但这似乎是该浏览器固有的问题。 – Robidu

+0

这与Content-Security-Policy HTTP标头(被default-src拒绝)相关联,因此解决方法是放弃标头 - 但该解决方案不令人满意,除非我可以找出一种专门针对Firefox调整标头的方法。此问题已为人所知,并且已有一个待处理的错误报告。 – Robidu