├── README.md ├── package.json ├── index.js └── .gitignore /README.md: -------------------------------------------------------------------------------- 1 | # quote-image-api 📜 2 | 3 | An API that serves beautiful images with inspirational quotes 📜 4 | 5 | ![screenshot](https://media.discordapp.net/attachments/609854271810306049/656579682392604702/generate.jpg?width=841&height=474) 6 | 7 | # Parameters 8 | 9 | **-height** 10 | **-width** 11 | **-invert** 12 | 13 | example : https://quoteimg.glitch.me/generate?height=1080&width=1080&invert=true 14 | ## Live demo 15 | 16 | [https://quoteimg.glitch.me/generate](https://quoteimg.glitch.me/generate) 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "quote-image-api", 3 | "version": "1.0.0", 4 | "description": "An API that serves beautiful images with inspirational quotes", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "node index.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/TasosY2K/quote-image-api.git" 12 | }, 13 | "keywords": [ 14 | "image", 15 | "random", 16 | "quote", 17 | "api" 18 | ], 19 | "author": "TasosY2K", 20 | "license": "ISC", 21 | "bugs": { 22 | "url": "https://github.com/TasosY2K/quote-image-api/issues" 23 | }, 24 | "homepage": "https://github.com/TasosY2K/quote-image-api#readme", 25 | "dependencies": { 26 | "canvas": "^2.6.1", 27 | "canvas-text-wrapper": "^0.10.2", 28 | "express": "^4.17.1", 29 | "request-promise": "^4.2.5" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const {createCanvas, loadImage, registerFont} = require('canvas'); 3 | const CanvasTextWrapper = require('canvas-text-wrapper').CanvasTextWrapper; 4 | const request = require('request-promise'); 5 | const express = require('express'); 6 | 7 | const app = express(); 8 | 9 | app.get('/', (req, res) => { 10 | res.send('Check code and docs at: https://github.com/TasosY2K/quote-image-api'); 11 | }); 12 | 13 | app.get('/generate', async function (req, res) { 14 | console.log(req.query); 15 | 16 | let quote = await request('https://api.quotable.io/random', {json: true}); 17 | 18 | let resolutions = [[1080, 1080], [1080, 608], [1920, 1080]]; 19 | let pair = req.query.width && req.query.height ? [Number.parseInt(req.query.width), Number.parseInt(req.query.height)] : resolutions[Math.floor(Math.random() * resolutions.length)]; 20 | 21 | let fonts = ['Arial','Times New Roman','Courier New','Courier','Verdana','Georgia','Trebuchet MS','Arial Black','Impact']; 22 | 23 | const canvas = createCanvas(pair[0], pair[1], 'jpg'); 24 | const ctx = canvas.getContext('2d'); 25 | 26 | loadImage(`https://picsum.photos/${pair[0]}/${pair[1]}`).then((image) => { 27 | let font = fonts[Math.floor(Math.random() * fonts.length) + 1]; 28 | ctx.drawImage(image, 0 , 0, pair[0], pair[1]); 29 | ctx.strokeStyle = '#000000'; 30 | ctx.fillStyle = '#ffffff'; 31 | 32 | ctx.globalCompositeOperation = req.query.invert && Boolean.valueOf(req.query.invert) ? 'difference' : 'normal'; 33 | 34 | CanvasTextWrapper(canvas, quote.content, {font: `60px ${font}`, textAlign: 'center', verticalAlign: 'middle', strokeText: true, paddingX: 100}); 35 | 36 | let stream = canvas.createJPEGStream({quality: 0.95, chromaSubsampling: false}); 37 | 38 | stream.pipe(res); 39 | }); 40 | }); 41 | 42 | app.listen(3000, () => { 43 | console.log('Listening on port 3000\nCheck code and docs at: https://github.com/TasosY2K/quote-image-api'); 44 | }); 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/node 3 | # Edit at https://www.gitignore.io/?templates=node 4 | 5 | ### Node ### 6 | # Logs 7 | logs 8 | *.log 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # Diagnostic reports (https://nodejs.org/api/report.html) 15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 16 | 17 | # Runtime data 18 | pids 19 | *.pid 20 | *.seed 21 | *.pid.lock 22 | 23 | # Directory for instrumented libs generated by jscoverage/JSCover 24 | lib-cov 25 | 26 | # Coverage directory used by tools like istanbul 27 | coverage 28 | *.lcov 29 | 30 | # nyc test coverage 31 | .nyc_output 32 | 33 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 34 | .grunt 35 | 36 | # Bower dependency directory (https://bower.io/) 37 | bower_components 38 | 39 | # node-waf configuration 40 | .lock-wscript 41 | 42 | # Compiled binary addons (https://nodejs.org/api/addons.html) 43 | build/Release 44 | 45 | # Dependency directories 46 | node_modules/ 47 | jspm_packages/ 48 | 49 | # TypeScript v1 declaration files 50 | typings/ 51 | 52 | # TypeScript cache 53 | *.tsbuildinfo 54 | 55 | # Optional npm cache directory 56 | .npm 57 | 58 | # Optional eslint cache 59 | .eslintcache 60 | 61 | # Optional REPL history 62 | .node_repl_history 63 | 64 | # Output of 'npm pack' 65 | *.tgz 66 | 67 | # Yarn Integrity file 68 | .yarn-integrity 69 | 70 | # dotenv environment variables file 71 | .env 72 | .env.test 73 | 74 | # parcel-bundler cache (https://parceljs.org/) 75 | .cache 76 | 77 | # next.js build output 78 | .next 79 | 80 | # nuxt.js build output 81 | .nuxt 82 | 83 | # react / gatsby 84 | public/ 85 | 86 | # vuepress build output 87 | .vuepress/dist 88 | 89 | # Serverless directories 90 | .serverless/ 91 | 92 | # FuseBox cache 93 | .fusebox/ 94 | 95 | # DynamoDB Local files 96 | .dynamodb/ 97 | 98 | # End of https://www.gitignore.io/api/node 99 | # Created by https://www.gitignore.io/api/node 100 | # Edit at https://www.gitignore.io/?templates=node 101 | 102 | ### Node ### 103 | # Logs 104 | logs 105 | *.log 106 | npm-debug.log* 107 | yarn-debug.log* 108 | yarn-error.log* 109 | lerna-debug.log* 110 | 111 | # Diagnostic reports (https://nodejs.org/api/report.html) 112 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 113 | 114 | # Runtime data 115 | pids 116 | *.pid 117 | *.seed 118 | *.pid.lock 119 | 120 | # Directory for instrumented libs generated by jscoverage/JSCover 121 | lib-cov 122 | 123 | # Coverage directory used by tools like istanbul 124 | coverage 125 | *.lcov 126 | 127 | # nyc test coverage 128 | .nyc_output 129 | 130 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 131 | .grunt 132 | 133 | # Bower dependency directory (https://bower.io/) 134 | bower_components 135 | 136 | # node-waf configuration 137 | .lock-wscript 138 | 139 | # Compiled binary addons (https://nodejs.org/api/addons.html) 140 | build/Release 141 | 142 | # Dependency directories 143 | node_modules/ 144 | jspm_packages/ 145 | 146 | # TypeScript v1 declaration files 147 | typings/ 148 | 149 | # TypeScript cache 150 | *.tsbuildinfo 151 | 152 | # Optional npm cache directory 153 | .npm 154 | 155 | # Optional eslint cache 156 | .eslintcache 157 | 158 | # Optional REPL history 159 | .node_repl_history 160 | 161 | # Output of 'npm pack' 162 | *.tgz 163 | 164 | # Yarn Integrity file 165 | .yarn-integrity 166 | 167 | # dotenv environment variables file 168 | .env 169 | .env.test 170 | 171 | # parcel-bundler cache (https://parceljs.org/) 172 | .cache 173 | 174 | # next.js build output 175 | .next 176 | 177 | # nuxt.js build output 178 | .nuxt 179 | 180 | # react / gatsby 181 | public/ 182 | 183 | # vuepress build output 184 | .vuepress/dist 185 | 186 | # Serverless directories 187 | .serverless/ 188 | 189 | # FuseBox cache 190 | .fusebox/ 191 | 192 | # DynamoDB Local files 193 | .dynamodb/ 194 | 195 | # End of https://www.gitignore.io/api/node 196 | --------------------------------------------------------------------------------