feat: Context.prototype.getImageData (experimental), for https://github.com/gliffy/canvas2svg/issues/3, for https://github.com/zenozeng/p5.js-svg/issues/203
This commit is contained in:
parent
5afaf230b7
commit
3991b8ee96
@ -26,8 +26,16 @@ ctx.fillRect(100,100,100,100);
|
|||||||
const mySerializedSVG = ctx.getSerializedSvg();
|
const mySerializedSVG = ctx.getSerializedSvg();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
https://zenozeng.github.io/p5.js-svg/test/
|
||||||
|
|
||||||
## CHANGELOG
|
## CHANGELOG
|
||||||
|
|
||||||
|
## v2.2.0
|
||||||
|
|
||||||
|
- feat: Context.prototype.getImageData (experimental) for https://github.com/gliffy/canvas2svg/issues/3 and https://github.com/zenozeng/p5.js-svg/issues/203
|
||||||
|
|
||||||
## v2.1.0
|
## v2.1.0
|
||||||
|
|
||||||
- feat: SVGCanvasElement(options)
|
- feat: SVGCanvasElement(options)
|
||||||
|
15
context.js
15
context.js
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import * as utils from './utils';
|
import * as utils from './utils';
|
||||||
|
import imageUtils from './image';
|
||||||
|
|
||||||
export default (function () {
|
export default (function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
@ -1306,12 +1307,24 @@ export default (function () {
|
|||||||
return new DOMPoint(x, y).matrixTransform(this.__transformMatrix)
|
return new DOMPoint(x, y).matrixTransform(this.__transformMatrix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {*} sx The x-axis coordinate of the top-left corner of the rectangle from which the ImageData will be extracted.
|
||||||
|
* @param {*} sy The y-axis coordinate of the top-left corner of the rectangle from which the ImageData will be extracted.
|
||||||
|
* @param {*} sw The width of the rectangle from which the ImageData will be extracted. Positive values are to the right, and negative to the left.
|
||||||
|
* @param {*} sh The height of the rectangle from which the ImageData will be extracted. Positive values are down, and negative are up.
|
||||||
|
* @param {Boolean} options.async Will return a Promise<ImageData> if true, must be set to true
|
||||||
|
* @returns An ImageData object containing the image data for the rectangle of the canvas specified. The coordinates of the rectangle's top-left corner are (sx, sy), while the coordinates of the bottom corner are (sx + sw, sy + sh).
|
||||||
|
*/
|
||||||
|
Context.prototype.getImageData = function(sx, sy, sw, sh, options) {
|
||||||
|
return imageUtils.getImageData(this.getSvg(), this.width, this.height, sx, sy, sw, sh, options);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Not yet implemented
|
* Not yet implemented
|
||||||
*/
|
*/
|
||||||
Context.prototype.drawFocusRing = function () {};
|
Context.prototype.drawFocusRing = function () {};
|
||||||
Context.prototype.createImageData = function () {};
|
Context.prototype.createImageData = function () {};
|
||||||
Context.prototype.getImageData = function () {};
|
|
||||||
Context.prototype.putImageData = function () {};
|
Context.prototype.putImageData = function () {};
|
||||||
Context.prototype.globalCompositeOperation = function () {};
|
Context.prototype.globalCompositeOperation = function () {};
|
||||||
|
|
||||||
|
49
element.js
49
element.js
@ -1,4 +1,5 @@
|
|||||||
import Context from './context';
|
import Context from './context';
|
||||||
|
import imageUtils from './image';
|
||||||
|
|
||||||
function SVGCanvasElement(options) {
|
function SVGCanvasElement(options) {
|
||||||
|
|
||||||
@ -74,45 +75,15 @@ SVGCanvasElement.prototype.toObjectURL = function() {
|
|||||||
return URL.createObjectURL(svg);
|
return URL.createObjectURL(svg);
|
||||||
};
|
};
|
||||||
|
|
||||||
SVGCanvasElement.prototype.toDataURL = function(type, options) {
|
/**
|
||||||
var xml = new XMLSerializer().serializeToString(this.svg);
|
* toDataURL returns a data URI containing a representation of the image in the format specified by the type parameter.
|
||||||
|
*
|
||||||
// documentMode is an IE-only property
|
* @param {String} type A DOMString indicating the image format. The default type is image/svg+xml; this image format will be also used if the specified type is not supported.
|
||||||
// http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx
|
* @param {Number} encoderOptions A Number between 0 and 1 indicating the image quality to be used when creating images using file formats that support lossy compression (such as image/jpeg or image/webp). A user agent will use its default quality value if this option is not specified, or if the number is outside the allowed range.
|
||||||
// http://stackoverflow.com/questions/10964966/detect-ie-version-prior-to-v9-in-javascript
|
* @param {Boolean} options.async Will return a Promise<String> if true, must be set to true if type is not image/svg+xml
|
||||||
var isIE = document.documentMode;
|
*/
|
||||||
|
SVGCanvasElement.prototype.toDataURL = function(type, encoderOptions, options) {
|
||||||
if (isIE) {
|
return imageUtils.toDataURL(this.svg, this.width, this.height, type, encoderOptions, options)
|
||||||
// This is patch from canvas2svg
|
|
||||||
// IE search for a duplicate xmnls because they didn't implement setAttributeNS correctly
|
|
||||||
var xmlns = /xmlns="http:\/\/www\.w3\.org\/2000\/svg".+xmlns="http:\/\/www\.w3\.org\/2000\/svg/gi;
|
|
||||||
if(xmlns.test(xml)) {
|
|
||||||
xml = xml.replace('xmlns="http://www.w3.org/2000/svg','xmlns:xlink="http://www.w3.org/1999/xlink');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var SVGDataURL = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(xml);
|
|
||||||
if (type === "image/svg+xml" || !type) {
|
|
||||||
return SVGDataURL;
|
|
||||||
}
|
|
||||||
if (type === "image/jpeg" || type === "image/png") {
|
|
||||||
var canvas = document.createElement('canvas');
|
|
||||||
canvas.width = this.width;
|
|
||||||
canvas.height = this.height;
|
|
||||||
var ctx = canvas.getContext('2d');
|
|
||||||
var img = new Image();
|
|
||||||
img.src = SVGDataURL;
|
|
||||||
if (img.complete && img.width > 0 && img.height > 0) {
|
|
||||||
// for chrome, it's ready immediately
|
|
||||||
ctx.drawImage(img, 0, 0);
|
|
||||||
return canvas.toDataURL(type, options);
|
|
||||||
} else {
|
|
||||||
// for firefox, it's not possible to provide sync api in current thread
|
|
||||||
// and web worker doesn't provide canvas API, so
|
|
||||||
throw new Error('svgcanvas.toDataURL() for jpeg/png is only available in Chrome.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new Error('Unknown type for SVGCanvas.prototype.toDataURL, please use image/jpeg | image/png | image/svg+xml.');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SVGCanvasElement.prototype.addEventListener = function() {
|
SVGCanvasElement.prototype.addEventListener = function() {
|
||||||
|
86
image.js
Normal file
86
image.js
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
class ImageUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert svg dataurl to canvas element
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
async svg2canvas(svgDataURL, width, height) {
|
||||||
|
const svgImage = await new Promise((resolve) => {
|
||||||
|
var svgImage = new Image();
|
||||||
|
svgImage.onload = function() {
|
||||||
|
resolve(svgImage);
|
||||||
|
}
|
||||||
|
svgImage.src = svgDataURL;
|
||||||
|
})
|
||||||
|
var canvas = document.createElement('canvas');
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
ctx.drawImage(svgImage, 0, 0);
|
||||||
|
return canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
toDataURL(svgNode, width, height, type, encoderOptions, options) {
|
||||||
|
var xml = new XMLSerializer().serializeToString(svgNode);
|
||||||
|
|
||||||
|
// documentMode is an IE-only property
|
||||||
|
// http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx
|
||||||
|
// http://stackoverflow.com/questions/10964966/detect-ie-version-prior-to-v9-in-javascript
|
||||||
|
var isIE = document.documentMode;
|
||||||
|
|
||||||
|
if (isIE) {
|
||||||
|
// This is patch from canvas2svg
|
||||||
|
// IE search for a duplicate xmnls because they didn't implement setAttributeNS correctly
|
||||||
|
var xmlns = /xmlns="http:\/\/www\.w3\.org\/2000\/svg".+xmlns="http:\/\/www\.w3\.org\/2000\/svg/gi;
|
||||||
|
if(xmlns.test(xml)) {
|
||||||
|
xml = xml.replace('xmlns="http://www.w3.org/2000/svg','xmlns:xlink="http://www.w3.org/1999/xlink');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!options) {
|
||||||
|
options = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
var SVGDataURL = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(xml);
|
||||||
|
if (type === "image/svg+xml" || !type) {
|
||||||
|
if (options.async) {
|
||||||
|
return Promise.resolve(SVGDataURL)
|
||||||
|
}
|
||||||
|
return SVGDataURL;
|
||||||
|
}
|
||||||
|
if (type === "image/jpeg" || type === "image/png") {
|
||||||
|
if (!options.async) {
|
||||||
|
throw new Error('svgcanvas: options.async must be set to true if type is image/jpeg | image/png')
|
||||||
|
}
|
||||||
|
return (async () => {
|
||||||
|
const canvas = await this.svg2canvas(SVGDataURL, width, height);
|
||||||
|
const dataUrl = canvas.toDataURL(type, encoderOptions);
|
||||||
|
canvas.remove();
|
||||||
|
return dataUrl;
|
||||||
|
})()
|
||||||
|
}
|
||||||
|
throw new Error('svgcanvas: Unknown type for toDataURL, please use image/jpeg | image/png | image/svg+xml.');
|
||||||
|
}
|
||||||
|
|
||||||
|
getImageData(svgNode, width, height, sx, sy, sw, sh, options) {
|
||||||
|
if (!options) {
|
||||||
|
options = {}
|
||||||
|
}
|
||||||
|
if (!options.async) {
|
||||||
|
throw new Error('svgcanvas: options.async must be set to true for getImageData')
|
||||||
|
}
|
||||||
|
const svgDataURL = this.toDataURL(svgNode, width, height, 'image/svg+xml');
|
||||||
|
return (async () => {
|
||||||
|
const canvas = await this.svg2canvas(svgDataURL, width, height);
|
||||||
|
const ctx = canvas.getContext('2d')
|
||||||
|
const imageData = ctx.getImageData(sx, sy, sw, sh);
|
||||||
|
canvas.remove();
|
||||||
|
return imageData;
|
||||||
|
})()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const utils = new ImageUtils();
|
||||||
|
|
||||||
|
export default utils;
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "svgcanvas",
|
"name": "svgcanvas",
|
||||||
"version": "2.1.0",
|
"version": "2.2.0",
|
||||||
"description": "svgcanvas",
|
"description": "svgcanvas",
|
||||||
"main": "dist/svgcanvas.js",
|
"main": "dist/svgcanvas.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user