UNPKG

imagegenerator

Version:
230 lines (193 loc) 7.51 kB
import { writeFileSync, existsSync, mkdirSync, readFileSync } from 'fs' import { dirname, parse } from 'path' import { Buffer } from 'buffer' let svg2png = require('svg2png'); let mkdirp = require('mkdirp'); import ImageProperties from "./ImageProperties" import WatermarkProperties from "./WatermarkProperties" import {toCss} from "./ObjectToCSS" /** * ImageGenerator * @constructor(quote, ImageProperties?) * @methods addQuote, addWatermark, generateImageSync, imageStyle, hasWaterMark * @static watermarkPosition.BOTTOMRIGHT,watermarkPosition.BOTTOMLEFT,watermarkPosition.TOPRIGHT,watermarkPosition.TOPLEFT */ class ImageGenerator { public static watermarkPosition = { BOTTOMRIGHT: "bottomright", BOTTOMLEFT: "bottomleft", TOPRIGHT: "topright", TOPLEFT: "topleft" } private quote: string; private defaultWaterMarkProperties: WatermarkProperties = { imageurl: "", position: ImageGenerator.watermarkPosition.BOTTOMRIGHT }; private waterMarkProperties: WatermarkProperties = {}; private watermarkURL: string; private ImageProperties: ImageProperties = {}; private defaultImageProperties: ImageProperties = { backgroundColor: "#fff", backgroundImage: "", color: "#000", fontFamily: "sans-serif", fontSize: 25, height: 500, width: 500, backgroundSize: "cover", padding: 10, textAlign: 'center', wordWrap: 'break-word', display: 'table-cell', verticalAlign: 'middle', boxSizing: 'border-box', fontStyle: 'none', textDecoration: 'none', fontWeight: 400 } constructor(quote?: string, options?: ImageProperties) { if (quote) { this.quote = quote; } if (options === undefined) { options = this.defaultImageProperties; } Object.keys(this.defaultImageProperties).forEach((key) => { if (options[key]) { this.ImageProperties[key] = options[key]; } else { this.ImageProperties[key] = this.defaultImageProperties[key]; } }); if (options.backgroundImage) { this.ImageProperties.backgroundImage = `url(${this.generateImageSrc(options.backgroundImage)})`; } else { this.ImageProperties.backgroundImage = this.defaultImageProperties.backgroundImage; } if (options.fontFamily) { this.ImageProperties.fontFamily = `'${this.generateImageSrc(options.fontFamily)}'`; } else { this.ImageProperties.fontFamily = this.defaultImageProperties.fontFamily; } } public addWatermark(watermarkProperties: WatermarkProperties) { if (watermarkProperties.imageurl === "") { throw new Error("No Image Provided for Watermark"); } this.waterMarkProperties = watermarkProperties; if (watermarkProperties.imageurl) { this.waterMarkProperties.imageurl = watermarkProperties.imageurl; } else { this.waterMarkProperties.imageurl = this.defaultWaterMarkProperties.imageurl; } } public addQuote(quote: string) { if (this.quote) { this.quote = ""; } this.quote = quote; } public imageStyle(imageProps: ImageProperties) { if (!imageProps) { throw new Error("undefined ImageProperties"); } Object.keys(this.defaultImageProperties).forEach((key) => { if(imageProps[key]) this.ImageProperties[key] = imageProps[key] }); if (imageProps.backgroundImage) { this.ImageProperties.backgroundImage = `url(${this.generateImageSrc(imageProps.backgroundImage)})`; } else { this.ImageProperties.backgroundImage = this.defaultImageProperties.backgroundImage; } if (imageProps.fontFamily) { this.ImageProperties.fontFamily = `'${imageProps.fontFamily}'`; } else { this.ImageProperties.fontFamily = this.defaultImageProperties.fontFamily; } } public generateImageSync(outputFileName: string) { let tempWaterProps = {} switch (this.waterMarkProperties.position) { case ImageGenerator.watermarkPosition.BOTTOMLEFT: tempWaterProps = { left: "15px", bottom: "15px" } break; case ImageGenerator.watermarkPosition.BOTTOMRIGHT: tempWaterProps = { right: "15px", bottom: "15px" } break; case ImageGenerator.watermarkPosition.TOPLEFT: tempWaterProps = { top: "15px", left: "15px" } break; case ImageGenerator.watermarkPosition.TOPRIGHT: tempWaterProps = { top: "15px", right: "15px" } break; } let waterMarkDisplay = "block" if (!this.hasWaterMark) { waterMarkDisplay = "none" } if (this.quote === undefined || this.quote === null) { this.quote = "" } let svgTemplate = ` <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" xml:space="preserve"> <style type="text/css"> p{ text-rendering: optimizeLegibility !important; -webkit-font-smoothing: antialiased !important; -moz-osx-font-smoothing: grayscale; ${toCss(this.ImageProperties)} } #waterMark{ height: 100px; opacity: 0.7; background-size: contain; z-index: 5; position: absolute; border: none; display:${waterMarkDisplay}; ${toCss(tempWaterProps)} } </style> <foreignObject height="${this.ImageProperties.height}" width="${this.ImageProperties.width}"> <p xmlns="http://www.w3.org/1999/xhtml">${this.quote}</p> <img xmlns="http://www.w3.org/1999/xhtml" src="${this.generateImageSrc(this.waterMarkProperties.imageurl)}" id="waterMark"/> </foreignObject> </svg> `; // console.log(svgTemplate) mkdirp.sync(dirname(outputFileName)); writeFileSync(outputFileName, svg2png.sync(svgTemplate, { width: this.ImageProperties.width, height: this.ImageProperties.height })); } public hasWaterMark(): boolean { if(this.waterMarkProperties.imageurl === "" || this.waterMarkProperties.imageurl === undefined) return false else return true; } private generateImageSrc(path:string): string{ let src=''; if(path){ if(existsSync(path)) src= "data:image;base64," + readFileSync(path).toString('base64'); else src = path; } return src; } } export default ImageGenerator;