PHP के साथ SVG छवि को PNG में बदलें


111

मैं एक वेब प्रोजेक्ट पर काम कर रहा हूं, जिसमें डेटा के एक सेट के आधार पर अमेरिका के विभिन्न राज्यों को गतिशील रूप से तैयार किया गया नक्शा शामिल है।

यह एसवीजी फ़ाइल मुझे यूएस का एक अच्छा खाली नक्शा देती है और प्रत्येक राज्य का रंग बदलने में बहुत आसान है। कठिनाई यह है कि IE ब्राउज़र एसवीजी का समर्थन नहीं करते हैं ताकि मेरे लिए आसान सिंटैक्स एसवीजी ऑफ़र का उपयोग करें, मुझे इसे जेपीजी में बदलने की आवश्यकता होगी।

आदर्श रूप में, मैं केवल GD2 लाइब्रेरी के साथ ऐसा करना चाहूंगा, लेकिन ImageMagick का उपयोग भी कर सकता हूं। मेरे पास ऐसा करने के लिए कोई सुराग नहीं है।

कोई भी समाधान जो मुझे अमेरिका के नक्शे पर राज्यों के रंगों को गतिशील रूप से बदलने की अनुमति देगा। कुंजी यह है कि फ्लाई पर रंगों को बदलना आसान है और यह क्रॉस ब्राउज़र है। PHP / अपाचे समाधान केवल, कृपया।


क्या वीएमएल पर एसवीजी को पोर्ट करने के लिए डिज़ाइन की गई कोई कक्षाएं हैं? इस तरह से आप अभी भी 'एचटीएमएल 5' प्रकार का समाधान पा सकते हैं
पैट्रिक

मेरे जवाब पर एक नज़र डालें। वास्तव में आपको क्या चाहिए

जवाबों:


142

यह मजेदार है कि आपने यह पूछा, मैंने अभी हाल ही में अपने काम की साइट के लिए यह किया था और मैं सोच रहा था कि मुझे एक ट्यूटोरियल लिखना चाहिए ... यहां बताया गया है कि इसे PHP / इमेजिक के साथ कैसे करना है, जो 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 के आधार पर भिन्न हो सकता है और आप आईडी और रंग मूल्यों को कैसे संग्रहीत करते हैं। यदि आप सर्वर पर फाइल स्टोर नहीं करना चाहते हैं, तो आप इमेज को बेस 64 की तरह आउटपुट कर सकते हैं

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

(इससे पहले कि आप स्पष्ट / नष्ट का उपयोग करें), लेकिन आधार के रूप में PNG के साथ मुद्दों है तो आप शायद jpeg के रूप में base64 उत्पादन करना होगा

आप यहां एक उदाहरण देख सकते हैं जो मैंने पूर्व नियोक्ता के बिक्री क्षेत्र के नक्शे के लिए किया था:

प्रारंभ: https://upload.wikimedia.org/wikipedia/commons/1/1a/Blank_US_Map_(states_only).svg

समाप्त: यहां छवि विवरण दर्ज करें

संपादित करें

उपरोक्त लिखने के बाद से, मैं 2 बेहतर तकनीकों के साथ आया हूँ:

1) राज्य पर भरने को बदलने के लिए एक रेगेक्स लूप के बजाय, स्टाइल नियम जैसे बनाने के लिए CSS का उपयोग करें

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

और फिर आप काल्पनिक jpeg / png निर्माण के साथ आगे बढ़ने से पहले अपने css नियमों को svg में इंजेक्ट करने के लिए एक एकल पाठ कर सकते हैं। यदि रंग नहीं बदलते हैं, तो यह सुनिश्चित करने के लिए जांचें कि आपके पास अपने रास्ते के टैग में कोई भी इनलाइन भरने की शैली नहीं है, सीएसएस को ओवरराइड करें।

2) यदि आपको वास्तव में jpeg / png इमेज फ़ाइल नहीं बनानी है (और आउटडेटेड ब्राउज़र को सपोर्ट करने की आवश्यकता नहीं है), तो आप सीधे jQuery के साथ svg में हेरफेर कर सकते हैं। जब आप 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 व्यूअर प्लग इन इंस्टॉल करने की आवश्यकता के बिना ie8 या उससे कम में समर्थित नहीं है: "सभी प्रमुख आधुनिक वेब ब्राउज़र, Microsoft इंटरनेट एक्सप्लोरर (IE) के बहुत ही उल्लेखनीय अपवाद के साथ सीधे SVG मार्कअप का समर्थन और रेंडर करते हैं।" 3] इंटरनेट एक्सप्लोरर 9 बीटा मूल एसवीजी सुविधा सेट का समर्थन करता है। [4] वर्तमान में, एंड्रॉइड के तहत चलने वाले ब्राउज़रों के लिए समर्थन भी सीमित है। "
वेबकेमिस्ट

1
हां, लेकिन svgweb को लगता है कि थोड़ी सी js और फ्लैश का उपयोग करके सभी असंगतियों को दूर किया जा सकता है। यही वह उपाय है जिसके साथ मैं गया था।
माइकल बर्कम्पास 20

2
मुझे आपका स्वच्छ और तेज समाधान पसंद है। व्यक्तिगत रूप से जब xml फ़ाइलों के साथ इंटरैक्ट करता हूं तो मैं रेगेक्स की तुलना में सुरक्षित महसूस करने के लिए डोम पार्सर का उपयोग करना पसंद करता हूं। की तरह sth:$dom = new DOMDocument(); $dom->loadXML( $svg ); $dom->getElementsByTagName('image')->item(0)->setAttribute('id', $state); $svg = $dom->saveXML();
टेपार

एक xml पार्सर एक सुरक्षित होगा, भले ही थोड़ा धीमा, किसी भी अन्य svg के साथ समाधान ... इस मामले में regex सुरक्षित है क्योंकि मैंने सुनिश्चित किया है कि प्रत्येक राज्य की विशेषताओं को बिल्कुल (id = "XX" शैली के रूप में स्वरूपित किया गया था) "भरें: # XXXXXX ")।
वेबकेमिस्ट

11

आप उल्लेख करते हैं कि आप ऐसा कर रहे हैं क्योंकि IE एसवीजी का समर्थन नहीं करता है।

अच्छी खबर यह है कि IE वेक्टर ग्राफिक्स का समर्थन करता है । ठीक है, इसलिए यह वीएमएल नामक एक भाषा के रूप में है जो एसवीजी के बजाय केवल आईई का समर्थन करता है, लेकिन यह वहां है, और आप इसका उपयोग कर सकते हैं।

Google मानचित्र, दूसरों के बीच, यह निर्धारित करने के लिए ब्राउज़र क्षमताओं का पता लगाएगा कि एसवीजी या वीएमएल की सेवा करना है या नहीं।

फिर राफेल लाइब्रेरी है , जो एक जावास्क्रिप्ट ब्राउजर आधारित ग्राफिक्स लाइब्रेरी है, जो फिर से ब्राउज़र के आधार पर एसवीजी या वीएमएल का समर्थन करती है।

एक और जो मदद कर सकता है: SVGWeb

जिनमें से सभी का मतलब है कि आप बिटमैप ग्राफिक्स का सहारा लिए बिना अपने IE उपयोगकर्ताओं का समर्थन कर सकते हैं।

इस प्रश्न का शीर्ष उत्तर भी देखें, उदाहरण के लिए: XSL ट्रांसफ़ॉर्म SVG से VML


रैफेल का उल्लेख करने के लिए +1, जो निश्चित रूप से एक अच्छा समाधान है और क्रॉस ब्राउज़र वेक्टर ग्राफिक्स के अपने उत्कृष्ट कार्यान्वयन के लिए जांच के लायक है।
DMP

10

SVG को पारदर्शी PNG में परिवर्तित करते समय, इस BEFORE को रखना न भूलें $imagick->readImageBlob():

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

छवि पढ़ने से पहले उस पद्धति को कॉल करना कैसे संभव है, मुझे एक त्रुटि प्राप्त हो रही है "खाली इमेजिक ऑब्जेक्ट को संसाधित नहीं कर सकता"। और हां मेरा इमेजिक एक्सटेंशन स्थापित है क्योंकि यह काम कर रहा है और छवियों को परिवर्तित कर रहा है।
डेनिस 2310

6

यह v। आसान है, पिछले कुछ हफ्तों से इस पर काम कर रहे हैं।

आपको बाटिक SVG टूलकिट की आवश्यकता है । डाउनलोड करें, और फ़ाइलों को उसी निर्देशिका में रखें, जिस SVG को आप JPEG में बदलना चाहते हैं , यह भी सुनिश्चित करें कि आप इसे पहले खोल दें।

टर्मिनल खोलें, और इस कमांड को चलाएं:

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

वह SVG फ़ाइल का JPEG आउटपुट देना चाहिए। वास्तव में आसान। आप इसे सिर्फ एक लूप में रख सकते हैं और एसवीजी के भार को परिवर्तित कर सकते हैं,

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 फ़ाइलों के बैच-प्रोसेस लोड के लिए पर्ल के साथ संयोजन के रूप में उपयोग करने जा रहा हूं।
सिमबेक

2

मैं एक स्वसंपूर्ण PHP / Apache समाधान के बारे में नहीं जानता, क्योंकि इसके लिए एक PHP पुस्तकालय की आवश्यकता होती है जो SVG छवियों को पढ़ और प्रस्तुत कर सकता है। मुझे यकीन नहीं है कि इस तरह की लाइब्रेरी मौजूद है - मुझे कोई जानकारी नहीं है।

ImageMagick SVG फ़ाइलों को कमांड लाइन या PHP बाइंडिंग, IMagick के माध्यम से रैस्टोर करने में सक्षम है , लेकिन इस फोरम थ्रेड में उदाहरण के रूप में दिखाए गए अनुसार कई क्विर्क और बाहरी निर्भरताएं हैं । मुझे लगता है कि यह अभी भी सबसे आशाजनक तरीका है, यह पहली बात है कि मैं देखूंगा कि मैं तुम थे।


2

यह मानक 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 में कनवर्ट करें और इसे सेव करें। (आप png के रूप में भी बचाया जा सकता है तो छवि gif के बजाय imagepng का उपयोग करें):

//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);

-1

आप राफेल-जावास्क्रिप्ट लाइब्रेरी का उपयोग कर सकते हैं और इसे आसानी से प्राप्त कर सकते हैं। यह IE में भी काम करेगा।


2
लिंक में मौजूद विवरण जोड़ें। लिंक किसी भी समय टूट सकता है
सागर जैन

-1
$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);

या उपयोग कर रहे हैं: पॉट्रेस डेमो: Tool4dev.com

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.