So you're in a browser environment and have a data:
URL describing an image? You don't need a package.
- Have the browser parse the URL and read it as an image with
i = new Image()
, i.addEventListener("load", listener)
, i.src = 'data:...'
.
- Within
listener
, create a canvas = new HTMLCanvasElement()
, and set its dimensions (width
, height
) to 28x28. The element doesn't need to be in the document, we'll just use it to draw things.
- Call
ctx = canvas.getContext("2d")
to get a 2D drawing canvas.
- Call
ctx.fillRect(0, 0, 28, 28)
to fill the canvas to a solid color, just in case the user's image contains an alpha channel you don't care about.. (Set fillColor
first if black isn't your thing.)
- Call
ctx.drawImage(i, 0, 0, 28, 28)
to draw the original image onto your context.
- Call
ctx.getImageData(0, 0, 28, 28)
to get an ImageData object describing the image.
- The ImageData object's
data
is now a 28 * 28 * 4 = 3136 byte array in RGBARGBARGBA... order. You wanted 784 (28 * 28 * 1) bytes, so either choose a channel (0, 1, 2) from the data
and copy with that offset and a stride of 4 to a 784-byte Uint8ClampedArray
, or average every 3 bytes to take a lazy grayscale of the RGB image data. (For a more correct grayscale, use e.g. v = 0.299 * r + 0.587 * g + 0.114 * b
for the YUV brightness scale.)
- Put the resulting 784-byte array where you need it to be.
(Since you mention you're working with tensors, and 28x28 sounds a lot like MNIST images, you may want to add additional logic to invert the grayscale if it looks like it's black-on-white; the MNIST images are white-on-black, and you'll get weird results if they're not the same.)