ব্রাউজারে এসভিজিকে চিত্রে (জেপিইজি, পিএনজি, ইত্যাদি) রূপান্তর করুন


299

আমি জাভাস্ক্রিপ্টের মাধ্যমে এসভিজিকে বিটম্যাপ চিত্রগুলিতে (জেপিইজি, পিএনজি ইত্যাদি) রূপান্তর করতে চাই।


আপনি আসলে কোন কাজটি সম্পাদন করতে চান? যদিও প্রতিধ্বনির উত্তর আমাদের জানান যে এটি সম্ভব (কিছু ব্রাউজারে) প্রায় সমস্ত ব্যবহারিক ক্ষেত্রে আরও ভাল এবং সহজ রূপান্তর পদ্ধতি রয়েছে।
অআআআআআআআআআআআআআআআআআ

2
এখানে d3 ব্যবহার করে একটি উদাহরণ দেওয়া হয়েছে: stackoverflow.com/a/23667012/439699
এস্ক

svgopen.org/2010/papers/62-From_SVG_to_Canvas_and_ack - পুরোপুরি কাজ করে! [লিঙ্ক পৃষ্ঠায়, সোর্স এসভিজি = $ ("# আপনার_এসভিজি_লেম_নাম")। পান (0)]
বিজয় সিং

উত্তর:


244

জাভাস্ক্রিপ্টের মাধ্যমে আপনি এটি কীভাবে করতে পারেন তা এখানে:

  1. ক্যানভাস ব্যবহার করে এসভিজি চিত্রটি রেন্ডার করতে ক্যানভিগ জাভাস্ক্রিপ্ট লাইব্রেরিটি ব্যবহার করুন: https://github.com/gabelerner/canvg
  2. এই নির্দেশাবলী অনুসারে ক্যানভাস থেকে জেপিজি (বা পিএনজি) হিসাবে এনকোডড একটি ডেটা ইউআরআই ক্যাপচার করুন : এইচটিএমএল ক্যানভাসকে জিআইএফ / জেপিজি / পিএনজি / পিডিএফ হিসাবে ক্যাপচার করবেন?

28
এটি কঠোরভাবে জাভাস্ক্রিপ্ট নয়, পাশাপাশি HTML5। এটি আইই 8 বা অন্য কোনও ব্রাউজারে কাজ করবে না যা এইচটিএমএল 5 ক্যানভাস সমর্থন করে না।
জেমস

16
ব্রাউজারটি যদি এসভিজি এবং ক্যানভাসকে সমর্থন করে, তবে এসভিজিকে মেমরিতে লোড করার এবং তারপরে এটি একটি ক্যানভাসে আঁকানোর আরও সহজ উপায় হতে পারে, এটি ক্যানভগের প্রয়োজন ছাড়াই, এটি একটি দুর্দান্ত বড় লাইব্রেরি কারণ এটি সমস্ত এসভিজি পার্সিং পরিচালনা করে that একটি এসভিজি-সমর্থনকারী ব্রাউজার ইতিমধ্যে বিনামূল্যে সরবরাহ করে। আমি নিশ্চিত নই যে এটি আসল ব্যবহারের ক্ষেত্রে সন্তুষ্ট কিনা, তবে যদি তা হয় তবে বিশদগুলির জন্য এই উত্সটি দেখুন
প্রেমাসাগর

120
আইই 8 সমর্থন না করার জন্য ধন্যবাদ। লোকেরা বুঝতে হবে যে এটি এগিয়ে যাওয়ার সময়।
সংকেত সাহু

9
এটি অর্জনের জন্য আপনি এখন জাভাস্ক্রিপ্ট এসভিজি লাইব্রেরি পাবলো ব্যবহার করতে পারেন (আমি এটি তৈরি করেছি)। স্বয়ংক্রিয়ভাবে ডাউনলোড করা চিত্রের জন্য toImage()এবং দেখুন download()
প্রেমাসাগর

2
svgopen.org/2010/papers/62-From_SVG_to_Canvas_and_ack - পুরোপুরি কাজ করে! [। লিংক পৃষ্ঠায়, sourceSVG = $ ( "# your_svg_elem_name") পেতে (0)]
বিজয় সিং

44

jbeard4 সমাধানটি সুন্দরভাবে কাজ করেছে।

আমি এসভিজি তৈরি করতে রাফেল স্কেচপ্যাড ব্যবহার করছি । পদক্ষেপ 1 এ ফাইলগুলির সাথে লিঙ্ক করুন।

একটি সংরক্ষণ বোতামের জন্য (এসভিজি আইডি "সম্পাদক", ক্যানভাসের আইডি "ক্যানভাস"):

$("#editor_save").click(function() {

// the canvg call that takes the svg xml and converts it to a canvas
canvg('canvas', $("#editor").html());

// the canvas calls to output a png
var canvas = document.getElementById("canvas");
var img = canvas.toDataURL("image/png");
// do what you want with the base64, write to screen, post to server, etc...
});

1
ক্যানভিগের জন্য দ্বিতীয় প্যারামিটারটি থাকতে হবে <svg>...</svgতবে জ্যাকুয়ের এইচটিএমএল () ফাংশনটি এসভিজি ট্যাগ যুক্ত করে না, সুতরাং এই কোডটি আমার পক্ষে কাজ করে তবে আমার পক্ষে ক্যানভিগ লাইভ এডিট করা দরকারcanvg('canvas', '<svg>'+$("#editor").html()+'</svg>');
লাকিন

1
@Luckyn যদি আপনি কল $(selector).html()আপনার অভিভাবক উপর SVG উপাদান এটি কাজ করবে
jonathanGB

@ লুকিন এবং @ জোনাথনজিবি, আপনাকে মোড়কে ব্যবহার করতে হবে না html(), বা ম্যানুয়ালি প্যারেন্ট svgট্যাগটি তৈরি করতে হবে না - যার ফলে আপনি এই হ্যাকটি ছেড়ে দিতে পারেন এমন বৈশিষ্ট্যও থাকতে পারে। কেবল ব্যবহার $(svg_elem)[0].outerHTMLআপনাকে এসভিজি এবং এর সামগ্রীগুলির সম্পূর্ণ উত্স দেয়। শুধু বলছি ...
nemesisfixx

18

এটি বেশিরভাগ ব্রাউজারে কাজ করে বলে মনে হচ্ছে:

function copyStylesInline(destinationNode, sourceNode) {
   var containerElements = ["svg","g"];
   for (var cd = 0; cd < destinationNode.childNodes.length; cd++) {
       var child = destinationNode.childNodes[cd];
       if (containerElements.indexOf(child.tagName) != -1) {
            copyStylesInline(child, sourceNode.childNodes[cd]);
            continue;
       }
       var style = sourceNode.childNodes[cd].currentStyle || window.getComputedStyle(sourceNode.childNodes[cd]);
       if (style == "undefined" || style == null) continue;
       for (var st = 0; st < style.length; st++){
            child.style.setProperty(style[st], style.getPropertyValue(style[st]));
       }
   }
}

function triggerDownload (imgURI, fileName) {
  var evt = new MouseEvent("click", {
    view: window,
    bubbles: false,
    cancelable: true
  });
  var a = document.createElement("a");
  a.setAttribute("download", fileName);
  a.setAttribute("href", imgURI);
  a.setAttribute("target", '_blank');
  a.dispatchEvent(evt);
}

function downloadSvg(svg, fileName) {
  var copy = svg.cloneNode(true);
  copyStylesInline(copy, svg);
  var canvas = document.createElement("canvas");
  var bbox = svg.getBBox();
  canvas.width = bbox.width;
  canvas.height = bbox.height;
  var ctx = canvas.getContext("2d");
  ctx.clearRect(0, 0, bbox.width, bbox.height);
  var data = (new XMLSerializer()).serializeToString(copy);
  var DOMURL = window.URL || window.webkitURL || window;
  var img = new Image();
  var svgBlob = new Blob([data], {type: "image/svg+xml;charset=utf-8"});
  var url = DOMURL.createObjectURL(svgBlob);
  img.onload = function () {
    ctx.drawImage(img, 0, 0);
    DOMURL.revokeObjectURL(url);
    if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob)
    {
        var blob = canvas.msToBlob();         
        navigator.msSaveOrOpenBlob(blob, fileName);
    } 
    else {
        var imgURI = canvas
            .toDataURL("image/png")
            .replace("image/png", "image/octet-stream");
        triggerDownload(imgURI, fileName);
    }
    document.removeChild(canvas);
  };
  img.src = url;
}

3
সুরক্ষা ইস্যুটির কারণে এটি .msToBlob()
1111-এ

ধন্যবাদ !! আমি পছন্দ করি এটি কীভাবে "স্থানীয়" এসভিজি এইচটিএমএল নোড এবং একটি দূরবর্তী এসভিজি ইউআরএল উভয়ের জন্য কাজ করে। এছাড়াও এটির জন্য একটি সম্পূর্ণ বাহ্যিক গ্রন্থাগার প্রয়োজন নেই
ফ্যাব্রিকিও পিএইচ

ফায়ারফক্সের জন্য কাজ করে না (68.4.2esr (64-বিট))
স্টেফান

7

SVG কে ব্লব ইউআরএল এবং ব্লব ইউআরএলকে পিএনজি ছবিতে রূপান্তর করার সমাধান

const svg=`<svg version="1.1" baseProfile="full" width="300" height="200"
xmlns="http://www.w3.org/2000/svg">
   <rect width="100%" height="100%" fill="red" />
   <circle cx="150" cy="100" r="80" fill="green" />
   <text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text></svg>`
svgToPng(svg,(imgData)=>{
    const pngImage = document.createElement('img');
    document.body.appendChild(pngImage);
    pngImage.src=imgData;
});
 function svgToPng(svg, callback) {
    const url = getSvgUrl(svg);
    svgUrlToPng(url, (imgData) => {
        callback(imgData);
        URL.revokeObjectURL(url);
    });
}
function getSvgUrl(svg) {
    return  URL.createObjectURL(new Blob([svg], { type: 'image/svg+xml' }));
}
function svgUrlToPng(svgUrl, callback) {
    const svgImage = document.createElement('img');
    // imgPreview.style.position = 'absolute';
    // imgPreview.style.top = '-9999px';
    document.body.appendChild(svgImage);
    svgImage.onload = function () {
        const canvas = document.createElement('canvas');
        canvas.width = svgImage.clientWidth;
        canvas.height = svgImage.clientHeight;
        const canvasCtx = canvas.getContext('2d');
        canvasCtx.drawImage(svgImage, 0, 0);
        const imgData = canvas.toDataURL('image/png');
        callback(imgData);
        // document.body.removeChild(imgPreview);
    };
    svgImage.src = svgUrl;
 }


3

আমি এই ES6 ক্লাসটি লিখেছি যা কাজটি করে।

class SvgToPngConverter {
  constructor() {
    this._init = this._init.bind(this);
    this._cleanUp = this._cleanUp.bind(this);
    this.convertFromInput = this.convertFromInput.bind(this);
  }

  _init() {
    this.canvas = document.createElement("canvas");
    this.imgPreview = document.createElement("img");
    this.imgPreview.style = "position: absolute; top: -9999px";

    document.body.appendChild(this.imgPreview);
    this.canvasCtx = this.canvas.getContext("2d");
  }

  _cleanUp() {
    document.body.removeChild(this.imgPreview);
  }

  convertFromInput(input, callback) {
    this._init();
    let _this = this;
    this.imgPreview.onload = function() {
      const img = new Image();
      _this.canvas.width = _this.imgPreview.clientWidth;
      _this.canvas.height = _this.imgPreview.clientHeight;
      img.crossOrigin = "anonymous";
      img.src = _this.imgPreview.src;
      img.onload = function() {
        _this.canvasCtx.drawImage(img, 0, 0);
        let imgData = _this.canvas.toDataURL("image/png");
        if(typeof callback == "function"){
            callback(imgData)
        }
        _this._cleanUp();
      };
    };

    this.imgPreview.src = input;
  }
}

আপনি এটি কীভাবে ব্যবহার করবেন তা এখানে

let input = "https://restcountries.eu/data/afg.svg"
new SvgToPngConverter().convertFromInput(input, function(imgData){
    // You now have your png data in base64 (imgData). 
    // Do what ever you wish with it here.
});

আপনি যদি ভ্যানিলা জাভাস্ক্রিপ্ট সংস্করণ চান তবে আপনি বাবেল ওয়েবসাইটের দিকে যেতে পারেন এবং সেখানে কোডটি স্থানান্তর করতে পারেন।


2

ফ্যান্টমজেএস-এর ভিত্তিতে একটি সার্ভার সাইড সমাধান রয়েছে। আপনি চিত্র পরিষেবায় ক্রস ডোমেন কল করতে JSONP ব্যবহার করতে পারেন:

https://github.com/vidalab/banquo-server

উদাহরণ স্বরূপ:

HTTP: // [হোস্ট] /api/https%3A%2F%2Fvida.io%2Fdocuments%2FWgBMc4zDWF7YpqXGR/viewport_width=980&viewport_height=900&delay=5000&selector=%23canvas

তারপরে আপনি img ট্যাগ সহ চিত্রটি প্রদর্শন করতে পারেন:

<img src="data:image/png;base64, [base64 data]"/>

এটি ব্রাউজার জুড়ে কাজ করে।


পরিষেবাটি মারা গেছে বলে মনে হচ্ছে।

3
আমাদের হোস্টটি বোগাস অনুরোধে আঘাত পেয়েছিল। সুতরাং আমরা এটিকে নামানোর সিদ্ধান্ত নিয়েছি। আপনাকে এখন নিজের সার্ভার চালাতে হবে। আরও তথ্যের জন্য গিথুব রেপো দেখুন।
ফুয়োক দো

1

svgআপনার উপাদান মেলে পরিবর্তন

function svg2img(){
    var svg = document.querySelector('svg');
    var xml = new XMLSerializer().serializeToString(svg);
    var svg64 = btoa(xml); //for utf8: btoa(unescape(encodeURIComponent(xml)))
    var b64start = 'data:image/svg+xml;base64,';
    var image64 = b64start + svg64;
    return image64;
};svg2img()

1
এটি আমার পক্ষে কাজ করছে না, আমি এই ত্রুটিটি Uncaught TypeError: Failed to execute 'serializeToString' on 'XMLSerializer': parameter 1 is not of type 'Node'.
পেয়েছি

1
@ এক্সএমএল DOMParser ইন্টারফেস বিকাশকারী.মোজিলা.আর.ইন.ইউএস
মাহদি খলিলি

1

Svgথেকে pngঅবস্থার উপর নির্ভর করে পরিবর্তিত করা যায়:

  1. যদি svgফর্ম্যাট এসভিজি (স্ট্রিং) পথে থাকে :
    • ক্যানভাস তৈরি করুন
    • প্যারামিটার হিসাবে তৈরি new Path2D()এবং সেট করুনsvg
    • ক্যানভাসে পথ আঁকো
    • চিত্র তৈরি করুন এবং canvas.toDataURL()হিসাবে ব্যবহার করুন src

উদাহরণ:

const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
let svgText = 'M10 10 h 80 v 80 h -80 Z';
let p = new Path2D('M10 10 h 80 v 80 h -80 Z');
ctx.stroke(p);
let url = canvas.toDataURL();
const img = new Image();
img.src = url;

নোট করুন যে Path2Dসমর্থিত নয় ieএবং আংশিকভাবে প্রান্তে সমর্থিত। পলিফিল এটি সমাধান করে: https://github.com/nilzona/path2d-polyfill

  1. svgব্লব তৈরি করুন এবং ক্যানভাসে অঙ্কন ব্যবহার করে .drawImage():
    • ক্যানভাস উপাদান তৈরি করুন
    • এসভিজি এক্সএমএল থেকে একটি এসভিজি ব্লব অবজেক্ট তৈরি করুন
    • domUrl.createObjectURL (svgBlob) থেকে url অবজেক্ট তৈরি করুন;
    • একটি চিত্র অবজেক্ট তৈরি করুন এবং চিত্র এসআরসি-তে ইউআরএল নির্ধারণ করুন
    • ক্যানভাসে চিত্র আঁকুন
    • ক্যানভাস থেকে পিএনজি ডেটা স্ট্রিং পান: ক্যানভাস.টোডাটা URL ();

সুন্দর বর্ণনা: http://ramblings.mcphan.com/Home/excelquirks/gassnips/svgtopng

মনে রাখবেন যে আপনি ক্যানভাস.ডোডাটাআরএল () এর মঞ্চে ব্যতিক্রম পাবেন; এটি কারণ আইই এর উচ্চ নিরাপত্তা সীমাবদ্ধতা রয়েছে এবং সেখানে চিত্র অঙ্কনের পরে ক্যানভাসকে কেবল পঠন হিসাবে আচরণ করে। অন্যান্য সমস্ত ব্রাউজার কেবল তখনই সীমাবদ্ধ থাকে যখন চিত্রটি ক্রস উত্স হয়।

  1. canvgজাভাস্ক্রিপ্ট লাইব্রেরি ব্যবহার করুন । এটি পৃথক গ্রন্থাগার তবে দরকারী কার্যকারিতা রয়েছে।

ভালো লেগেছে:

ctx.drawSvg(rawSvg);
var dataURL = canvas.toDataURL();

তৃতীয় লিঙ্কটি ভাঙা হয়েছে
সর্দার সায়েন

হ্যাঁ, সত্যিই কীভাবে এখন সেখানে পৌঁছতে জানি না। তবে উপরের বর্ণনাটি কিছু বোঝার জন্য যথেষ্ট হতে পারে। ভবিষ্যতের সহকারীদের জন্য ভাল ধারণা রেফারেন্সের পরে কিছু প্রসঙ্গটি অনুলিপি করুন
অ্যালেক্স ভোভুকুক

0

আমি সম্প্রতি জাভাস্ক্রিপ্টের জন্য বেশ কয়েকটি চিত্রের ট্রেসিং গ্রন্থাগার আবিষ্কার করেছি যা প্রকৃতপক্ষে আকার এবং মানের উভয় বিটম্যাপে একটি গ্রহণযোগ্য সান্নিধ্য তৈরি করতে সক্ষম। আমি এই জাভাস্ক্রিপ্ট লাইব্রেরি এবং সিএলআই বিকাশ করছি:

https://www.npmjs.com/package/svg-png-converter

যা তাদের সকলের জন্য ইউনিফাইড এপিআই সরবরাহ করে, সমর্থনকারী ব্রাউজার এবং নোড, ডিওএম এর উপর নির্ভর করে নয়, এবং একটি কমান্ড লাইন সরঞ্জাম।

লোগো / কার্টুন / চিত্র পছন্দ করার জন্য এটি দুর্দান্ত কাজ করে। ফটোগুলি / বাস্তববাদের জন্য কিছু টুইট করা দরকার কারণ আউটপুট আকারটি অনেক বাড়তে পারে।

এটিতে খেলার মাঠ রয়েছে যদিও এই মুহুর্তে আরও ভাল বৈশিষ্ট্য যুক্ত করা হয়েছে বলে আমি আরও ভাল, ব্যবহারে সহজতর কাজ করছি on

https://cancerberosgx.github.io/demos/svg-png-converter/playground/#

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.