yisibl / resvg-js

A high-performance SVG renderer and toolkit, powered by Rust based resvg and napi-rs.
https://resvg-js.vercel.app/
Mozilla Public License 2.0
1.52k stars 54 forks source link

Feature request: (nice to have) output should extend ImageData #300

Open yjutard opened 6 months ago

yjutard commented 6 months ago

Hi, thanks for this lib that looks great! (I'm still evaluating)

I'm trying to pass the output to another lib, which requires an ImageData input:

class ImageData {
  data, // Uint8ClampedArray one-dimensional array containing the data in the RGBA order, with integer values between 0 and 255 (inclusive). The order goes by rows from the top-left pixel to the bottom-right.
  colorSpace, // string indicating the color space of the image data.
  height,
  width,
}

Looking at the output of resvg-js, it looks extremely similar:

export class RenderedImage {
  /** Write the image data to Buffer */
  asPng(): Buffer
  /** Get the RGBA pixels of the image */
  get pixels(): Buffer
  /** Get the PNG width */
  get width(): number
  /** Get the PNG height */
  get height(): number
}

My suggestion is to switch the output of resvg-js to the standard API ImageData or provide a conversion function, ex. toImageData()

yisibl commented 6 months ago

I haven't used ImageData, so resvg-js is mostly missing ImageData.colorSpace and the Uint8ClampedArray needed for ImageData.data?

See also: https://github.com/yisibl/resvg-js/pull/123

yisibl commented 6 months ago

Note: This structure is available in the node-related canvas library. https://github.com/Brooooooklyn/canvas/blob/a6b5cc4a45e2b58d7576ee413eff156f394511ff/index.d.ts#L169-L186

yisibl commented 6 months ago

resvg currently always uses the sRGB color space. See: https://github.com/RazrFalcon/resvg/issues/629

yisibl commented 6 months ago

Please see that having #304 is the solution to your needs?

yisibl commented 5 months ago

ping @yjutard

yjutard commented 5 months ago

Thanks @yisibl I was able to convert resvg's output to ImageData without effort:

const renderedImage = resvg.render();
const imageData = { // https://developer.mozilla.org/en-US/docs/Web/API/ImageData
    width: renderedImage.width,
    height: renderedImage.height,
    colorSpace: 'srgb', // let's try...
    data: renderedImage.pixels,
};
let { top, right, bottom, left } = getTrimEdges(imageData); // it works! (npm lib trim-image-data)

So it seems the current "pixels" format is OK ✅

My comment was about the data shape. Instead of inventing a new one, suggestion to use a "standard" one.

All good, not critical since the conversion is trivial. This issue can serve as doc. Feel free to close it!