Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

toBuffer() returns bgra #1416

Closed
bgirschig opened this issue May 5, 2019 · 1 comment · Fixed by #1421
Closed

toBuffer() returns bgra #1416

bgirschig opened this issue May 5, 2019 · 1 comment · Fixed by #1421
Assignees

Comments

@bgirschig
Copy link

Issue or Feature

I'm seeing something weird with the toBuffer method: The documentation says canvas.toBuffer('raw') returns argb data, but it is actually returning bgra.

That's not a big deal: once I found where this came from, I simply had to change a parameter in my ffmpeg command... But maybe the doc could be updated?

By the way, thanks a lot. This tool is awesome.

Steps to Reproduce

const { createCanvas } = require('canvas');

const canvas = createCanvas(2, 2);
const ctx = canvas.getContext('2d');

ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 1, 1);
ctx.fillStyle = 'green';
ctx.fillRect(1, 0, 1, 1);
ctx.fillStyle = 'blue';
ctx.fillRect(0, 1, 1, 1);
ctx.fillStyle = 'black';
ctx.fillRect(1, 1, 1, 1);

const buffer = canvas.toBuffer('raw');

console.log(buffer);
// expected (argb): ff,ff,0,0, ff,0,80,0, ff,0,0,ff, ff,0,0,0
// received (bgra): 0,0,ff,ff, 0,80,0,ff, ff,0,0,ff, 0,0,0,ff

Environment

node-canvas 2.4.1
node 10.0 on Mac OS X 10.14

@zbjornson
Copy link
Collaborator

Yeah, that's definitely confusing. Cairo describes it as:

ARGB32 ... alpha in the upper 8 bits, then red, then green, then blue. The 32-bit quantities are stored native-endian

i.e. the "upper" byte (alpha) is the 4th byte on little-endian systems like your Mac.

If you're interested in gory details, Wikipedia has a lengthy section on the ambiguity of this terminology, and there are ~20 messages on the cairo mailing list starting here and here.

PR welcome -- could more or less quote Cairo's description, along with a note like "on most systems (i.e. little-endian architectures), this means that the byte array is ordered [b,g,r,a,...]". Or if you prefer I can write up a PR (byte ordering is an odd fascination of mine).


BTW ImageData.data is described by the spec as "RGBA" and returns the more-expected, byte-wise result (except on big-endian systems, #908). Adjusting your ffmpeg usage to work with toBuffer('raw') as you've done is almost certainly faster, but just mentioning it.

0xFF,0,0,0xFF,   0,0x80,0,0xFF,   0,0,0xFF,0xFF,    0,0,0,0xFF

zbjornson added a commit to zbjornson/node-canvas that referenced this issue May 11, 2019
zbjornson added a commit to zbjornson/node-canvas that referenced this issue May 11, 2019
zbjornson added a commit to zbjornson/node-canvas that referenced this issue May 11, 2019
@zbjornson zbjornson self-assigned this May 11, 2019
zbjornson added a commit to zbjornson/node-canvas that referenced this issue May 31, 2019
zbjornson added a commit that referenced this issue May 31, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants