2011-01-26 9 views
92

나는 일련의 데이터를 기반으로 미국을 색칠하여 동적으로 생성 된지도가 포함 된 웹 프로젝트를 진행하고 있습니다.PHP를 사용하여 SVG 이미지를 PNG로 변환

SVG 파일은 미국의 빈지도를 제공하며 각 국가의 색을 변경하는 것은 매우 쉽습니다. 어려움은 IE 브라우저가 SVG를 지원하지 않기 때문에 svg가 제공하는 편리한 구문을 사용하려면 JPG로 변환해야합니다.

이상적으로는 GD2 라이브러리에서만이 작업을 수행하고 싶지만 ImageMagick도 사용할 수 있습니다. 나는 이것을 할 방법이 전혀 없다.

미국지도의 상태 색상을 동적으로 변경할 수있는 모든 해결책이 고려됩니다. 열쇠는 즉석에서 색상을 변경하는 것이 쉽고 크로스 브라우저라는 점입니다. PHP/Apache 솔루션 만 사용하십시오.

+0

이 포트 SVG로 설계된 클래스가 VML에 이상이 있습니다를? 그런 식으로 당신은 여전히 ​​'HTML5'타입의 솔루션을 가질 수 있습니다. – Patrick

+0

제 답변을보십시오. 정확히 무엇이 필요합니까? –

답변

115

가, 난 그냥 내 일의 사이트에 최근 이런 짓을하고 내가 자습서를 작성해야 생각 :

예를 들어,이 질문에 또한 상단 답변을 참조하십시오 ImageMagick이 그것을 수행하는 방법 :

$usmap = '/path/to/blank/us-map.svg'; 
$im = new Imagick(); 
$svg = file_get_contents($usmap); 

/*loop to color each state as needed, something like*/ 
$idColorArray = array(
    "AL" => "339966" 
    ,"AK" => "0099FF" 
    ... 
    ,"WI" => "FF4B00" 
    ,"WY" => "A3609B" 
); 

foreach($idColorArray as $state => $color){ 
//Where $color is a RRGGBB hex value 
    $svg = preg_replace(
     '/id="'.$state.'" style="fill:#([0-9a-f]{6})/' 
     , 'id="'.$state.'" style="fill:#'.$color 
     , $svg 
    ); 
} 

$im->readImageBlob($svg); 

/*png settings*/ 
$im->setImageFormat("png24"); 
$im->resizeImage(720, 445, imagick::FILTER_LANCZOS, 1); /*Optional, if you need to resize*/ 

/*jpeg*/ 
$im->setImageFormat("jpeg"); 
$im->adaptiveResizeImage(720, 445); /*Optional, if you need to resize*/ 

$im->writeImage('/path/to/colored/us-map.png');/*(or .jpg)*/ 
$im->clear(); 
$im->destroy(); 

단계 정규식 색상 교체는 SVG 경로 XML 및 ID & 색상 값은 어떻게 저장되어에 따라 다를 수 있습니다.서버에 파일을 저장하지 않으려면 출력

<?php echo '<img src="data:image/jpg;base64,' . base64_encode($im) . '" />';?> 

같은베이스 (64)와 이미지 (당신이 명확 사용하기 전에/파괴) 할 수 있지만이 좋겠 있도록 즉 64 기수로 PNG로 문제가 아마도 JPEG로 출력베이스 64에있는

당신은 내가 이전 고용주의 영업 지역지도를 위해 한 여기에 예를 볼 수 있습니다

:

시작 : https://upload.wikimedia.org/wikipedia/commons/1/1a/Blank_US_Map_(states_only).svg

마침 : 상태에 채우기를 변경

1) 대신 정규식 루프의 : enter image description here

편집

위를 쓰기 때문에, 나는이 개 개선 된 기술로 왔어요 스타일 규칙을 만들려면 CSS를 사용하십시오.

<style type="text/css"> 
#CA,#FL,HI{ 
    fill:blue; 
} 
#Al, #NY, #NM{ 
    fill:#cc6699; 
} 
/*etc..*/ 
</style> 

그런 다음 하나의 텍스트를 injec으로 대체 할 수 있습니다 imagick jpeg/png 생성을 진행하기 전에 CSS 규칙을 svg에 적용하십시오. 색상이 변경되지 않으면 css를 재정의하여 경로 태그에 인라인 채우기 스타일이 없는지 확인하십시오.

2) 실제로 jpeg/png 이미지 파일을 만들 필요가 없으며 (구식 브라우저를 지원할 필요가없는 경우) svg를 jQuery로 직접 조작 할 수 있습니다. 당신은 IMG 또는 개체 태그를 사용하여 SVG를 매립 SVG 경로에 액세스 할 수 없습니다, 그래서 당신은해야합니다 직접 같은 웹 페이지의 HTML에 SVG XML을 포함 :

다음 색상을 변경
<div> 
<?php echo file_get_contents('/path/to/blank/us-map.svg');?> 
</div> 

는만큼 간단합니다 :

<script type="text/javascript" src="/path/to/jquery.js"></script> 
<script type="text/javascript"> 
    $('#CA').css('fill', 'blue'); 
    $('#NY').css('fill', '#ff0000'); 
</script> 
+1

이 작업을 수행하는 방법에 대한 매우 정확하고 유용한 자습서를 제공해 주셔서 감사합니다. 확실히 당신의 솔루션을 백업으로 사용 하겠지만 모든 주요 브라우저에서 svg 호환성을 얻으려고 열심입니다. –

+1

SVG 위키 백과 페이지에서 "SVG 마크 업을 지원하는 모든 주요 현대 웹 브라우저는 SVG 마크 업을 직접 지원합니다. Microsoft Internet Explorer (IE) [3] Internet Explorer 9 베타는 기본적인 SVG 기능 세트를 지원합니다. [4] 현재 Android에서 실행되는 브라우저에 대한 지원도 제한되어 있습니다. " – WebChemist

+1

예,하지만 svgweb은 js와 플래시를 사용하여 모든 비 호환성 문제를 해결하는 것으로 보입니다. 그것이 내가 함께 갔던 해결책이다. –

2

독립 실행 형 PHP/Apache 솔루션에 대해 알지 못합니다. SVG 이미지를 읽고 렌더링 할 수있는 PHP 라이브러리가 필요합니다. 나는 그런 도서관이 존재하는지 모른다. 나는 모른다.

ImageMagick은 명령 줄 또는 PHP 바인딩 인 IMagick을 통해 SVG 파일을 래스터화할 수 있지만 예를 들어 수많은 불일치 및 외부 종속성이있는 것 같습니다. this forum thread에 있습니다. 나는 그것이 여전히 가장 유망한 방법이라고 생각합니다. 그것이 내가 당신이라면 내가 조사 할 것입니다.

+0

+1 이것은 간단하고 최상의 답이 될 것입니다. –

11

IE가 SVG를 지원하지 않기 때문에이 작업을 수행한다고 언급했습니다.

좋은 소식은 IE 벡터 그래픽을 지원합니다. 좋아요, 그래서 그것은 SVG보다는 IE 만 지원하는 VML이라는 언어의 형태입니다. 그러나 거기에 있으며, 당신은 그것을 사용할 수 있습니다.

Google지도는 SVG 또는 VML 서비스를 제공할지 여부를 결정하는 브라우저 기능을 감지합니다.

다음은 브라우저에 따라 SVG 또는 VML을 지원하는 Javascript 브라우저 기반 그래픽 라이브러리 인 Raphael library입니다.

도움이 될만한 다른 사람 : SVGWeb.

모두 비트 맵 그래픽을 사용하지 않고도 IE 사용자를 지원할 수 있습니다. 다음은 ... 당신이 질문 재미 XSL Transform SVG to VML

+0

+ 1 라파 (lraphael)에 대해 언급했는데, 이것은 좋은 해결책이며, 크로스 브라우저 벡터 그래픽의 우수한 구현을 조사 할 가치가 있습니다. – dmp

5

이것은 지난 몇 주 동안이 작업을 해왔습니다.

Batik SVG Toolkit이 필요합니다. 다운로드 및 파일을 JPEG으로 변환하려는 SVG와 동일한 디렉토리에 배치하고 압축을 먼저 풀어야합니다.

열기 터미널

,이 명령을 실행 SVG 파일의 JPEG 출력해야
java -jar batik-rasterizer.jar -m image/jpeg -q 0.8 NAME_OF_SVG_FILE.svg 

. 정말 쉽습니다. 당신은 단지

import os 

svgs = ('test1.svg', 'test2.svg', 'etc.svg') 
for svg in svgs: 
    os.system('java -jar batik-rasterizer.jar -m image/jpeg -q 0.8 '+str(svg)+'.svg') 
+0

이것은 위대하다. 팁 고마워. 필자는 템플릿에서 생성 한 SVG 파일을 일괄 적으로 처리하기 위해 perl과 함께 사용하려고합니다. – simbabque

16

또 다른 매우 빠른 & 정확한 옵션은

http://phantomjs.org/

+1

Batik, Imagemagick 및 일부 웹 기반 솔루션을 테스트 한 후 클리핑, 마스킹, 필터 효과, foreignObject (및 svg 앞에 놓인 html 콘텐츠조차도)를 올바르게 얻을 수있는 유일한 방법은 phantomjs뿐이었습니다. 정말로 이것을 추천 할 수 있습니다! –

3

당신은 canvg을 사용할 수 있습니다 (웹킷) 헤드리스 브라우저 PhantomJS입니다, 루프에 배치하고 SVGs의 부하를 변환 할 수 있습니다 SVG를 PNG로 변환하는 js 라이브러리, 여기 더 자세한 정보 http://paksula.users.cs.helsinki.fi/svg_open_2010/demo.xhtml 모든 주요 브라우저와 호환!내가

+1

링크가 깨졌습니다 :-( –

+1

나는이 피들 shoud 일 http://jsfiddle.net/plaliberte/HAXyd/ 생각하고 여기 canvg https://code.google.com/p/canvg/의 소스 코드 페이지입니다 – razor7

6

잊지 투명 PNG로 SVG를 해달라고 변환하는 $ 전에이를 넣을 때 (물론 파일을 저장하기 위해 PHP의 도움으로) 내 프로젝트에서 사용하고 실제로 PNG로 SVG로 변환하고있어

imagick-> readImageBlob() :

$imagick->setBackgroundColor(new ImagickPixel('transparent')); 
-1

Raphaël—JavaScript Library을 사용하면 쉽게 얻을 수 있습니다. 그것은 또한 IE에서 작동합니다.

+2

세부 정보를 링크에 추가하십시오. 언제든지 링크가 끊어 질 수 있습니다. –

0
$command = 'convert -density 300 '; 
         if(Input::Post('height')!='' && Input::Post('width')!=''){ 
          $command.='-resize '.Input::Post('width').'x'.Input::Post('height').' '; 
         } 
         $command.=$svg.' '.$source; 
         exec($command); 
         @unlink($svg); 

또는 사용 : potrace에게 데모 : Tool4dev.com

관련 문제