[php] PHP를 사용하여 SVG 이미지를 PNG로 변환

저는 데이터 세트를 기반으로 여러 주를 채색하는 동적으로 생성 된 미국지도를 포함하는 웹 프로젝트를 진행하고 있습니다.

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

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

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



답변

당신이 이것을 물었다는 것은 재밌습니다. 저는 최근에 제 작업 사이트를 위해 이것을했습니다. 그리고 저는 튜토리얼을 작성해야한다고 생각하고있었습니다 … ImageMagick을 사용하는 PHP / Imagick으로 이것을하는 방법은 다음과 같습니다 :

$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 및 색상 값이 저장되는 방법에 따라 다를 수 있습니다. 서버에 파일을 저장하지 않으려면 이미지를 base 64로 출력 할 수 있습니다.

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

(clear / destroy를 사용하기 전에)하지만 즉, PNG에 base64로 문제가 있으므로 base64를 jpeg로 출력해야 할 것입니다.

여기에서 전 고용주의 판매 지역지도에 대한 예를 볼 수 있습니다.

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

끝: 여기에 이미지 설명 입력

편집하다

위의 글을 쓴 이후로 두 가지 개선 된 기술을 생각해 냈습니다.

1) 상태 채우기를 변경하는 정규식 루프 대신 CSS를 사용하여 다음과 같은 스타일 규칙을 만듭니다.

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

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

2) 실제로 jpeg / png 이미지 파일을 만들 필요가없고 오래된 브라우저를 지원할 필요도 없다면 jQuery를 사용하여 직접 svg를 조작 할 수 있습니다. img 또는 object 태그를 사용하여 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>


답변

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

좋은 소식은 IE 벡터 그래픽을 지원 한다는 것 입니다. 좋습니다. 이것은 SVG가 아닌 IE 만 지원하는 VML이라는 언어의 형태이지만 거기에 있고 사용할 수 있습니다.

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

그 다음에 는 브라우저에 따라 SVG 또는 VML을 지원하는 자바 스크립트 브라우저 기반 그래픽 라이브러리 인 Raphael 라이브러리 가 있습니다.

도움이 될 수있는 또 다른 방법 : SVGWeb .

즉, 비트 맵 그래픽에 의존하지 않고도 IE 사용자를 지원할 수 있습니다.

이 질문에 대한 상위 답변도 참조하십시오. 예 : XSL SVG를 VML로 변환


답변

SVG를 투명한 PNG로 변환 할 때 다음을 입력하는 것을 잊지 마십시오 $imagick->readImageBlob().

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


답변

이것은 v. 쉽습니다. 지난 몇 주 동안 이것에 대한 작업을 해왔습니다.

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

터미널을 열고 다음 명령을 실행하십시오.

java -jar batik-rasterizer.jar -m image/jpeg -q 0.8 NAME_OF_SVG_FILE.svg

SVG 파일의 JPEG를 출력해야합니다. 정말 쉽습니다. 루프에 배치하고 많은 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')


답변

SVG 이미지를 읽고 렌더링 할 수있는 PHP 라이브러리가 필요하기 때문에 독립 실행 형 PHP / Apache 솔루션을 모릅니다. 그런 라이브러리가 있는지 잘 모르겠습니다. 저는 어떤 것도 모릅니다.

ImageMagick 은 명령 줄이나 PHP 바인딩 IMagick을 통해 SVG 파일을 래스터화할 수 있지만 이 포럼 스레드 에 표시된 것처럼 여러 가지 단점과 외부 종속성이있는 것 같습니다 . 여전히 가장 유망한 방법이라고 생각합니다. 제가 당신이라면 가장 먼저 살펴볼 것입니다.


답변

표준 PHP GD 도구를 사용하여 svg 그림을 gif로 변환하는 방법입니다.

1) 브라우저의 캔버스 요소에 이미지를 넣습니다.

<canvas id=myCanvas></canvas>

<script>
var Key='picturename'
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
base_image = new Image();
base_image.src = myimage.svg;
base_image.onload = function(){

    //get the image info as base64 text string

    var dataURL = canvas.toDataURL();
    //Post the image (dataURL) to the server using jQuery post method
    $.post('ProcessPicture.php',{'TheKey':Key,'image': dataURL ,'h': canvas.height,'w':canvas.width,"stemme":stemme } ,function(data,status){ alert(data+' '+status) });
}
</script>    

그런 다음 서버 (ProcessPicture.php)에서 (기본값) png에서 gif로 변환하고 저장합니다. (이미지 gif 대신 imagepng를 사용하여 png로 저장할 수도 있습니다) :

//receive the posted data in php
$pic=$_POST['image'];
$Key=$_POST['TheKey'];
$height=$_POST['h'];
$width=$_POST['w'];
$dir='../gif/'
$gifName=$dir.$Key.'.gif';
 $pngName=$dir.$Key.'.png';

//split the generated base64 string before the comma. to remove the 'data:image/png;base64, header  created by and get the image data
$data = explode(',', $pic);
$base64img = base64_decode($data[1]);
$dimg=imagecreatefromstring($base64img); 

//in order to avoid copying a black figure into a (default) black background you must create a white background

$im_out = ImageCreateTrueColor($width,$height);
$bgfill = imagecolorallocate( $im_out, 255, 255, 255 );
imagefill( $im_out, 0,0, $bgfill );

//Copy the uploaded picture in on the white background
ImageCopyResampled($im_out, $dimg ,0, 0, 0, 0, $width, $height,$width, $height);

//Make the gif and png file 
imagegif($im_out, $gifName);
imagepng($im_out, $pngName);


답변

Raphaël—JavaScript Library를 사용 하여 쉽게 얻을 수 있습니다. IE에서도 작동합니다.