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

How to generate image from stream of raw input? #1579

Closed
flipactual opened this issue Feb 16, 2019 · 7 comments
Closed

How to generate image from stream of raw input? #1579

flipactual opened this issue Feb 16, 2019 · 7 comments

Comments

@flipactual
Copy link

flipactual commented Feb 16, 2019

I am trying to create an image (ideally to be output as a png) from raw pixel data, but I'm struggling to understand the desired format

const rs = Readable();
  const transformer = sharp({
    raw: {
      width,
      height,
      channels: 3,
    },
  });
  rs.pipe(transformer).pipe(createWriteStream(outputPath));

I have tried setting _read on rs to push Uint8Arrays, Buffers, and other types representing RGB data, but I inevitably get the Error: Unexpected data on Writable Stream error

I'm stumped, any help would be greatly appreciated

@lovell
Copy link
Owner

lovell commented Feb 16, 2019

Hello, this approach should be supported but sadly, as you point out, it looks like it isn't currently working. There are no unit tests for stream-based input of raw pixel data so this could be a regression, oops.

Luckily a small rejig of the logic relating to raw input in _createInputDescriptor should fix this. Happy to accept/help with a PR if you're able.

@lovell lovell added the bug label Feb 16, 2019
@flipactual
Copy link
Author

Thanks for the quick reply, I’ll start working on it today

@flipactual
Copy link
Author

flipactual commented Feb 16, 2019

@lovell Hey, I've got sharp building locally, tests pass and all that, ready to take a stab at this

But I'm a stream noob and I'm not sure how this change should go in

  1. Do we need a new branch in _createInputDescriptor with new functionality in is to check for a readable stream or is the intended input a buffer (coming from the stream)?
  2. If we are expecting a buffer, do we need to set this.options.input.buffer on instantiation? It seems to be referred to often in the path that's currently followed, but I'm unclear on how and where it's set in this case
  3. Again assuming that we're passing buffers through the stream to sharp, what should be in the buffers? I was guessing it would be Uint8Arrays like [0, 0, 0] (for three channels), but again, I have no idea what the intention is

@lovell
Copy link
Owner

lovell commented Feb 17, 2019

Fantastic, thanks for looking into this.

When Stream-based input is expected, inputDescriptor.buffer becomes an array ready for chunks to be pushed to in _write() - there's an internal _isStreamInput() helper function to test for this.

There's probably scope for simplification (and definitely a need for testing) but something like the following might work:

  } else if (!is.defined(input) && is.object(containerOptions) && containerOptions.allowStream) {
    // Stream
    inputDescriptor.buffer = [];
+ } else if (is.object(input) && is.object(input.raw) && is.object(containerOptions) && containerOptions.allowStream) {
+    // Raw Stream
+    inputDescriptor.buffer = [];
  } else {
    throw new Error('Unsupported input ' + typeof input);

@antmarot
Copy link

antmarot commented Mar 1, 2019

For anyone having trouble loading a raw stream, you can can do it by using null in the constructor.

Example:

const pipeline = sharp(null, { raw }).jpeg();
inStream.pipe(pipeline).pipe(outStream);

@lovell
Copy link
Owner

lovell commented Mar 18, 2019

Commit 83cdb55 adds a test for this, plus fixes the problem.

This will be in v0.22.0 - thanks for reporting!

@lovell lovell added this to the v0.22.0 milestone Mar 18, 2019
@lovell
Copy link
Owner

lovell commented Mar 19, 2019

v0.22.0 now available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants