Default bounding box for SVG without viewBox can result in clipped content
Open
Nobody has claimed this yet.
blocked-upstream-dependency
- Dominant language
- JavaScript
- Stars
- 32.7k
- Forks
- 1.4k
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 5
Description
my environment:
nodejs v14.15.0
sharp 0.26.3
svg
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" height="100" width="900">
<use xlink:href="#0" x="0" y="0"/>
<symbol id="0" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="100px" height="100px" viewBox="0 0 278 500">
<path d="M204 88L28 88 28 45 260 45 260 80Q243 98 226 122 209 146 192 176.5 175 207 162.5 237.5 150 268 140 300L140 300Q128 345 124 399L124 399 78 399Q79 378 83 352.5 87 327 95 297L95 297Q111 237 140 181L140 181Q155 153 171 130 187 107 204 88L204 88Z"/>
</symbol>
<use xlink:href="#1" x="100" y="0"/>
<symbol id="1" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="100px" height="100px" viewBox="0 0 278 500">
<path d="M254 128L210 132Q204 106 193 94L193 94Q175 76 149 76L149 76Q128 76 112 87L112 87Q91 103 80 131L80 131Q74 146 70.5 166.5 67 187 67 214L67 214Q83 190 106 178.5 129 167 154 167L154 167Q198 167 229 199.5 260 232 260 283L260 283Q260 316 245.5 345 231 374 206 389.5 181 405 148 405L148 405Q93 405 58.5 365 24 325 24 231L24 231Q24 127 62 80L62 80Q95 39 152 39L152 39Q194 39 221 62.5 248 86 254 128L254 128ZM74 283L74 283Q74 305 84 326 94 347 111 358 128 369 147 369L147 369Q174 369 194.5 346.5 215 324 215 286.5 215 249 195 227 175 205 145.5 205 116 205 95 226.5 74 248 74 283Z"/>
</symbol>
<use xlink:href="#2" x="200" y="0"/>
<symbol id="2" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="100px" height="100px" viewBox="0 0 278 500">
<path d="M26 305L72 301Q77 336 95 352.5 113 369 140 369L140 369Q172 369 194 344.5 216 320 216 281.5 216 243 194.5 221.5 173 200 140 200L140 200Q118 200 101.5 209.5 85 219 75 235L75 235 33 230 68 46 246
46 246 88 103 88 84 184Q100 173 117 167 134 161 151 161L151 161Q198 161 230.5 193.5 263 226 263 277L263 277Q263 325 234 361L234 361Q200 405 140 405L140 405Q91 405 60.5 377.5 30 350 26 305L26 305Z"/>
</symbol>
<use xlink:href="#3" x="300" y="0"/>
<symbol id="3" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="100px" height="100px" viewBox="0 0 278 500">
<path d="M26 304L70 298Q77 336 95 352.5 113 369 140 369L140 369Q171 369 192 347.5 213 326 213 295 213 264 193 244 173 224 143 224L143 224Q130 224 112 229L112 229 117 191 124 191Q153 191 175 176.5 197 162 197 131L197 131Q197 107 181.5 91.5 166 76 139.5 76 113 76 96 91.5 79 107 74 140L74 140 30 132Q38 87 67 63 96 39 138 39L138 39Q167 39 191.5 51.5 216 64 229.5 86 243 108 243 132 243 156 230.5 175 218 194 193 205L193 205Q225 212 242.5 235 260 258 260 293L260 293Q260 340 226 372.5 192 405 140 405L140 405Q92 405 61 377 30 349 26 304L26 304Z"/>
</symbol>
<use xlink:href="#4" x="400" y="0"/>
<symbol id="4" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="100px" height="100px" viewBox="0 0 278 500">
<path d="M81 357L256 357 256 399 20 399Q20 383 25 368L25 368Q30 356 37 344 44 332 54 320.5 64 309 78 295.5 92 282 111 266L111 266Q140 242 160 223.5 180 205 190 191L190 191Q211 163 211 137.5 211 112 192
94 173 76 142.5 76 112 76 93 94.5 74 113 73 148L73 148 28 143Q33 92 63 65.5 93 39 144.5 39 196 39 226 67.5 256 96 256 139L256 139Q256 161 247.5 180.5 239 200 218 225L218 225Q208 236 191 252 174 268 150 288L150 288Q130 304 118 316L118 316 99 333 89 345Q85 350 81 357L81 357Z"/>
</symbol>
<use xlink:href="#5" x="500" y="0"/>
<symbol id="5" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="100px" height="100px" viewBox="0 0 278 500">
<path d="M210 399L166 399 166 313 11 313 11 273 174 41 210 41 210 273 259 273 259 313 210 313 210 399ZM54 273L166 273 166 111 54 273Z"/>
</symbol>
<use xlink:href="#6" x="600" y="0"/>
<symbol id="6" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="100px" height="100px" viewBox="0 0 278 500">
<path d="M32 316L74 312Q80 342 95 355.5 110 369 134 369L134 369Q155 369 169.5 359.5 184 350 194 334.5 204 319 211 293L211 293Q214 280 215.5 266.5 217 253 217 239L217 239 217 230Q204 251 181.5 264 159 277 131 277L131 277Q87 277 56.5 245 26 213 26 159.5 26 106 57.5 72.5 89 39 138 39L138 39Q172 39 201.5 58 231 77 246 112 261 147 261 212L261 212Q261 281 246 321.5 231 362 201.5 383.5 172 405 133 405L133 405Q90 405 63.5 381.5 37 358 32 316L32 316ZM212 158L212 158Q212 120 191.5 98 171 76 142.5 76 114 76 92.5 99.5 71 123 71 162L71 162Q71 197 91.5 218 112 239 142.5 239 173 239 192.5 217 212 195 212 158Z"/>
</symbol>
<use xlink:href="#7" x="700" y="0"/>
<symbol id="7" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" width="100px" height="100px" viewBox="0 0 278 500">
<path d="M93 205L93 205Q39 185 39 132L39 132Q39 92 67 65.5 95 39 142 39 189 39 217.5 67 246 95 246 133L246 133Q246 185 193 205L193 205Q226 216 243.5 239.5 261 263 261 296L261 296Q261 343 228.5 374 196 405 143 405 90 405 57.5 374.5 25 344 25 295L25 295Q25 260 42.5 236.5 60 213 93 205ZM84 130L84 130Q84 156 100.5 172 117 188 142 188 167 188 184 172 201 156 201 132.5 201 109 184.5 92.5 168 76 142.5 76 117 76
100.5 92 84 108 84 130ZM70 295L70 295Q70 315 78.5 332 87 349 105 359 123 369 143 369L143 369Q159 369 172 363.5 185 358 195 348L195 348Q216 329 216 297 216 265 195 244.5 174 224 142.5 224 111 224 90.5 244 70 264 70 295Z"/>
</symbol>
</svg>
convert code
let png = await sharp(Buffer.from(svgstr)).flatten({ background: { r: 255, g: 255, b: 255, alpha: 255 } }).png().toBuffer();
fs.writeFileSync(`${fileDir}/test.png`, png);
convert result

What is the expected behaviour?

What is the output of running npx envinfo --binaries --system?
System:
OS: Windows 10 10.0.18363
CPU: (8) x64 Intel(R) Xeon(R) CPU E3-1231 v3 @ 3.40GHz
Memory: 4.00 GB / 7.94 GB
Binaries:
Node: 14.15.0 - C:\Program Files\nodejs\node.EXE
npm: 6.14.8 - C:\Program Files\nodejs\npm.CMD
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the issue through the shown sharp(Buffer.from(svgstr)).flatten(...).png() entry point with the supplied SVG, comparing the generated image with the expected image. Investigate how an SVG without a root viewBox determines its default bounding box; done means the SVG content is rendered without clipping.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, node.js
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100