ding-image-editor 3.15.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +193 -0
- package/dist/svg/icon-a.svg +376 -0
- package/dist/svg/icon-b.svg +369 -0
- package/dist/svg/icon-c.svg +369 -0
- package/dist/svg/icon-d.svg +369 -0
- package/dist/tui-image-editor.css +6 -0
- package/dist/tui-image-editor.js +62329 -0
- package/dist/tui-image-editor.min.css +5 -0
- package/dist/tui-image-editor.min.js +15 -0
- package/index.d.ts +334 -0
- package/package.json +52 -0
- package/src/css/buttons.styl +102 -0
- package/src/css/checkbox.styl +86 -0
- package/src/css/colorpicker.styl +98 -0
- package/src/css/gridtable.styl +45 -0
- package/src/css/icon.styl +44 -0
- package/src/css/index.styl +17 -0
- package/src/css/main.styl +163 -0
- package/src/css/position.styl +309 -0
- package/src/css/range.styl +91 -0
- package/src/css/submenu.styl +168 -0
- package/src/index.js +29 -0
- package/src/js/action.js +686 -0
- package/src/js/command/addIcon.js +42 -0
- package/src/js/command/addImageObject.js +34 -0
- package/src/js/command/addObject.js +43 -0
- package/src/js/command/addShape.js +51 -0
- package/src/js/command/addText.js +73 -0
- package/src/js/command/applyFilter.js +95 -0
- package/src/js/command/changeIconColor.js +48 -0
- package/src/js/command/changeSelection.js +31 -0
- package/src/js/command/changeShape.js +84 -0
- package/src/js/command/changeText.js +44 -0
- package/src/js/command/changeTextStyle.js +80 -0
- package/src/js/command/clearObjects.js +33 -0
- package/src/js/command/flip.js +36 -0
- package/src/js/command/loadImage.js +58 -0
- package/src/js/command/removeFilter.js +38 -0
- package/src/js/command/removeObject.js +37 -0
- package/src/js/command/resize.js +41 -0
- package/src/js/command/resizeCanvasDimension.js +40 -0
- package/src/js/command/rotate.js +64 -0
- package/src/js/command/setObjectPosition.js +50 -0
- package/src/js/command/setObjectProperties.js +55 -0
- package/src/js/component/cropper.js +407 -0
- package/src/js/component/filter.js +229 -0
- package/src/js/component/flip.js +146 -0
- package/src/js/component/freeDrawing.js +144 -0
- package/src/js/component/icon.js +246 -0
- package/src/js/component/imageLoader.js +84 -0
- package/src/js/component/line.js +205 -0
- package/src/js/component/resize.js +103 -0
- package/src/js/component/rotation.js +91 -0
- package/src/js/component/shape.js +601 -0
- package/src/js/component/text.js +572 -0
- package/src/js/component/zoom.js +708 -0
- package/src/js/consts.js +404 -0
- package/src/js/drawingMode/cropper.js +35 -0
- package/src/js/drawingMode/freeDrawing.js +36 -0
- package/src/js/drawingMode/icon.js +35 -0
- package/src/js/drawingMode/lineDrawing.js +36 -0
- package/src/js/drawingMode/resize.js +35 -0
- package/src/js/drawingMode/shape.js +35 -0
- package/src/js/drawingMode/text.js +35 -0
- package/src/js/drawingMode/zoom.js +37 -0
- package/src/js/extension/arrowLine.js +172 -0
- package/src/js/extension/blur.js +29 -0
- package/src/js/extension/colorFilter.js +104 -0
- package/src/js/extension/cropzone.js +568 -0
- package/src/js/extension/emboss.js +29 -0
- package/src/js/extension/mask.js +90 -0
- package/src/js/extension/sharpen.js +29 -0
- package/src/js/factory/command.js +36 -0
- package/src/js/factory/errorMessage.js +27 -0
- package/src/js/graphics.js +1539 -0
- package/src/js/helper/imagetracer.js +1396 -0
- package/src/js/helper/selectionModifyHelper.js +86 -0
- package/src/js/helper/shapeFilterFillHelper.js +564 -0
- package/src/js/helper/shapeResizeHelper.js +237 -0
- package/src/js/imageEditor.js +1795 -0
- package/src/js/interface/command.js +131 -0
- package/src/js/interface/component.js +127 -0
- package/src/js/interface/drawingMode.js +47 -0
- package/src/js/invoker.js +292 -0
- package/src/js/polyfill.js +498 -0
- package/src/js/ui/crop.js +139 -0
- package/src/js/ui/draw.js +187 -0
- package/src/js/ui/filter.js +510 -0
- package/src/js/ui/flip.js +87 -0
- package/src/js/ui/history.js +171 -0
- package/src/js/ui/icon.js +191 -0
- package/src/js/ui/locale/locale.js +19 -0
- package/src/js/ui/mask.js +96 -0
- package/src/js/ui/panelMenu.js +130 -0
- package/src/js/ui/resize.js +241 -0
- package/src/js/ui/rotate.js +123 -0
- package/src/js/ui/shape.js +265 -0
- package/src/js/ui/submenuBase.js +122 -0
- package/src/js/ui/template/controls.js +21 -0
- package/src/js/ui/template/mainContainer.js +38 -0
- package/src/js/ui/template/style.js +146 -0
- package/src/js/ui/template/submenu/crop.js +73 -0
- package/src/js/ui/template/submenu/draw.js +42 -0
- package/src/js/ui/template/submenu/filter.js +157 -0
- package/src/js/ui/template/submenu/flip.js +41 -0
- package/src/js/ui/template/submenu/history.js +22 -0
- package/src/js/ui/template/submenu/icon.js +108 -0
- package/src/js/ui/template/submenu/mask.js +30 -0
- package/src/js/ui/template/submenu/resize.js +54 -0
- package/src/js/ui/template/submenu/rotate.js +32 -0
- package/src/js/ui/template/submenu/shape.js +45 -0
- package/src/js/ui/template/submenu/text.js +67 -0
- package/src/js/ui/template/submenu/zoom.js +41 -0
- package/src/js/ui/text.js +279 -0
- package/src/js/ui/theme/standard.js +220 -0
- package/src/js/ui/theme/theme.js +249 -0
- package/src/js/ui/tools/colorpicker.js +250 -0
- package/src/js/ui/tools/range.js +390 -0
- package/src/js/ui.js +858 -0
- package/src/js/util.js +551 -0
- package/src/svg/default.svg +335 -0
- package/src/svg/icon-a/ic-apply.svg +6 -0
- package/src/svg/icon-a/ic-cancel.svg +6 -0
- package/src/svg/icon-a/ic-color-transparent-w.svg +12 -0
- package/src/svg/icon-a/ic-crop.svg +7 -0
- package/src/svg/icon-a/ic-delete-all.svg +6 -0
- package/src/svg/icon-a/ic-delete.svg +6 -0
- package/src/svg/icon-a/ic-draw-free.svg +5 -0
- package/src/svg/icon-a/ic-draw-line.svg +5 -0
- package/src/svg/icon-a/ic-draw.svg +6 -0
- package/src/svg/icon-a/ic-filter.svg +7 -0
- package/src/svg/icon-a/ic-flip-reset.svg +7 -0
- package/src/svg/icon-a/ic-flip-x.svg +6 -0
- package/src/svg/icon-a/ic-flip-y.svg +6 -0
- package/src/svg/icon-a/ic-flip.svg +6 -0
- package/src/svg/icon-a/ic-history-check.svg +5 -0
- package/src/svg/icon-a/ic-history-crop.svg +7 -0
- package/src/svg/icon-a/ic-history-delete.svg +9 -0
- package/src/svg/icon-a/ic-history-draw.svg +7 -0
- package/src/svg/icon-a/ic-history-filter.svg +8 -0
- package/src/svg/icon-a/ic-history-flip.svg +6 -0
- package/src/svg/icon-a/ic-history-group.svg +9 -0
- package/src/svg/icon-a/ic-history-icon.svg +6 -0
- package/src/svg/icon-a/ic-history-load.svg +7 -0
- package/src/svg/icon-a/ic-history-mask.svg +9 -0
- package/src/svg/icon-a/ic-history-resize.svg +12 -0
- package/src/svg/icon-a/ic-history-rotate.svg +16 -0
- package/src/svg/icon-a/ic-history-shape.svg +7 -0
- package/src/svg/icon-a/ic-history-text.svg +8 -0
- package/src/svg/icon-a/ic-history.svg +6 -0
- package/src/svg/icon-a/ic-icon-arrow-2.svg +5 -0
- package/src/svg/icon-a/ic-icon-arrow-3.svg +5 -0
- package/src/svg/icon-a/ic-icon-arrow.svg +5 -0
- package/src/svg/icon-a/ic-icon-bubble.svg +5 -0
- package/src/svg/icon-a/ic-icon-heart.svg +5 -0
- package/src/svg/icon-a/ic-icon-load.svg +8 -0
- package/src/svg/icon-a/ic-icon-location.svg +8 -0
- package/src/svg/icon-a/ic-icon-polygon.svg +5 -0
- package/src/svg/icon-a/ic-icon-star-2.svg +5 -0
- package/src/svg/icon-a/ic-icon-star.svg +5 -0
- package/src/svg/icon-a/ic-icon.svg +5 -0
- package/src/svg/icon-a/ic-mask-load.svg +8 -0
- package/src/svg/icon-a/ic-mask.svg +6 -0
- package/src/svg/icon-a/ic-redo.svg +7 -0
- package/src/svg/icon-a/ic-reset.svg +7 -0
- package/src/svg/icon-a/ic-resize.svg +13 -0
- package/src/svg/icon-a/ic-rotate-clockwise.svg +7 -0
- package/src/svg/icon-a/ic-rotate-counterclockwise.svg +7 -0
- package/src/svg/icon-a/ic-rotate.svg +7 -0
- package/src/svg/icon-a/ic-shape-circle.svg +5 -0
- package/src/svg/icon-a/ic-shape-rectangle.svg +5 -0
- package/src/svg/icon-a/ic-shape-triangle.svg +5 -0
- package/src/svg/icon-a/ic-shape.svg +6 -0
- package/src/svg/icon-a/ic-text-align-center.svg +6 -0
- package/src/svg/icon-a/ic-text-align-left.svg +6 -0
- package/src/svg/icon-a/ic-text-align-right.svg +6 -0
- package/src/svg/icon-a/ic-text-bold.svg +7 -0
- package/src/svg/icon-a/ic-text-italic.svg +6 -0
- package/src/svg/icon-a/ic-text-underline.svg +7 -0
- package/src/svg/icon-a/ic-text.svg +7 -0
- package/src/svg/icon-a/ic-undo.svg +7 -0
- package/src/svg/icon-a/ic-zoom-hand.svg +8 -0
- package/src/svg/icon-a/ic-zoom-zoom-in.svg +10 -0
- package/src/svg/icon-a/ic-zoom-zoom-out.svg +9 -0
- package/src/svg/icon-a/img-bi.svg +5 -0
- package/src/svg/icon-b/ic-apply.svg +6 -0
- package/src/svg/icon-b/ic-cancel.svg +6 -0
- package/src/svg/icon-b/ic-crop.svg +7 -0
- package/src/svg/icon-b/ic-delete-all.svg +6 -0
- package/src/svg/icon-b/ic-delete.svg +6 -0
- package/src/svg/icon-b/ic-draw-free.svg +5 -0
- package/src/svg/icon-b/ic-draw-line.svg +5 -0
- package/src/svg/icon-b/ic-draw.svg +6 -0
- package/src/svg/icon-b/ic-filter.svg +7 -0
- package/src/svg/icon-b/ic-flip-reset.svg +7 -0
- package/src/svg/icon-b/ic-flip-x.svg +6 -0
- package/src/svg/icon-b/ic-flip-y.svg +6 -0
- package/src/svg/icon-b/ic-flip.svg +6 -0
- package/src/svg/icon-b/ic-history-check.svg +5 -0
- package/src/svg/icon-b/ic-history-crop.svg +7 -0
- package/src/svg/icon-b/ic-history-delete.svg +9 -0
- package/src/svg/icon-b/ic-history-draw.svg +7 -0
- package/src/svg/icon-b/ic-history-filter.svg +8 -0
- package/src/svg/icon-b/ic-history-flip.svg +6 -0
- package/src/svg/icon-b/ic-history-group.svg +9 -0
- package/src/svg/icon-b/ic-history-icon.svg +6 -0
- package/src/svg/icon-b/ic-history-load.svg +7 -0
- package/src/svg/icon-b/ic-history-mask.svg +9 -0
- package/src/svg/icon-b/ic-history-resize.svg +12 -0
- package/src/svg/icon-b/ic-history-rotate.svg +16 -0
- package/src/svg/icon-b/ic-history-shape.svg +7 -0
- package/src/svg/icon-b/ic-history-text.svg +8 -0
- package/src/svg/icon-b/ic-history.svg +6 -0
- package/src/svg/icon-b/ic-icon-arrow-2.svg +5 -0
- package/src/svg/icon-b/ic-icon-arrow-3.svg +5 -0
- package/src/svg/icon-b/ic-icon-arrow.svg +5 -0
- package/src/svg/icon-b/ic-icon-bubble.svg +5 -0
- package/src/svg/icon-b/ic-icon-heart.svg +5 -0
- package/src/svg/icon-b/ic-icon-load.svg +8 -0
- package/src/svg/icon-b/ic-icon-location.svg +8 -0
- package/src/svg/icon-b/ic-icon-polygon.svg +5 -0
- package/src/svg/icon-b/ic-icon-star-2.svg +5 -0
- package/src/svg/icon-b/ic-icon-star.svg +5 -0
- package/src/svg/icon-b/ic-icon.svg +5 -0
- package/src/svg/icon-b/ic-mask-load.svg +8 -0
- package/src/svg/icon-b/ic-mask.svg +6 -0
- package/src/svg/icon-b/ic-redo.svg +7 -0
- package/src/svg/icon-b/ic-reset.svg +7 -0
- package/src/svg/icon-b/ic-resize.svg +13 -0
- package/src/svg/icon-b/ic-rotate-clockwise.svg +7 -0
- package/src/svg/icon-b/ic-rotate-counterclockwise.svg +7 -0
- package/src/svg/icon-b/ic-rotate.svg +7 -0
- package/src/svg/icon-b/ic-shape-circle.svg +5 -0
- package/src/svg/icon-b/ic-shape-rectangle.svg +5 -0
- package/src/svg/icon-b/ic-shape-triangle.svg +5 -0
- package/src/svg/icon-b/ic-shape.svg +6 -0
- package/src/svg/icon-b/ic-text-align-center.svg +6 -0
- package/src/svg/icon-b/ic-text-align-left.svg +6 -0
- package/src/svg/icon-b/ic-text-align-right.svg +6 -0
- package/src/svg/icon-b/ic-text-bold.svg +7 -0
- package/src/svg/icon-b/ic-text-italic.svg +6 -0
- package/src/svg/icon-b/ic-text-underline.svg +7 -0
- package/src/svg/icon-b/ic-text.svg +7 -0
- package/src/svg/icon-b/ic-undo.svg +7 -0
- package/src/svg/icon-b/ic-zoom-hand.svg +8 -0
- package/src/svg/icon-b/ic-zoom-zoom-in.svg +12 -0
- package/src/svg/icon-b/ic-zoom-zoom-out.svg +11 -0
- package/src/svg/icon-b/img-bi.svg +5 -0
- package/src/svg/icon-c/ic-apply.svg +6 -0
- package/src/svg/icon-c/ic-cancel.svg +6 -0
- package/src/svg/icon-c/ic-crop.svg +7 -0
- package/src/svg/icon-c/ic-delete-all.svg +6 -0
- package/src/svg/icon-c/ic-delete.svg +6 -0
- package/src/svg/icon-c/ic-draw-free.svg +5 -0
- package/src/svg/icon-c/ic-draw-line.svg +5 -0
- package/src/svg/icon-c/ic-draw.svg +6 -0
- package/src/svg/icon-c/ic-filter.svg +7 -0
- package/src/svg/icon-c/ic-flip-reset.svg +7 -0
- package/src/svg/icon-c/ic-flip-x.svg +6 -0
- package/src/svg/icon-c/ic-flip-y.svg +6 -0
- package/src/svg/icon-c/ic-flip.svg +6 -0
- package/src/svg/icon-c/ic-history-check.svg +5 -0
- package/src/svg/icon-c/ic-history-crop.svg +7 -0
- package/src/svg/icon-c/ic-history-delete.svg +9 -0
- package/src/svg/icon-c/ic-history-draw.svg +7 -0
- package/src/svg/icon-c/ic-history-filter.svg +8 -0
- package/src/svg/icon-c/ic-history-flip.svg +6 -0
- package/src/svg/icon-c/ic-history-group.svg +9 -0
- package/src/svg/icon-c/ic-history-icon.svg +6 -0
- package/src/svg/icon-c/ic-history-load.svg +7 -0
- package/src/svg/icon-c/ic-history-mask.svg +9 -0
- package/src/svg/icon-c/ic-history-resize.svg +12 -0
- package/src/svg/icon-c/ic-history-rotate.svg +16 -0
- package/src/svg/icon-c/ic-history-shape.svg +7 -0
- package/src/svg/icon-c/ic-history-text.svg +8 -0
- package/src/svg/icon-c/ic-history.svg +6 -0
- package/src/svg/icon-c/ic-icon-arrow-2.svg +5 -0
- package/src/svg/icon-c/ic-icon-arrow-3.svg +5 -0
- package/src/svg/icon-c/ic-icon-arrow.svg +5 -0
- package/src/svg/icon-c/ic-icon-bubble.svg +5 -0
- package/src/svg/icon-c/ic-icon-heart.svg +5 -0
- package/src/svg/icon-c/ic-icon-load.svg +8 -0
- package/src/svg/icon-c/ic-icon-location.svg +8 -0
- package/src/svg/icon-c/ic-icon-polygon.svg +5 -0
- package/src/svg/icon-c/ic-icon-star-2.svg +5 -0
- package/src/svg/icon-c/ic-icon-star.svg +5 -0
- package/src/svg/icon-c/ic-icon.svg +5 -0
- package/src/svg/icon-c/ic-mask-load.svg +8 -0
- package/src/svg/icon-c/ic-mask.svg +6 -0
- package/src/svg/icon-c/ic-redo.svg +7 -0
- package/src/svg/icon-c/ic-reset.svg +7 -0
- package/src/svg/icon-c/ic-resize.svg +13 -0
- package/src/svg/icon-c/ic-rotate-clockwise.svg +7 -0
- package/src/svg/icon-c/ic-rotate-counterclockwise.svg +7 -0
- package/src/svg/icon-c/ic-rotate.svg +7 -0
- package/src/svg/icon-c/ic-shape-circle.svg +5 -0
- package/src/svg/icon-c/ic-shape-rectangle.svg +5 -0
- package/src/svg/icon-c/ic-shape-triangle.svg +5 -0
- package/src/svg/icon-c/ic-shape.svg +6 -0
- package/src/svg/icon-c/ic-text-align-center.svg +6 -0
- package/src/svg/icon-c/ic-text-align-left.svg +6 -0
- package/src/svg/icon-c/ic-text-align-right.svg +6 -0
- package/src/svg/icon-c/ic-text-bold.svg +7 -0
- package/src/svg/icon-c/ic-text-italic.svg +6 -0
- package/src/svg/icon-c/ic-text-underline.svg +7 -0
- package/src/svg/icon-c/ic-text.svg +7 -0
- package/src/svg/icon-c/ic-undo.svg +7 -0
- package/src/svg/icon-c/ic-zoom-hand.svg +8 -0
- package/src/svg/icon-c/ic-zoom-zoom-in.svg +12 -0
- package/src/svg/icon-c/ic-zoom-zoom-out.svg +11 -0
- package/src/svg/icon-c/img-bi.svg +5 -0
- package/src/svg/icon-d/ic-apply.svg +6 -0
- package/src/svg/icon-d/ic-cancel.svg +6 -0
- package/src/svg/icon-d/ic-crop.svg +7 -0
- package/src/svg/icon-d/ic-delete-all.svg +6 -0
- package/src/svg/icon-d/ic-delete.svg +6 -0
- package/src/svg/icon-d/ic-draw-free.svg +5 -0
- package/src/svg/icon-d/ic-draw-line.svg +5 -0
- package/src/svg/icon-d/ic-draw.svg +6 -0
- package/src/svg/icon-d/ic-filter.svg +7 -0
- package/src/svg/icon-d/ic-flip-reset.svg +7 -0
- package/src/svg/icon-d/ic-flip-x.svg +6 -0
- package/src/svg/icon-d/ic-flip-y.svg +6 -0
- package/src/svg/icon-d/ic-flip.svg +6 -0
- package/src/svg/icon-d/ic-history-check.svg +5 -0
- package/src/svg/icon-d/ic-history-crop.svg +7 -0
- package/src/svg/icon-d/ic-history-delete.svg +9 -0
- package/src/svg/icon-d/ic-history-draw.svg +7 -0
- package/src/svg/icon-d/ic-history-filter.svg +8 -0
- package/src/svg/icon-d/ic-history-flip.svg +6 -0
- package/src/svg/icon-d/ic-history-group.svg +9 -0
- package/src/svg/icon-d/ic-history-icon.svg +6 -0
- package/src/svg/icon-d/ic-history-load.svg +7 -0
- package/src/svg/icon-d/ic-history-mask.svg +9 -0
- package/src/svg/icon-d/ic-history-resize.svg +12 -0
- package/src/svg/icon-d/ic-history-rotate.svg +16 -0
- package/src/svg/icon-d/ic-history-shape.svg +7 -0
- package/src/svg/icon-d/ic-history-text.svg +8 -0
- package/src/svg/icon-d/ic-history.svg +6 -0
- package/src/svg/icon-d/ic-icon-arrow-2.svg +5 -0
- package/src/svg/icon-d/ic-icon-arrow-3.svg +5 -0
- package/src/svg/icon-d/ic-icon-arrow.svg +5 -0
- package/src/svg/icon-d/ic-icon-bubble.svg +5 -0
- package/src/svg/icon-d/ic-icon-heart.svg +5 -0
- package/src/svg/icon-d/ic-icon-load.svg +8 -0
- package/src/svg/icon-d/ic-icon-location.svg +8 -0
- package/src/svg/icon-d/ic-icon-polygon.svg +5 -0
- package/src/svg/icon-d/ic-icon-star-2.svg +5 -0
- package/src/svg/icon-d/ic-icon-star.svg +5 -0
- package/src/svg/icon-d/ic-icon.svg +5 -0
- package/src/svg/icon-d/ic-mask-load.svg +8 -0
- package/src/svg/icon-d/ic-mask.svg +6 -0
- package/src/svg/icon-d/ic-redo.svg +7 -0
- package/src/svg/icon-d/ic-reset.svg +7 -0
- package/src/svg/icon-d/ic-resize.svg +13 -0
- package/src/svg/icon-d/ic-rotate-clockwise.svg +7 -0
- package/src/svg/icon-d/ic-rotate-counterclockwise.svg +7 -0
- package/src/svg/icon-d/ic-rotate.svg +7 -0
- package/src/svg/icon-d/ic-shape-circle.svg +5 -0
- package/src/svg/icon-d/ic-shape-rectangle.svg +5 -0
- package/src/svg/icon-d/ic-shape-triangle.svg +5 -0
- package/src/svg/icon-d/ic-shape.svg +6 -0
- package/src/svg/icon-d/ic-text-align-center.svg +6 -0
- package/src/svg/icon-d/ic-text-align-left.svg +6 -0
- package/src/svg/icon-d/ic-text-align-right.svg +6 -0
- package/src/svg/icon-d/ic-text-bold.svg +7 -0
- package/src/svg/icon-d/ic-text-italic.svg +6 -0
- package/src/svg/icon-d/ic-text-underline.svg +7 -0
- package/src/svg/icon-d/ic-text.svg +7 -0
- package/src/svg/icon-d/ic-undo.svg +7 -0
- package/src/svg/icon-d/ic-zoom-hand.svg +8 -0
- package/src/svg/icon-d/ic-zoom-zoom-in.svg +12 -0
- package/src/svg/icon-d/ic-zoom-zoom-out.svg +11 -0
- package/src/svg/icon-d/img-bi.svg +5 -0
@@ -0,0 +1,1396 @@
|
|
1
|
+
/*
|
2
|
+
imagetracer.js version 1.2.4
|
3
|
+
Simple raster image tracer and vectorizer written in JavaScript.
|
4
|
+
andras@jankovics.net
|
5
|
+
*/
|
6
|
+
|
7
|
+
/*
|
8
|
+
The Unlicense / PUBLIC DOMAIN
|
9
|
+
This is free and unencumbered software released into the public domain.
|
10
|
+
Anyone is free to copy, modify, publish, use, compile, sell, or
|
11
|
+
distribute this software, either in source code form or as a compiled
|
12
|
+
binary, for any purpose, commercial or non-commercial, and by any
|
13
|
+
means.
|
14
|
+
In jurisdictions that recognize copyright laws, the author or authors
|
15
|
+
of this software dedicate any and all copyright interest in the
|
16
|
+
software to the public domain. We make this dedication for the benefit
|
17
|
+
of the public at large and to the detriment of our heirs and
|
18
|
+
successors. We intend this dedication to be an overt act of
|
19
|
+
relinquishment in perpetuity of all present and future rights to this
|
20
|
+
software under copyright law.
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
22
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
23
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
24
|
+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
25
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
26
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
27
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
28
|
+
For more information, please refer to http://unlicense.org/
|
29
|
+
*/
|
30
|
+
export default class ImageTracer {
|
31
|
+
static tracerDefaultOption() {
|
32
|
+
return {
|
33
|
+
pathomit: 100,
|
34
|
+
ltres: 0.1,
|
35
|
+
qtres: 1,
|
36
|
+
|
37
|
+
scale: 1,
|
38
|
+
strokewidth: 5,
|
39
|
+
viewbox: false,
|
40
|
+
linefilter: true,
|
41
|
+
desc: false,
|
42
|
+
rightangleenhance: false,
|
43
|
+
pal: [
|
44
|
+
{
|
45
|
+
r: 0,
|
46
|
+
g: 0,
|
47
|
+
b: 0,
|
48
|
+
a: 255,
|
49
|
+
},
|
50
|
+
{
|
51
|
+
r: 255,
|
52
|
+
g: 255,
|
53
|
+
b: 255,
|
54
|
+
a: 255,
|
55
|
+
},
|
56
|
+
],
|
57
|
+
};
|
58
|
+
}
|
59
|
+
/* eslint-disable */
|
60
|
+
constructor() {
|
61
|
+
this.versionnumber = '1.2.4';
|
62
|
+
this.optionpresets = {
|
63
|
+
default: {
|
64
|
+
corsenabled: false,
|
65
|
+
ltres: 1,
|
66
|
+
qtres: 1,
|
67
|
+
pathomit: 8,
|
68
|
+
rightangleenhance: true,
|
69
|
+
colorsampling: 2,
|
70
|
+
numberofcolors: 16,
|
71
|
+
mincolorratio: 0,
|
72
|
+
colorquantcycles: 3,
|
73
|
+
layering: 0,
|
74
|
+
strokewidth: 1,
|
75
|
+
linefilter: false,
|
76
|
+
scale: 1,
|
77
|
+
roundcoords: 1,
|
78
|
+
viewbox: false,
|
79
|
+
desc: false,
|
80
|
+
lcpr: 0,
|
81
|
+
qcpr: 0,
|
82
|
+
blurradius: 0,
|
83
|
+
blurdelta: 20,
|
84
|
+
},
|
85
|
+
posterized1: {
|
86
|
+
colorsampling: 0,
|
87
|
+
numberofcolors: 2,
|
88
|
+
},
|
89
|
+
posterized2: {
|
90
|
+
numberofcolors: 4,
|
91
|
+
blurradius: 5,
|
92
|
+
},
|
93
|
+
curvy: {
|
94
|
+
ltres: 0.01,
|
95
|
+
linefilter: true,
|
96
|
+
rightangleenhance: false,
|
97
|
+
},
|
98
|
+
sharp: { qtres: 0.01, linefilter: false },
|
99
|
+
detailed: { pathomit: 0, roundcoords: 2, ltres: 0.5, qtres: 0.5, numberofcolors: 64 },
|
100
|
+
smoothed: { blurradius: 5, blurdelta: 64 },
|
101
|
+
grayscale: { colorsampling: 0, colorquantcycles: 1, numberofcolors: 7 },
|
102
|
+
fixedpalette: { colorsampling: 0, colorquantcycles: 1, numberofcolors: 27 },
|
103
|
+
randomsampling1: { colorsampling: 1, numberofcolors: 8 },
|
104
|
+
randomsampling2: { colorsampling: 1, numberofcolors: 64 },
|
105
|
+
artistic1: {
|
106
|
+
colorsampling: 0,
|
107
|
+
colorquantcycles: 1,
|
108
|
+
pathomit: 0,
|
109
|
+
blurradius: 5,
|
110
|
+
blurdelta: 64,
|
111
|
+
ltres: 0.01,
|
112
|
+
linefilter: true,
|
113
|
+
numberofcolors: 16,
|
114
|
+
strokewidth: 2,
|
115
|
+
},
|
116
|
+
artistic2: {
|
117
|
+
qtres: 0.01,
|
118
|
+
colorsampling: 0,
|
119
|
+
colorquantcycles: 1,
|
120
|
+
numberofcolors: 4,
|
121
|
+
strokewidth: 0,
|
122
|
+
},
|
123
|
+
artistic3: { qtres: 10, ltres: 10, numberofcolors: 8 },
|
124
|
+
artistic4: {
|
125
|
+
qtres: 10,
|
126
|
+
ltres: 10,
|
127
|
+
numberofcolors: 64,
|
128
|
+
blurradius: 5,
|
129
|
+
blurdelta: 256,
|
130
|
+
strokewidth: 2,
|
131
|
+
},
|
132
|
+
posterized3: {
|
133
|
+
ltres: 1,
|
134
|
+
qtres: 1,
|
135
|
+
pathomit: 20,
|
136
|
+
rightangleenhance: true,
|
137
|
+
colorsampling: 0,
|
138
|
+
numberofcolors: 3,
|
139
|
+
mincolorratio: 0,
|
140
|
+
colorquantcycles: 3,
|
141
|
+
blurradius: 3,
|
142
|
+
blurdelta: 20,
|
143
|
+
strokewidth: 0,
|
144
|
+
linefilter: false,
|
145
|
+
roundcoords: 1,
|
146
|
+
pal: [
|
147
|
+
{ r: 0, g: 0, b: 100, a: 255 },
|
148
|
+
{ r: 255, g: 255, b: 255, a: 255 },
|
149
|
+
],
|
150
|
+
},
|
151
|
+
};
|
152
|
+
|
153
|
+
this.pathscan_combined_lookup = [
|
154
|
+
[
|
155
|
+
[-1, -1, -1, -1],
|
156
|
+
[-1, -1, -1, -1],
|
157
|
+
[-1, -1, -1, -1],
|
158
|
+
[-1, -1, -1, -1],
|
159
|
+
],
|
160
|
+
[
|
161
|
+
[0, 1, 0, -1],
|
162
|
+
[-1, -1, -1, -1],
|
163
|
+
[-1, -1, -1, -1],
|
164
|
+
[0, 2, -1, 0],
|
165
|
+
],
|
166
|
+
[
|
167
|
+
[-1, -1, -1, -1],
|
168
|
+
[-1, -1, -1, -1],
|
169
|
+
[0, 1, 0, -1],
|
170
|
+
[0, 0, 1, 0],
|
171
|
+
],
|
172
|
+
[
|
173
|
+
[0, 0, 1, 0],
|
174
|
+
[-1, -1, -1, -1],
|
175
|
+
[0, 2, -1, 0],
|
176
|
+
[-1, -1, -1, -1],
|
177
|
+
],
|
178
|
+
[
|
179
|
+
[-1, -1, -1, -1],
|
180
|
+
[0, 0, 1, 0],
|
181
|
+
[0, 3, 0, 1],
|
182
|
+
[-1, -1, -1, -1],
|
183
|
+
],
|
184
|
+
[
|
185
|
+
[13, 3, 0, 1],
|
186
|
+
[13, 2, -1, 0],
|
187
|
+
[7, 1, 0, -1],
|
188
|
+
[7, 0, 1, 0],
|
189
|
+
],
|
190
|
+
[
|
191
|
+
[-1, -1, -1, -1],
|
192
|
+
[0, 1, 0, -1],
|
193
|
+
[-1, -1, -1, -1],
|
194
|
+
[0, 3, 0, 1],
|
195
|
+
],
|
196
|
+
[
|
197
|
+
[0, 3, 0, 1],
|
198
|
+
[0, 2, -1, 0],
|
199
|
+
[-1, -1, -1, -1],
|
200
|
+
[-1, -1, -1, -1],
|
201
|
+
],
|
202
|
+
[
|
203
|
+
[0, 3, 0, 1],
|
204
|
+
[0, 2, -1, 0],
|
205
|
+
[-1, -1, -1, -1],
|
206
|
+
[-1, -1, -1, -1],
|
207
|
+
],
|
208
|
+
[
|
209
|
+
[-1, -1, -1, -1],
|
210
|
+
[0, 1, 0, -1],
|
211
|
+
[-1, -1, -1, -1],
|
212
|
+
[0, 3, 0, 1],
|
213
|
+
],
|
214
|
+
[
|
215
|
+
[11, 1, 0, -1],
|
216
|
+
[14, 0, 1, 0],
|
217
|
+
[14, 3, 0, 1],
|
218
|
+
[11, 2, -1, 0],
|
219
|
+
],
|
220
|
+
[
|
221
|
+
[-1, -1, -1, -1],
|
222
|
+
[0, 0, 1, 0],
|
223
|
+
[0, 3, 0, 1],
|
224
|
+
[-1, -1, -1, -1],
|
225
|
+
],
|
226
|
+
[
|
227
|
+
[0, 0, 1, 0],
|
228
|
+
[-1, -1, -1, -1],
|
229
|
+
[0, 2, -1, 0],
|
230
|
+
[-1, -1, -1, -1],
|
231
|
+
],
|
232
|
+
[
|
233
|
+
[-1, -1, -1, -1],
|
234
|
+
[-1, -1, -1, -1],
|
235
|
+
[0, 1, 0, -1],
|
236
|
+
[0, 0, 1, 0],
|
237
|
+
],
|
238
|
+
[
|
239
|
+
[0, 1, 0, -1],
|
240
|
+
[-1, -1, -1, -1],
|
241
|
+
[-1, -1, -1, -1],
|
242
|
+
[0, 2, -1, 0],
|
243
|
+
],
|
244
|
+
[
|
245
|
+
[-1, -1, -1, -1],
|
246
|
+
[-1, -1, -1, -1],
|
247
|
+
[-1, -1, -1, -1],
|
248
|
+
[-1, -1, -1, -1],
|
249
|
+
],
|
250
|
+
];
|
251
|
+
|
252
|
+
this.gks = [
|
253
|
+
[0.27901, 0.44198, 0.27901],
|
254
|
+
[0.135336, 0.228569, 0.272192, 0.228569, 0.135336],
|
255
|
+
[0.086776, 0.136394, 0.178908, 0.195843, 0.178908, 0.136394, 0.086776],
|
256
|
+
[0.063327, 0.093095, 0.122589, 0.144599, 0.152781, 0.144599, 0.122589, 0.093095, 0.063327],
|
257
|
+
[
|
258
|
+
0.049692,
|
259
|
+
0.069304,
|
260
|
+
0.089767,
|
261
|
+
0.107988,
|
262
|
+
0.120651,
|
263
|
+
0.125194,
|
264
|
+
0.120651,
|
265
|
+
0.107988,
|
266
|
+
0.089767,
|
267
|
+
0.069304,
|
268
|
+
0.049692,
|
269
|
+
],
|
270
|
+
];
|
271
|
+
|
272
|
+
this.specpalette = [
|
273
|
+
{ r: 0, g: 0, b: 0, a: 255 },
|
274
|
+
{ r: 128, g: 128, b: 128, a: 255 },
|
275
|
+
{ r: 0, g: 0, b: 128, a: 255 },
|
276
|
+
{ r: 64, g: 64, b: 128, a: 255 },
|
277
|
+
{ r: 192, g: 192, b: 192, a: 255 },
|
278
|
+
{ r: 255, g: 255, b: 255, a: 255 },
|
279
|
+
{ r: 128, g: 128, b: 192, a: 255 },
|
280
|
+
{ r: 0, g: 0, b: 192, a: 255 },
|
281
|
+
{ r: 128, g: 0, b: 0, a: 255 },
|
282
|
+
{ r: 128, g: 64, b: 64, a: 255 },
|
283
|
+
{ r: 128, g: 0, b: 128, a: 255 },
|
284
|
+
{ r: 168, g: 168, b: 168, a: 255 },
|
285
|
+
{ r: 192, g: 128, b: 128, a: 255 },
|
286
|
+
{ r: 192, g: 0, b: 0, a: 255 },
|
287
|
+
{ r: 255, g: 255, b: 255, a: 255 },
|
288
|
+
{ r: 0, g: 128, b: 0, a: 255 },
|
289
|
+
];
|
290
|
+
}
|
291
|
+
|
292
|
+
imageToSVG(url, callback, options) {
|
293
|
+
options = this.checkoptions(options);
|
294
|
+
this.loadImage(
|
295
|
+
url,
|
296
|
+
(canvas) => {
|
297
|
+
callback(this.imagedataToSVG(this.getImgdata(canvas), options));
|
298
|
+
},
|
299
|
+
options
|
300
|
+
);
|
301
|
+
}
|
302
|
+
|
303
|
+
imagedataToSVG(imgd, options) {
|
304
|
+
options = this.checkoptions(options);
|
305
|
+
const td = this.imagedataToTracedata(imgd, options);
|
306
|
+
|
307
|
+
return this.getsvgstring(td, options);
|
308
|
+
}
|
309
|
+
|
310
|
+
imageToTracedata(url, callback, options) {
|
311
|
+
options = this.checkoptions(options);
|
312
|
+
this.loadImage(
|
313
|
+
url,
|
314
|
+
(canvas) => {
|
315
|
+
callback(this.imagedataToTracedata(this.getImgdata(canvas), options));
|
316
|
+
},
|
317
|
+
options
|
318
|
+
);
|
319
|
+
}
|
320
|
+
|
321
|
+
imagedataToTracedata(imgd, options) {
|
322
|
+
options = this.checkoptions(options);
|
323
|
+
const ii = this.colorquantization(imgd, options);
|
324
|
+
let tracedata;
|
325
|
+
if (options.layering === 0) {
|
326
|
+
tracedata = {
|
327
|
+
layers: [],
|
328
|
+
palette: ii.palette,
|
329
|
+
width: ii.array[0].length - 2,
|
330
|
+
height: ii.array.length - 2,
|
331
|
+
};
|
332
|
+
|
333
|
+
for (let colornum = 0; colornum < ii.palette.length; colornum += 1) {
|
334
|
+
const tracedlayer = this.batchtracepaths(
|
335
|
+
this.internodes(
|
336
|
+
this.pathscan(this.layeringstep(ii, colornum), options.pathomit),
|
337
|
+
options
|
338
|
+
),
|
339
|
+
options.ltres,
|
340
|
+
options.qtres
|
341
|
+
);
|
342
|
+
tracedata.layers.push(tracedlayer);
|
343
|
+
}
|
344
|
+
} else {
|
345
|
+
const ls = this.layering(ii);
|
346
|
+
if (options.layercontainerid) {
|
347
|
+
this.drawLayers(ls, this.specpalette, options.scale, options.layercontainerid);
|
348
|
+
}
|
349
|
+
const bps = this.batchpathscan(ls, options.pathomit);
|
350
|
+
const bis = this.batchinternodes(bps, options);
|
351
|
+
tracedata = {
|
352
|
+
layers: this.batchtracelayers(bis, options.ltres, options.qtres),
|
353
|
+
palette: ii.palette,
|
354
|
+
width: imgd.width,
|
355
|
+
height: imgd.height,
|
356
|
+
};
|
357
|
+
}
|
358
|
+
|
359
|
+
return tracedata;
|
360
|
+
}
|
361
|
+
|
362
|
+
checkoptions(options) {
|
363
|
+
options = options || {};
|
364
|
+
if (typeof options === 'string') {
|
365
|
+
options = options.toLowerCase();
|
366
|
+
if (this.optionpresets[options]) {
|
367
|
+
options = this.optionpresets[options];
|
368
|
+
} else {
|
369
|
+
options = {};
|
370
|
+
}
|
371
|
+
}
|
372
|
+
const ok = Object.keys(this.optionpresets['default']);
|
373
|
+
for (let k = 0; k < ok.length; k += 1) {
|
374
|
+
if (!options.hasOwnProperty(ok[k])) {
|
375
|
+
options[ok[k]] = this.optionpresets['default'][ok[k]];
|
376
|
+
}
|
377
|
+
}
|
378
|
+
|
379
|
+
return options;
|
380
|
+
}
|
381
|
+
|
382
|
+
colorquantization(imgd, options) {
|
383
|
+
const arr = [];
|
384
|
+
let idx = 0;
|
385
|
+
let cd;
|
386
|
+
let cdl;
|
387
|
+
let ci;
|
388
|
+
const paletteacc = [];
|
389
|
+
const pixelnum = imgd.width * imgd.height;
|
390
|
+
let i;
|
391
|
+
let j;
|
392
|
+
let k;
|
393
|
+
let cnt;
|
394
|
+
let palette;
|
395
|
+
|
396
|
+
for (j = 0; j < imgd.height + 2; j += 1) {
|
397
|
+
arr[j] = [];
|
398
|
+
for (i = 0; i < imgd.width + 2; i += 1) {
|
399
|
+
arr[j][i] = -1;
|
400
|
+
}
|
401
|
+
}
|
402
|
+
if (options.pal) {
|
403
|
+
palette = options.pal;
|
404
|
+
} else if (options.colorsampling === 0) {
|
405
|
+
palette = this.generatepalette(options.numberofcolors);
|
406
|
+
} else if (options.colorsampling === 1) {
|
407
|
+
palette = this.samplepalette(options.numberofcolors, imgd);
|
408
|
+
} else {
|
409
|
+
palette = this.samplepalette2(options.numberofcolors, imgd);
|
410
|
+
}
|
411
|
+
if (options.blurradius > 0) {
|
412
|
+
imgd = this.blur(imgd, options.blurradius, options.blurdelta);
|
413
|
+
}
|
414
|
+
for (cnt = 0; cnt < options.colorquantcycles; cnt += 1) {
|
415
|
+
if (cnt > 0) {
|
416
|
+
for (k = 0; k < palette.length; k += 1) {
|
417
|
+
if (paletteacc[k].n > 0) {
|
418
|
+
palette[k] = {
|
419
|
+
r: Math.floor(paletteacc[k].r / paletteacc[k].n),
|
420
|
+
g: Math.floor(paletteacc[k].g / paletteacc[k].n),
|
421
|
+
b: Math.floor(paletteacc[k].b / paletteacc[k].n),
|
422
|
+
a: Math.floor(paletteacc[k].a / paletteacc[k].n),
|
423
|
+
};
|
424
|
+
}
|
425
|
+
|
426
|
+
if (
|
427
|
+
paletteacc[k].n / pixelnum < options.mincolorratio &&
|
428
|
+
cnt < options.colorquantcycles - 1
|
429
|
+
) {
|
430
|
+
palette[k] = {
|
431
|
+
r: Math.floor(Math.random() * 255),
|
432
|
+
g: Math.floor(Math.random() * 255),
|
433
|
+
b: Math.floor(Math.random() * 255),
|
434
|
+
a: Math.floor(Math.random() * 255),
|
435
|
+
};
|
436
|
+
}
|
437
|
+
}
|
438
|
+
}
|
439
|
+
|
440
|
+
for (i = 0; i < palette.length; i += 1) {
|
441
|
+
paletteacc[i] = { r: 0, g: 0, b: 0, a: 0, n: 0 };
|
442
|
+
}
|
443
|
+
|
444
|
+
for (j = 0; j < imgd.height; j += 1) {
|
445
|
+
for (i = 0; i < imgd.width; i += 1) {
|
446
|
+
idx = (j * imgd.width + i) * 4;
|
447
|
+
|
448
|
+
ci = 0;
|
449
|
+
cdl = 1024;
|
450
|
+
for (k = 0; k < palette.length; k += 1) {
|
451
|
+
cd =
|
452
|
+
Math.abs(palette[k].r - imgd.data[idx]) +
|
453
|
+
Math.abs(palette[k].g - imgd.data[idx + 1]) +
|
454
|
+
Math.abs(palette[k].b - imgd.data[idx + 2]) +
|
455
|
+
Math.abs(palette[k].a - imgd.data[idx + 3]);
|
456
|
+
|
457
|
+
if (cd < cdl) {
|
458
|
+
cdl = cd;
|
459
|
+
ci = k;
|
460
|
+
}
|
461
|
+
}
|
462
|
+
|
463
|
+
paletteacc[ci].r += imgd.data[idx];
|
464
|
+
paletteacc[ci].g += imgd.data[idx + 1];
|
465
|
+
paletteacc[ci].b += imgd.data[idx + 2];
|
466
|
+
paletteacc[ci].a += imgd.data[idx + 3];
|
467
|
+
paletteacc[ci].n += 1;
|
468
|
+
|
469
|
+
arr[j + 1][i + 1] = ci;
|
470
|
+
}
|
471
|
+
}
|
472
|
+
}
|
473
|
+
|
474
|
+
return { array: arr, palette };
|
475
|
+
}
|
476
|
+
|
477
|
+
samplepalette(numberofcolors, imgd) {
|
478
|
+
let idx;
|
479
|
+
const palette = [];
|
480
|
+
for (let i = 0; i < numberofcolors; i += 1) {
|
481
|
+
idx = Math.floor((Math.random() * imgd.data.length) / 4) * 4;
|
482
|
+
palette.push({
|
483
|
+
r: imgd.data[idx],
|
484
|
+
g: imgd.data[idx + 1],
|
485
|
+
b: imgd.data[idx + 2],
|
486
|
+
a: imgd.data[idx + 3],
|
487
|
+
});
|
488
|
+
}
|
489
|
+
|
490
|
+
return palette;
|
491
|
+
}
|
492
|
+
|
493
|
+
samplepalette2(numberofcolors, imgd) {
|
494
|
+
let idx;
|
495
|
+
const palette = [];
|
496
|
+
const ni = Math.ceil(Math.sqrt(numberofcolors));
|
497
|
+
const nj = Math.ceil(numberofcolors / ni);
|
498
|
+
const vx = imgd.width / (ni + 1);
|
499
|
+
const vy = imgd.height / (nj + 1);
|
500
|
+
for (let j = 0; j < nj; j += 1) {
|
501
|
+
for (let i = 0; i < ni; i += 1) {
|
502
|
+
if (palette.length === numberofcolors) {
|
503
|
+
break;
|
504
|
+
} else {
|
505
|
+
idx = Math.floor((j + 1) * vy * imgd.width + (i + 1) * vx) * 4;
|
506
|
+
palette.push({
|
507
|
+
r: imgd.data[idx],
|
508
|
+
g: imgd.data[idx + 1],
|
509
|
+
b: imgd.data[idx + 2],
|
510
|
+
a: imgd.data[idx + 3],
|
511
|
+
});
|
512
|
+
}
|
513
|
+
}
|
514
|
+
}
|
515
|
+
|
516
|
+
return palette;
|
517
|
+
}
|
518
|
+
|
519
|
+
generatepalette(numberofcolors) {
|
520
|
+
const palette = [];
|
521
|
+
let rcnt;
|
522
|
+
let gcnt;
|
523
|
+
let bcnt;
|
524
|
+
if (numberofcolors < 8) {
|
525
|
+
const graystep = Math.floor(255 / (numberofcolors - 1));
|
526
|
+
for (let i = 0; i < numberofcolors; i += 1) {
|
527
|
+
palette.push({ r: i * graystep, g: i * graystep, b: i * graystep, a: 255 });
|
528
|
+
}
|
529
|
+
} else {
|
530
|
+
const colorqnum = Math.floor(Math.pow(numberofcolors, 1 / 3));
|
531
|
+
const colorstep = Math.floor(255 / (colorqnum - 1));
|
532
|
+
const rndnum = numberofcolors - colorqnum * colorqnum * colorqnum;
|
533
|
+
for (rcnt = 0; rcnt < colorqnum; rcnt += 1) {
|
534
|
+
for (gcnt = 0; gcnt < colorqnum; gcnt += 1) {
|
535
|
+
for (bcnt = 0; bcnt < colorqnum; bcnt += 1) {
|
536
|
+
palette.push({ r: rcnt * colorstep, g: gcnt * colorstep, b: bcnt * colorstep, a: 255 });
|
537
|
+
}
|
538
|
+
}
|
539
|
+
}
|
540
|
+
for (rcnt = 0; rcnt < rndnum; rcnt += 1) {
|
541
|
+
palette.push({
|
542
|
+
r: Math.floor(Math.random() * 255),
|
543
|
+
g: Math.floor(Math.random() * 255),
|
544
|
+
b: Math.floor(Math.random() * 255),
|
545
|
+
a: Math.floor(Math.random() * 255),
|
546
|
+
});
|
547
|
+
}
|
548
|
+
}
|
549
|
+
|
550
|
+
return palette;
|
551
|
+
}
|
552
|
+
|
553
|
+
layering(ii) {
|
554
|
+
const layers = [];
|
555
|
+
let val = 0;
|
556
|
+
const ah = ii.array.length;
|
557
|
+
const aw = ii.array[0].length;
|
558
|
+
let n1;
|
559
|
+
let n2;
|
560
|
+
let n3;
|
561
|
+
let n4;
|
562
|
+
let n5;
|
563
|
+
let n6;
|
564
|
+
let n7;
|
565
|
+
let n8;
|
566
|
+
let i;
|
567
|
+
let j;
|
568
|
+
let k;
|
569
|
+
for (k = 0; k < ii.palette.length; k += 1) {
|
570
|
+
layers[k] = [];
|
571
|
+
for (j = 0; j < ah; j += 1) {
|
572
|
+
layers[k][j] = [];
|
573
|
+
for (i = 0; i < aw; i += 1) {
|
574
|
+
layers[k][j][i] = 0;
|
575
|
+
}
|
576
|
+
}
|
577
|
+
}
|
578
|
+
for (j = 1; j < ah - 1; j += 1) {
|
579
|
+
for (i = 1; i < aw - 1; i += 1) {
|
580
|
+
val = ii.array[j][i];
|
581
|
+
|
582
|
+
n1 = ii.array[j - 1][i - 1] === val ? 1 : 0;
|
583
|
+
n2 = ii.array[j - 1][i] === val ? 1 : 0;
|
584
|
+
n3 = ii.array[j - 1][i + 1] === val ? 1 : 0;
|
585
|
+
n4 = ii.array[j][i - 1] === val ? 1 : 0;
|
586
|
+
n5 = ii.array[j][i + 1] === val ? 1 : 0;
|
587
|
+
n6 = ii.array[j + 1][i - 1] === val ? 1 : 0;
|
588
|
+
n7 = ii.array[j + 1][i] === val ? 1 : 0;
|
589
|
+
n8 = ii.array[j + 1][i + 1] === val ? 1 : 0;
|
590
|
+
|
591
|
+
layers[val][j + 1][i + 1] = 1 + n5 * 2 + n8 * 4 + n7 * 8;
|
592
|
+
if (!n4) {
|
593
|
+
layers[val][j + 1][i] = 0 + 2 + n7 * 4 + n6 * 8;
|
594
|
+
}
|
595
|
+
if (!n2) {
|
596
|
+
layers[val][j][i + 1] = 0 + n3 * 2 + n5 * 4 + 8;
|
597
|
+
}
|
598
|
+
if (!n1) {
|
599
|
+
layers[val][j][i] = 0 + n2 * 2 + 4 + n4 * 8;
|
600
|
+
}
|
601
|
+
}
|
602
|
+
}
|
603
|
+
|
604
|
+
return layers;
|
605
|
+
}
|
606
|
+
|
607
|
+
layeringstep(ii, cnum) {
|
608
|
+
const layer = [];
|
609
|
+
const ah = ii.array.length;
|
610
|
+
const aw = ii.array[0].length;
|
611
|
+
let i;
|
612
|
+
let j;
|
613
|
+
for (j = 0; j < ah; j += 1) {
|
614
|
+
layer[j] = [];
|
615
|
+
for (i = 0; i < aw; i += 1) {
|
616
|
+
layer[j][i] = 0;
|
617
|
+
}
|
618
|
+
}
|
619
|
+
for (j = 1; j < ah; j += 1) {
|
620
|
+
for (i = 1; i < aw; i += 1) {
|
621
|
+
layer[j][i] =
|
622
|
+
(ii.array[j - 1][i - 1] === cnum ? 1 : 0) +
|
623
|
+
(ii.array[j - 1][i] === cnum ? 2 : 0) +
|
624
|
+
(ii.array[j][i - 1] === cnum ? 8 : 0) +
|
625
|
+
(ii.array[j][i] === cnum ? 4 : 0);
|
626
|
+
}
|
627
|
+
}
|
628
|
+
|
629
|
+
return layer;
|
630
|
+
}
|
631
|
+
|
632
|
+
pathscan(arr, pathomit) {
|
633
|
+
const paths = [];
|
634
|
+
let pacnt = 0;
|
635
|
+
let pcnt = 0;
|
636
|
+
let px = 0;
|
637
|
+
let py = 0;
|
638
|
+
const w = arr[0].length;
|
639
|
+
const h = arr.length;
|
640
|
+
let dir = 0;
|
641
|
+
let pathfinished = true;
|
642
|
+
let holepath = false;
|
643
|
+
let lookuprow;
|
644
|
+
for (let j = 0; j < h; j += 1) {
|
645
|
+
for (let i = 0; i < w; i += 1) {
|
646
|
+
if (arr[j][i] === 4 || arr[j][i] === 11) {
|
647
|
+
px = i;
|
648
|
+
py = j;
|
649
|
+
paths[pacnt] = {};
|
650
|
+
paths[pacnt].points = [];
|
651
|
+
paths[pacnt].boundingbox = [px, py, px, py];
|
652
|
+
paths[pacnt].holechildren = [];
|
653
|
+
pathfinished = false;
|
654
|
+
pcnt = 0;
|
655
|
+
holepath = arr[j][i] === 11;
|
656
|
+
dir = 1;
|
657
|
+
|
658
|
+
while (!pathfinished) {
|
659
|
+
paths[pacnt].points[pcnt] = {};
|
660
|
+
paths[pacnt].points[pcnt].x = px - 1;
|
661
|
+
paths[pacnt].points[pcnt].y = py - 1;
|
662
|
+
paths[pacnt].points[pcnt].t = arr[py][px];
|
663
|
+
|
664
|
+
if (px - 1 < paths[pacnt].boundingbox[0]) {
|
665
|
+
paths[pacnt].boundingbox[0] = px - 1;
|
666
|
+
}
|
667
|
+
if (px - 1 > paths[pacnt].boundingbox[2]) {
|
668
|
+
paths[pacnt].boundingbox[2] = px - 1;
|
669
|
+
}
|
670
|
+
if (py - 1 < paths[pacnt].boundingbox[1]) {
|
671
|
+
paths[pacnt].boundingbox[1] = py - 1;
|
672
|
+
}
|
673
|
+
if (py - 1 > paths[pacnt].boundingbox[3]) {
|
674
|
+
paths[pacnt].boundingbox[3] = py - 1;
|
675
|
+
}
|
676
|
+
|
677
|
+
lookuprow = this.pathscan_combined_lookup[arr[py][px]][dir];
|
678
|
+
arr[py][px] = lookuprow[0];
|
679
|
+
dir = lookuprow[1];
|
680
|
+
px += lookuprow[2];
|
681
|
+
py += lookuprow[3];
|
682
|
+
|
683
|
+
if (px - 1 === paths[pacnt].points[0].x && py - 1 === paths[pacnt].points[0].y) {
|
684
|
+
pathfinished = true;
|
685
|
+
|
686
|
+
if (paths[pacnt].points.length < pathomit) {
|
687
|
+
paths.pop();
|
688
|
+
} else {
|
689
|
+
paths[pacnt].isholepath = !!holepath;
|
690
|
+
|
691
|
+
if (holepath) {
|
692
|
+
let parentidx = 0,
|
693
|
+
parentbbox = [-1, -1, w + 1, h + 1];
|
694
|
+
for (let parentcnt = 0; parentcnt < pacnt; parentcnt++) {
|
695
|
+
if (
|
696
|
+
!paths[parentcnt].isholepath &&
|
697
|
+
this.boundingboxincludes(
|
698
|
+
paths[parentcnt].boundingbox,
|
699
|
+
paths[pacnt].boundingbox
|
700
|
+
) &&
|
701
|
+
this.boundingboxincludes(parentbbox, paths[parentcnt].boundingbox)
|
702
|
+
) {
|
703
|
+
parentidx = parentcnt;
|
704
|
+
parentbbox = paths[parentcnt].boundingbox;
|
705
|
+
}
|
706
|
+
}
|
707
|
+
paths[parentidx].holechildren.push(pacnt);
|
708
|
+
}
|
709
|
+
pacnt += 1;
|
710
|
+
}
|
711
|
+
}
|
712
|
+
pcnt += 1;
|
713
|
+
}
|
714
|
+
}
|
715
|
+
}
|
716
|
+
}
|
717
|
+
|
718
|
+
return paths;
|
719
|
+
}
|
720
|
+
|
721
|
+
boundingboxincludes(parentbbox, childbbox) {
|
722
|
+
return (
|
723
|
+
parentbbox[0] < childbbox[0] &&
|
724
|
+
parentbbox[1] < childbbox[1] &&
|
725
|
+
parentbbox[2] > childbbox[2] &&
|
726
|
+
parentbbox[3] > childbbox[3]
|
727
|
+
);
|
728
|
+
}
|
729
|
+
|
730
|
+
batchpathscan(layers, pathomit) {
|
731
|
+
const bpaths = [];
|
732
|
+
for (const k in layers) {
|
733
|
+
if (!layers.hasOwnProperty(k)) {
|
734
|
+
continue;
|
735
|
+
}
|
736
|
+
bpaths[k] = this.pathscan(layers[k], pathomit);
|
737
|
+
}
|
738
|
+
|
739
|
+
return bpaths;
|
740
|
+
}
|
741
|
+
|
742
|
+
internodes(paths, options) {
|
743
|
+
const ins = [];
|
744
|
+
let palen = 0;
|
745
|
+
let nextidx = 0;
|
746
|
+
let nextidx2 = 0;
|
747
|
+
let previdx = 0;
|
748
|
+
let previdx2 = 0;
|
749
|
+
let pacnt;
|
750
|
+
let pcnt;
|
751
|
+
for (pacnt = 0; pacnt < paths.length; pacnt += 1) {
|
752
|
+
ins[pacnt] = {};
|
753
|
+
ins[pacnt].points = [];
|
754
|
+
ins[pacnt].boundingbox = paths[pacnt].boundingbox;
|
755
|
+
ins[pacnt].holechildren = paths[pacnt].holechildren;
|
756
|
+
ins[pacnt].isholepath = paths[pacnt].isholepath;
|
757
|
+
palen = paths[pacnt].points.length;
|
758
|
+
|
759
|
+
for (pcnt = 0; pcnt < palen; pcnt += 1) {
|
760
|
+
nextidx = (pcnt + 1) % palen;
|
761
|
+
nextidx2 = (pcnt + 2) % palen;
|
762
|
+
previdx = (pcnt - 1 + palen) % palen;
|
763
|
+
previdx2 = (pcnt - 2 + palen) % palen;
|
764
|
+
|
765
|
+
if (
|
766
|
+
options.rightangleenhance &&
|
767
|
+
this.testrightangle(paths[pacnt], previdx2, previdx, pcnt, nextidx, nextidx2)
|
768
|
+
) {
|
769
|
+
if (ins[pacnt].points.length > 0) {
|
770
|
+
ins[pacnt].points[ins[pacnt].points.length - 1].linesegment = this.getdirection(
|
771
|
+
ins[pacnt].points[ins[pacnt].points.length - 1].x,
|
772
|
+
ins[pacnt].points[ins[pacnt].points.length - 1].y,
|
773
|
+
paths[pacnt].points[pcnt].x,
|
774
|
+
paths[pacnt].points[pcnt].y
|
775
|
+
);
|
776
|
+
}
|
777
|
+
|
778
|
+
ins[pacnt].points.push({
|
779
|
+
x: paths[pacnt].points[pcnt].x,
|
780
|
+
y: paths[pacnt].points[pcnt].y,
|
781
|
+
linesegment: this.getdirection(
|
782
|
+
paths[pacnt].points[pcnt].x,
|
783
|
+
paths[pacnt].points[pcnt].y,
|
784
|
+
(paths[pacnt].points[pcnt].x + paths[pacnt].points[nextidx].x) / 2,
|
785
|
+
(paths[pacnt].points[pcnt].y + paths[pacnt].points[nextidx].y) / 2
|
786
|
+
),
|
787
|
+
});
|
788
|
+
}
|
789
|
+
|
790
|
+
ins[pacnt].points.push({
|
791
|
+
x: (paths[pacnt].points[pcnt].x + paths[pacnt].points[nextidx].x) / 2,
|
792
|
+
y: (paths[pacnt].points[pcnt].y + paths[pacnt].points[nextidx].y) / 2,
|
793
|
+
linesegment: this.getdirection(
|
794
|
+
(paths[pacnt].points[pcnt].x + paths[pacnt].points[nextidx].x) / 2,
|
795
|
+
(paths[pacnt].points[pcnt].y + paths[pacnt].points[nextidx].y) / 2,
|
796
|
+
(paths[pacnt].points[nextidx].x + paths[pacnt].points[nextidx2].x) / 2,
|
797
|
+
(paths[pacnt].points[nextidx].y + paths[pacnt].points[nextidx2].y) / 2
|
798
|
+
),
|
799
|
+
});
|
800
|
+
}
|
801
|
+
}
|
802
|
+
|
803
|
+
return ins;
|
804
|
+
}
|
805
|
+
|
806
|
+
testrightangle(path, idx1, idx2, idx3, idx4, idx5) {
|
807
|
+
return (
|
808
|
+
(path.points[idx3].x === path.points[idx1].x &&
|
809
|
+
path.points[idx3].x === path.points[idx2].x &&
|
810
|
+
path.points[idx3].y === path.points[idx4].y &&
|
811
|
+
path.points[idx3].y === path.points[idx5].y) ||
|
812
|
+
(path.points[idx3].y === path.points[idx1].y &&
|
813
|
+
path.points[idx3].y === path.points[idx2].y &&
|
814
|
+
path.points[idx3].x === path.points[idx4].x &&
|
815
|
+
path.points[idx3].x === path.points[idx5].x)
|
816
|
+
);
|
817
|
+
}
|
818
|
+
|
819
|
+
getdirection(x1, y1, x2, y2) {
|
820
|
+
let val = 8;
|
821
|
+
if (x1 < x2) {
|
822
|
+
if (y1 < y2) {
|
823
|
+
val = 1;
|
824
|
+
} else if (y1 > y2) {
|
825
|
+
val = 7;
|
826
|
+
} else {
|
827
|
+
val = 0;
|
828
|
+
}
|
829
|
+
} else if (x1 > x2) {
|
830
|
+
if (y1 < y2) {
|
831
|
+
val = 3;
|
832
|
+
} else if (y1 > y2) {
|
833
|
+
val = 5;
|
834
|
+
} else {
|
835
|
+
val = 4;
|
836
|
+
}
|
837
|
+
} else if (y1 < y2) {
|
838
|
+
val = 2;
|
839
|
+
} else if (y1 > y2) {
|
840
|
+
val = 6;
|
841
|
+
} else {
|
842
|
+
val = 8;
|
843
|
+
}
|
844
|
+
|
845
|
+
return val;
|
846
|
+
}
|
847
|
+
|
848
|
+
batchinternodes(bpaths, options) {
|
849
|
+
const binternodes = [];
|
850
|
+
for (const k in bpaths) {
|
851
|
+
if (!bpaths.hasOwnProperty(k)) {
|
852
|
+
continue;
|
853
|
+
}
|
854
|
+
binternodes[k] = this.internodes(bpaths[k], options);
|
855
|
+
}
|
856
|
+
|
857
|
+
return binternodes;
|
858
|
+
}
|
859
|
+
|
860
|
+
tracepath(path, ltres, qtres) {
|
861
|
+
let pcnt = 0;
|
862
|
+
let segtype1;
|
863
|
+
let segtype2;
|
864
|
+
let seqend;
|
865
|
+
const smp = {};
|
866
|
+
smp.segments = [];
|
867
|
+
smp.boundingbox = path.boundingbox;
|
868
|
+
smp.holechildren = path.holechildren;
|
869
|
+
smp.isholepath = path.isholepath;
|
870
|
+
|
871
|
+
while (pcnt < path.points.length) {
|
872
|
+
segtype1 = path.points[pcnt].linesegment;
|
873
|
+
segtype2 = -1;
|
874
|
+
seqend = pcnt + 1;
|
875
|
+
while (
|
876
|
+
(path.points[seqend].linesegment === segtype1 ||
|
877
|
+
path.points[seqend].linesegment === segtype2 ||
|
878
|
+
segtype2 === -1) &&
|
879
|
+
seqend < path.points.length - 1
|
880
|
+
) {
|
881
|
+
if (path.points[seqend].linesegment !== segtype1 && segtype2 === -1) {
|
882
|
+
segtype2 = path.points[seqend].linesegment;
|
883
|
+
}
|
884
|
+
seqend += 1;
|
885
|
+
}
|
886
|
+
if (seqend === path.points.length - 1) {
|
887
|
+
seqend = 0;
|
888
|
+
}
|
889
|
+
|
890
|
+
smp.segments = smp.segments.concat(this.fitseq(path, ltres, qtres, pcnt, seqend));
|
891
|
+
|
892
|
+
if (seqend > 0) {
|
893
|
+
pcnt = seqend;
|
894
|
+
} else {
|
895
|
+
pcnt = path.points.length;
|
896
|
+
}
|
897
|
+
}
|
898
|
+
|
899
|
+
return smp;
|
900
|
+
}
|
901
|
+
|
902
|
+
fitseq(path, ltres, qtres, seqstart, seqend) {
|
903
|
+
if (seqend > path.points.length || seqend < 0) {
|
904
|
+
return [];
|
905
|
+
}
|
906
|
+
let errorpoint = seqstart,
|
907
|
+
errorval = 0,
|
908
|
+
curvepass = true,
|
909
|
+
px,
|
910
|
+
py,
|
911
|
+
dist2;
|
912
|
+
let tl = seqend - seqstart;
|
913
|
+
if (tl < 0) {
|
914
|
+
tl += path.points.length;
|
915
|
+
}
|
916
|
+
let vx = (path.points[seqend].x - path.points[seqstart].x) / tl,
|
917
|
+
vy = (path.points[seqend].y - path.points[seqstart].y) / tl;
|
918
|
+
let pcnt = (seqstart + 1) % path.points.length,
|
919
|
+
pl;
|
920
|
+
while (pcnt != seqend) {
|
921
|
+
pl = pcnt - seqstart;
|
922
|
+
if (pl < 0) {
|
923
|
+
pl += path.points.length;
|
924
|
+
}
|
925
|
+
px = path.points[seqstart].x + vx * pl;
|
926
|
+
py = path.points[seqstart].y + vy * pl;
|
927
|
+
dist2 =
|
928
|
+
(path.points[pcnt].x - px) * (path.points[pcnt].x - px) +
|
929
|
+
(path.points[pcnt].y - py) * (path.points[pcnt].y - py);
|
930
|
+
if (dist2 > ltres) {
|
931
|
+
curvepass = false;
|
932
|
+
}
|
933
|
+
if (dist2 > errorval) {
|
934
|
+
errorpoint = pcnt;
|
935
|
+
errorval = dist2;
|
936
|
+
}
|
937
|
+
pcnt = (pcnt + 1) % path.points.length;
|
938
|
+
}
|
939
|
+
if (curvepass) {
|
940
|
+
return [
|
941
|
+
{
|
942
|
+
type: 'L',
|
943
|
+
x1: path.points[seqstart].x,
|
944
|
+
y1: path.points[seqstart].y,
|
945
|
+
x2: path.points[seqend].x,
|
946
|
+
y2: path.points[seqend].y,
|
947
|
+
},
|
948
|
+
];
|
949
|
+
}
|
950
|
+
const fitpoint = errorpoint;
|
951
|
+
curvepass = true;
|
952
|
+
errorval = 0;
|
953
|
+
let t = (fitpoint - seqstart) / tl,
|
954
|
+
t1 = (1 - t) * (1 - t),
|
955
|
+
t2 = 2 * (1 - t) * t,
|
956
|
+
t3 = t * t;
|
957
|
+
let cpx =
|
958
|
+
(t1 * path.points[seqstart].x + t3 * path.points[seqend].x - path.points[fitpoint].x) / -t2,
|
959
|
+
cpy =
|
960
|
+
(t1 * path.points[seqstart].y + t3 * path.points[seqend].y - path.points[fitpoint].y) / -t2;
|
961
|
+
pcnt = seqstart + 1;
|
962
|
+
while (pcnt != seqend) {
|
963
|
+
t = (pcnt - seqstart) / tl;
|
964
|
+
t1 = (1 - t) * (1 - t);
|
965
|
+
t2 = 2 * (1 - t) * t;
|
966
|
+
t3 = t * t;
|
967
|
+
px = t1 * path.points[seqstart].x + t2 * cpx + t3 * path.points[seqend].x;
|
968
|
+
py = t1 * path.points[seqstart].y + t2 * cpy + t3 * path.points[seqend].y;
|
969
|
+
dist2 =
|
970
|
+
(path.points[pcnt].x - px) * (path.points[pcnt].x - px) +
|
971
|
+
(path.points[pcnt].y - py) * (path.points[pcnt].y - py);
|
972
|
+
if (dist2 > qtres) {
|
973
|
+
curvepass = false;
|
974
|
+
}
|
975
|
+
if (dist2 > errorval) {
|
976
|
+
errorpoint = pcnt;
|
977
|
+
errorval = dist2;
|
978
|
+
}
|
979
|
+
pcnt = (pcnt + 1) % path.points.length;
|
980
|
+
}
|
981
|
+
if (curvepass) {
|
982
|
+
return [
|
983
|
+
{
|
984
|
+
type: 'Q',
|
985
|
+
x1: path.points[seqstart].x,
|
986
|
+
y1: path.points[seqstart].y,
|
987
|
+
x2: cpx,
|
988
|
+
y2: cpy,
|
989
|
+
x3: path.points[seqend].x,
|
990
|
+
y3: path.points[seqend].y,
|
991
|
+
},
|
992
|
+
];
|
993
|
+
}
|
994
|
+
const splitpoint = fitpoint;
|
995
|
+
|
996
|
+
return this.fitseq(path, ltres, qtres, seqstart, splitpoint).concat(
|
997
|
+
this.fitseq(path, ltres, qtres, splitpoint, seqend)
|
998
|
+
);
|
999
|
+
}
|
1000
|
+
|
1001
|
+
batchtracepaths(internodepaths, ltres, qtres) {
|
1002
|
+
const btracedpaths = [];
|
1003
|
+
for (const k in internodepaths) {
|
1004
|
+
if (!internodepaths.hasOwnProperty(k)) {
|
1005
|
+
continue;
|
1006
|
+
}
|
1007
|
+
btracedpaths.push(this.tracepath(internodepaths[k], ltres, qtres));
|
1008
|
+
}
|
1009
|
+
|
1010
|
+
return btracedpaths;
|
1011
|
+
}
|
1012
|
+
|
1013
|
+
batchtracelayers(binternodes, ltres, qtres) {
|
1014
|
+
const btbis = [];
|
1015
|
+
for (const k in binternodes) {
|
1016
|
+
if (!binternodes.hasOwnProperty(k)) {
|
1017
|
+
continue;
|
1018
|
+
}
|
1019
|
+
btbis[k] = this.batchtracepaths(binternodes[k], ltres, qtres);
|
1020
|
+
}
|
1021
|
+
|
1022
|
+
return btbis;
|
1023
|
+
}
|
1024
|
+
|
1025
|
+
roundtodec(val, places) {
|
1026
|
+
return Number(val.toFixed(places));
|
1027
|
+
}
|
1028
|
+
|
1029
|
+
svgpathstring(tracedata, lnum, pathnum, options) {
|
1030
|
+
let layer = tracedata.layers[lnum],
|
1031
|
+
smp = layer[pathnum],
|
1032
|
+
str = '',
|
1033
|
+
pcnt;
|
1034
|
+
if (options.linefilter && smp.segments.length < 3) {
|
1035
|
+
return str;
|
1036
|
+
}
|
1037
|
+
str = `<path ${options.desc ? `desc="l ${lnum} p ${pathnum}" ` : ''}${this.tosvgcolorstr(
|
1038
|
+
tracedata.palette[lnum],
|
1039
|
+
options
|
1040
|
+
)}d="`;
|
1041
|
+
if (options.roundcoords === -1) {
|
1042
|
+
str += `M ${smp.segments[0].x1 * options.scale} ${smp.segments[0].y1 * options.scale} `;
|
1043
|
+
for (pcnt = 0; pcnt < smp.segments.length; pcnt++) {
|
1044
|
+
str += `${smp.segments[pcnt].type} ${smp.segments[pcnt].x2 * options.scale} ${
|
1045
|
+
smp.segments[pcnt].y2 * options.scale
|
1046
|
+
} `;
|
1047
|
+
if (smp.segments[pcnt].hasOwnProperty('x3')) {
|
1048
|
+
str += `${smp.segments[pcnt].x3 * options.scale} ${
|
1049
|
+
smp.segments[pcnt].y3 * options.scale
|
1050
|
+
} `;
|
1051
|
+
}
|
1052
|
+
}
|
1053
|
+
str += 'Z ';
|
1054
|
+
} else {
|
1055
|
+
str += `M ${this.roundtodec(
|
1056
|
+
smp.segments[0].x1 * options.scale,
|
1057
|
+
options.roundcoords
|
1058
|
+
)} ${this.roundtodec(smp.segments[0].y1 * options.scale, options.roundcoords)} `;
|
1059
|
+
for (pcnt = 0; pcnt < smp.segments.length; pcnt++) {
|
1060
|
+
str += `${smp.segments[pcnt].type} ${this.roundtodec(
|
1061
|
+
smp.segments[pcnt].x2 * options.scale,
|
1062
|
+
options.roundcoords
|
1063
|
+
)} ${this.roundtodec(smp.segments[pcnt].y2 * options.scale, options.roundcoords)} `;
|
1064
|
+
if (smp.segments[pcnt].hasOwnProperty('x3')) {
|
1065
|
+
str += `${this.roundtodec(
|
1066
|
+
smp.segments[pcnt].x3 * options.scale,
|
1067
|
+
options.roundcoords
|
1068
|
+
)} ${this.roundtodec(smp.segments[pcnt].y3 * options.scale, options.roundcoords)} `;
|
1069
|
+
}
|
1070
|
+
}
|
1071
|
+
str += 'Z ';
|
1072
|
+
}
|
1073
|
+
for (var hcnt = 0; hcnt < smp.holechildren.length; hcnt++) {
|
1074
|
+
var hsmp = layer[smp.holechildren[hcnt]];
|
1075
|
+
|
1076
|
+
if (options.roundcoords === -1) {
|
1077
|
+
if (hsmp.segments[hsmp.segments.length - 1].hasOwnProperty('x3')) {
|
1078
|
+
str += `M ${hsmp.segments[hsmp.segments.length - 1].x3 * options.scale} ${
|
1079
|
+
hsmp.segments[hsmp.segments.length - 1].y3 * options.scale
|
1080
|
+
} `;
|
1081
|
+
} else {
|
1082
|
+
str += `M ${hsmp.segments[hsmp.segments.length - 1].x2 * options.scale} ${
|
1083
|
+
hsmp.segments[hsmp.segments.length - 1].y2 * options.scale
|
1084
|
+
} `;
|
1085
|
+
}
|
1086
|
+
for (pcnt = hsmp.segments.length - 1; pcnt >= 0; pcnt--) {
|
1087
|
+
str += `${hsmp.segments[pcnt].type} `;
|
1088
|
+
if (hsmp.segments[pcnt].hasOwnProperty('x3')) {
|
1089
|
+
str += `${hsmp.segments[pcnt].x2 * options.scale} ${
|
1090
|
+
hsmp.segments[pcnt].y2 * options.scale
|
1091
|
+
} `;
|
1092
|
+
}
|
1093
|
+
str += `${hsmp.segments[pcnt].x1 * options.scale} ${
|
1094
|
+
hsmp.segments[pcnt].y1 * options.scale
|
1095
|
+
} `;
|
1096
|
+
}
|
1097
|
+
} else {
|
1098
|
+
if (hsmp.segments[hsmp.segments.length - 1].hasOwnProperty('x3')) {
|
1099
|
+
str += `M ${this.roundtodec(
|
1100
|
+
hsmp.segments[hsmp.segments.length - 1].x3 * options.scale
|
1101
|
+
)} ${this.roundtodec(hsmp.segments[hsmp.segments.length - 1].y3 * options.scale)} `;
|
1102
|
+
} else {
|
1103
|
+
str += `M ${this.roundtodec(
|
1104
|
+
hsmp.segments[hsmp.segments.length - 1].x2 * options.scale
|
1105
|
+
)} ${this.roundtodec(hsmp.segments[hsmp.segments.length - 1].y2 * options.scale)} `;
|
1106
|
+
}
|
1107
|
+
for (pcnt = hsmp.segments.length - 1; pcnt >= 0; pcnt--) {
|
1108
|
+
str += `${hsmp.segments[pcnt].type} `;
|
1109
|
+
if (hsmp.segments[pcnt].hasOwnProperty('x3')) {
|
1110
|
+
str += `${this.roundtodec(hsmp.segments[pcnt].x2 * options.scale)} ${this.roundtodec(
|
1111
|
+
hsmp.segments[pcnt].y2 * options.scale
|
1112
|
+
)} `;
|
1113
|
+
}
|
1114
|
+
str += `${this.roundtodec(hsmp.segments[pcnt].x1 * options.scale)} ${this.roundtodec(
|
1115
|
+
hsmp.segments[pcnt].y1 * options.scale
|
1116
|
+
)} `;
|
1117
|
+
}
|
1118
|
+
}
|
1119
|
+
str += 'Z ';
|
1120
|
+
}
|
1121
|
+
str += '" />';
|
1122
|
+
if (options.lcpr || options.qcpr) {
|
1123
|
+
for (pcnt = 0; pcnt < smp.segments.length; pcnt++) {
|
1124
|
+
if (smp.segments[pcnt].hasOwnProperty('x3') && options.qcpr) {
|
1125
|
+
str += `<circle cx="${smp.segments[pcnt].x2 * options.scale}" cy="${
|
1126
|
+
smp.segments[pcnt].y2 * options.scale
|
1127
|
+
}" r="${options.qcpr}" fill="cyan" stroke-width="${
|
1128
|
+
options.qcpr * 0.2
|
1129
|
+
}" stroke="black" />`;
|
1130
|
+
str += `<circle cx="${smp.segments[pcnt].x3 * options.scale}" cy="${
|
1131
|
+
smp.segments[pcnt].y3 * options.scale
|
1132
|
+
}" r="${options.qcpr}" fill="white" stroke-width="${
|
1133
|
+
options.qcpr * 0.2
|
1134
|
+
}" stroke="black" />`;
|
1135
|
+
str += `<line x1="${smp.segments[pcnt].x1 * options.scale}" y1="${
|
1136
|
+
smp.segments[pcnt].y1 * options.scale
|
1137
|
+
}" x2="${smp.segments[pcnt].x2 * options.scale}" y2="${
|
1138
|
+
smp.segments[pcnt].y2 * options.scale
|
1139
|
+
}" stroke-width="${options.qcpr * 0.2}" stroke="cyan" />`;
|
1140
|
+
str += `<line x1="${smp.segments[pcnt].x2 * options.scale}" y1="${
|
1141
|
+
smp.segments[pcnt].y2 * options.scale
|
1142
|
+
}" x2="${smp.segments[pcnt].x3 * options.scale}" y2="${
|
1143
|
+
smp.segments[pcnt].y3 * options.scale
|
1144
|
+
}" stroke-width="${options.qcpr * 0.2}" stroke="cyan" />`;
|
1145
|
+
}
|
1146
|
+
if (!smp.segments[pcnt].hasOwnProperty('x3') && options.lcpr) {
|
1147
|
+
str += `<circle cx="${smp.segments[pcnt].x2 * options.scale}" cy="${
|
1148
|
+
smp.segments[pcnt].y2 * options.scale
|
1149
|
+
}" r="${options.lcpr}" fill="white" stroke-width="${
|
1150
|
+
options.lcpr * 0.2
|
1151
|
+
}" stroke="black" />`;
|
1152
|
+
}
|
1153
|
+
}
|
1154
|
+
|
1155
|
+
for (var hcnt = 0; hcnt < smp.holechildren.length; hcnt++) {
|
1156
|
+
var hsmp = layer[smp.holechildren[hcnt]];
|
1157
|
+
for (pcnt = 0; pcnt < hsmp.segments.length; pcnt++) {
|
1158
|
+
if (hsmp.segments[pcnt].hasOwnProperty('x3') && options.qcpr) {
|
1159
|
+
str += `<circle cx="${hsmp.segments[pcnt].x2 * options.scale}" cy="${
|
1160
|
+
hsmp.segments[pcnt].y2 * options.scale
|
1161
|
+
}" r="${options.qcpr}" fill="cyan" stroke-width="${
|
1162
|
+
options.qcpr * 0.2
|
1163
|
+
}" stroke="black" />`;
|
1164
|
+
str += `<circle cx="${hsmp.segments[pcnt].x3 * options.scale}" cy="${
|
1165
|
+
hsmp.segments[pcnt].y3 * options.scale
|
1166
|
+
}" r="${options.qcpr}" fill="white" stroke-width="${
|
1167
|
+
options.qcpr * 0.2
|
1168
|
+
}" stroke="black" />`;
|
1169
|
+
str += `<line x1="${hsmp.segments[pcnt].x1 * options.scale}" y1="${
|
1170
|
+
hsmp.segments[pcnt].y1 * options.scale
|
1171
|
+
}" x2="${hsmp.segments[pcnt].x2 * options.scale}" y2="${
|
1172
|
+
hsmp.segments[pcnt].y2 * options.scale
|
1173
|
+
}" stroke-width="${options.qcpr * 0.2}" stroke="cyan" />`;
|
1174
|
+
str += `<line x1="${hsmp.segments[pcnt].x2 * options.scale}" y1="${
|
1175
|
+
hsmp.segments[pcnt].y2 * options.scale
|
1176
|
+
}" x2="${hsmp.segments[pcnt].x3 * options.scale}" y2="${
|
1177
|
+
hsmp.segments[pcnt].y3 * options.scale
|
1178
|
+
}" stroke-width="${options.qcpr * 0.2}" stroke="cyan" />`;
|
1179
|
+
}
|
1180
|
+
if (!hsmp.segments[pcnt].hasOwnProperty('x3') && options.lcpr) {
|
1181
|
+
str += `<circle cx="${hsmp.segments[pcnt].x2 * options.scale}" cy="${
|
1182
|
+
hsmp.segments[pcnt].y2 * options.scale
|
1183
|
+
}" r="${options.lcpr}" fill="white" stroke-width="${
|
1184
|
+
options.lcpr * 0.2
|
1185
|
+
}" stroke="black" />`;
|
1186
|
+
}
|
1187
|
+
}
|
1188
|
+
}
|
1189
|
+
}
|
1190
|
+
|
1191
|
+
return str;
|
1192
|
+
}
|
1193
|
+
|
1194
|
+
getsvgstring(tracedata, options) {
|
1195
|
+
options = this.checkoptions(options);
|
1196
|
+
const w = tracedata.width * options.scale;
|
1197
|
+
const h = tracedata.height * options.scale;
|
1198
|
+
|
1199
|
+
let svgstr = `<svg ${
|
1200
|
+
options.viewbox ? `viewBox="0 0 ${w} ${h}" ` : `width="${w}" height="${h}" `
|
1201
|
+
}version="1.1" xmlns="http://www.w3.org/2000/svg" desc="Created with imagetracer.js version ${
|
1202
|
+
this.versionnumber
|
1203
|
+
}" >`;
|
1204
|
+
for (let lcnt = 0; lcnt < tracedata.layers.length; lcnt += 1) {
|
1205
|
+
for (let pcnt = 0; pcnt < tracedata.layers[lcnt].length; pcnt += 1) {
|
1206
|
+
if (!tracedata.layers[lcnt][pcnt].isholepath) {
|
1207
|
+
svgstr += this.svgpathstring(tracedata, lcnt, pcnt, options);
|
1208
|
+
}
|
1209
|
+
}
|
1210
|
+
}
|
1211
|
+
svgstr += '</svg>';
|
1212
|
+
|
1213
|
+
return svgstr;
|
1214
|
+
}
|
1215
|
+
|
1216
|
+
compareNumbers(a, b) {
|
1217
|
+
return a - b;
|
1218
|
+
}
|
1219
|
+
|
1220
|
+
torgbastr(c) {
|
1221
|
+
return `rgba(${c.r},${c.g},${c.b},${c.a})`;
|
1222
|
+
}
|
1223
|
+
|
1224
|
+
tosvgcolorstr(c, options) {
|
1225
|
+
return `fill="rgb(${c.r},${c.g},${c.b})" stroke="rgb(${c.r},${c.g},${c.b})" stroke-width="${
|
1226
|
+
options.strokewidth
|
1227
|
+
}" opacity="${c.a / 255.0}" `;
|
1228
|
+
}
|
1229
|
+
|
1230
|
+
appendSVGString(svgstr, parentid) {
|
1231
|
+
let div;
|
1232
|
+
if (parentid) {
|
1233
|
+
div = document.getElementById(parentid);
|
1234
|
+
if (!div) {
|
1235
|
+
div = document.createElement('div');
|
1236
|
+
div.id = parentid;
|
1237
|
+
document.body.appendChild(div);
|
1238
|
+
}
|
1239
|
+
} else {
|
1240
|
+
div = document.createElement('div');
|
1241
|
+
document.body.appendChild(div);
|
1242
|
+
}
|
1243
|
+
div.innerHTML += svgstr;
|
1244
|
+
}
|
1245
|
+
|
1246
|
+
blur(imgd, radius, delta) {
|
1247
|
+
let i, j, k, d, idx, racc, gacc, bacc, aacc, wacc;
|
1248
|
+
const imgd2 = { width: imgd.width, height: imgd.height, data: [] };
|
1249
|
+
radius = Math.floor(radius);
|
1250
|
+
if (radius < 1) {
|
1251
|
+
return imgd;
|
1252
|
+
}
|
1253
|
+
if (radius > 5) {
|
1254
|
+
radius = 5;
|
1255
|
+
}
|
1256
|
+
delta = Math.abs(delta);
|
1257
|
+
if (delta > 1024) {
|
1258
|
+
delta = 1024;
|
1259
|
+
}
|
1260
|
+
const thisgk = this.gks[radius - 1];
|
1261
|
+
for (j = 0; j < imgd.height; j++) {
|
1262
|
+
for (i = 0; i < imgd.width; i++) {
|
1263
|
+
racc = 0;
|
1264
|
+
gacc = 0;
|
1265
|
+
bacc = 0;
|
1266
|
+
aacc = 0;
|
1267
|
+
wacc = 0;
|
1268
|
+
|
1269
|
+
for (k = -radius; k < radius + 1; k++) {
|
1270
|
+
if (i + k > 0 && i + k < imgd.width) {
|
1271
|
+
idx = (j * imgd.width + i + k) * 4;
|
1272
|
+
racc += imgd.data[idx] * thisgk[k + radius];
|
1273
|
+
gacc += imgd.data[idx + 1] * thisgk[k + radius];
|
1274
|
+
bacc += imgd.data[idx + 2] * thisgk[k + radius];
|
1275
|
+
aacc += imgd.data[idx + 3] * thisgk[k + radius];
|
1276
|
+
wacc += thisgk[k + radius];
|
1277
|
+
}
|
1278
|
+
}
|
1279
|
+
|
1280
|
+
idx = (j * imgd.width + i) * 4;
|
1281
|
+
imgd2.data[idx] = Math.floor(racc / wacc);
|
1282
|
+
imgd2.data[idx + 1] = Math.floor(gacc / wacc);
|
1283
|
+
imgd2.data[idx + 2] = Math.floor(bacc / wacc);
|
1284
|
+
imgd2.data[idx + 3] = Math.floor(aacc / wacc);
|
1285
|
+
}
|
1286
|
+
}
|
1287
|
+
const himgd = new Uint8ClampedArray(imgd2.data);
|
1288
|
+
for (j = 0; j < imgd.height; j++) {
|
1289
|
+
for (i = 0; i < imgd.width; i++) {
|
1290
|
+
racc = 0;
|
1291
|
+
gacc = 0;
|
1292
|
+
bacc = 0;
|
1293
|
+
aacc = 0;
|
1294
|
+
wacc = 0;
|
1295
|
+
|
1296
|
+
for (k = -radius; k < radius + 1; k++) {
|
1297
|
+
if (j + k > 0 && j + k < imgd.height) {
|
1298
|
+
idx = ((j + k) * imgd.width + i) * 4;
|
1299
|
+
racc += himgd[idx] * thisgk[k + radius];
|
1300
|
+
gacc += himgd[idx + 1] * thisgk[k + radius];
|
1301
|
+
bacc += himgd[idx + 2] * thisgk[k + radius];
|
1302
|
+
aacc += himgd[idx + 3] * thisgk[k + radius];
|
1303
|
+
wacc += thisgk[k + radius];
|
1304
|
+
}
|
1305
|
+
}
|
1306
|
+
|
1307
|
+
idx = (j * imgd.width + i) * 4;
|
1308
|
+
imgd2.data[idx] = Math.floor(racc / wacc);
|
1309
|
+
imgd2.data[idx + 1] = Math.floor(gacc / wacc);
|
1310
|
+
imgd2.data[idx + 2] = Math.floor(bacc / wacc);
|
1311
|
+
imgd2.data[idx + 3] = Math.floor(aacc / wacc);
|
1312
|
+
}
|
1313
|
+
}
|
1314
|
+
for (j = 0; j < imgd.height; j++) {
|
1315
|
+
for (i = 0; i < imgd.width; i++) {
|
1316
|
+
idx = (j * imgd.width + i) * 4;
|
1317
|
+
|
1318
|
+
d =
|
1319
|
+
Math.abs(imgd2.data[idx] - imgd.data[idx]) +
|
1320
|
+
Math.abs(imgd2.data[idx + 1] - imgd.data[idx + 1]) +
|
1321
|
+
Math.abs(imgd2.data[idx + 2] - imgd.data[idx + 2]) +
|
1322
|
+
Math.abs(imgd2.data[idx + 3] - imgd.data[idx + 3]);
|
1323
|
+
|
1324
|
+
if (d > delta) {
|
1325
|
+
imgd2.data[idx] = imgd.data[idx];
|
1326
|
+
imgd2.data[idx + 1] = imgd.data[idx + 1];
|
1327
|
+
imgd2.data[idx + 2] = imgd.data[idx + 2];
|
1328
|
+
imgd2.data[idx + 3] = imgd.data[idx + 3];
|
1329
|
+
}
|
1330
|
+
}
|
1331
|
+
}
|
1332
|
+
|
1333
|
+
return imgd2;
|
1334
|
+
}
|
1335
|
+
|
1336
|
+
loadImage(url, callback, options) {
|
1337
|
+
const img = new Image();
|
1338
|
+
if (options && options.corsenabled) {
|
1339
|
+
img.crossOrigin = 'Anonymous';
|
1340
|
+
}
|
1341
|
+
img.src = url;
|
1342
|
+
img.onload = function () {
|
1343
|
+
const canvas = document.createElement('canvas');
|
1344
|
+
canvas.width = img.width;
|
1345
|
+
canvas.height = img.height;
|
1346
|
+
const context = canvas.getContext('2d');
|
1347
|
+
context.drawImage(img, 0, 0);
|
1348
|
+
callback(canvas);
|
1349
|
+
};
|
1350
|
+
}
|
1351
|
+
|
1352
|
+
getImgdata(canvas) {
|
1353
|
+
const context = canvas.getContext('2d');
|
1354
|
+
|
1355
|
+
return context.getImageData(0, 0, canvas.width, canvas.height);
|
1356
|
+
}
|
1357
|
+
|
1358
|
+
drawLayers(layers, palette, scale, parentid) {
|
1359
|
+
scale = scale || 1;
|
1360
|
+
let w, h, i, j, k;
|
1361
|
+
let div;
|
1362
|
+
if (parentid) {
|
1363
|
+
div = document.getElementById(parentid);
|
1364
|
+
if (!div) {
|
1365
|
+
div = document.createElement('div');
|
1366
|
+
div.id = parentid;
|
1367
|
+
document.body.appendChild(div);
|
1368
|
+
}
|
1369
|
+
} else {
|
1370
|
+
div = document.createElement('div');
|
1371
|
+
document.body.appendChild(div);
|
1372
|
+
}
|
1373
|
+
for (k in layers) {
|
1374
|
+
if (!layers.hasOwnProperty(k)) {
|
1375
|
+
continue;
|
1376
|
+
}
|
1377
|
+
|
1378
|
+
w = layers[k][0].length;
|
1379
|
+
h = layers[k].length;
|
1380
|
+
|
1381
|
+
const canvas = document.createElement('canvas');
|
1382
|
+
canvas.width = w * scale;
|
1383
|
+
canvas.height = h * scale;
|
1384
|
+
const context = canvas.getContext('2d');
|
1385
|
+
|
1386
|
+
for (j = 0; j < h; j += 1) {
|
1387
|
+
for (i = 0; i < w; i += 1) {
|
1388
|
+
context.fillStyle = this.torgbastr(palette[layers[k][j][i] % palette.length]);
|
1389
|
+
context.fillRect(i * scale, j * scale, scale, scale);
|
1390
|
+
}
|
1391
|
+
}
|
1392
|
+
|
1393
|
+
div.appendChild(canvas);
|
1394
|
+
}
|
1395
|
+
}
|
1396
|
+
}
|