-
Notifications
You must be signed in to change notification settings - Fork 365
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
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
nodejs implementation #43
Comments
I just used this library, I am not sure what I am doing is correct, but this seems to work: import * as blurhash from 'blurhash'
import { createCanvas, loadImage, Image } from 'canvas'
const getImageData = (image: Image) => {
const canvas = createCanvas(image.width, image.height)
const context = canvas.getContext('2d')
context.drawImage(image, 0, 0)
return context.getImageData(0, 0, image.width, image.height)
}
const image = await loadImage('https://fakeimg.pl/300/')
console.log(' image = ', image.width, image.height)
const imageData = getImageData(image)
return blurhash.encode(
imageData.data,
imageData.width,
imageData.height,
4,
4
) |
Tx for your help. |
It would be nice, but for now this seems to work OK. |
An alternative implementation is to use Sharp. const sharp = require("sharp");
const { encode } = require("blurhash");
const encodeImageToBlurhash = path =>
new Promise((resolve, reject) => {
sharp(path)
.raw()
.ensureAlpha()
.resize(32, 32, { fit: "inside" })
.toBuffer((err, buffer, { width, height }) => {
if (err) return reject(err);
resolve(encode(new Uint8ClampedArray(buffer), width, height, 4, 4));
});
});
encodeImageToBlurhash("./img.jpg").then(hash => {
console.log(hash);
}); |
If you only work with png files use upng-js for other formats there are similar libraries with no extra processing libraries. Both of the previous techniques require a some heavy libraries Sharp uses 'libvips' and 'canvas' uses cairo OpenGL and it's overkill The lightest solution I found which only relies on javascript and works oob in nodejs/browsers: for example I needed to SSR so I can add the src to the image directly. import decode as decodeBlurhash from 'blurhash';
import UPNG from 'upng-js';
import encode as encode64 from 'base64-arraybuffer';
let width = 512;
let height = 512;
let colorsNumber = 256; //0 should use all colors but it does not work
let blurHashString='here is your blurhash string';
let pixels = decodeBlurhash(blurHashString, width, height);
let png = UPNG.encode([pixels], width, height, colorsNumber) ;
//I needed it as bas64string png you can just do something else with png data
imageSrc = 'data:image/png;base64,' + encode64(png);
// and so on.... for making the blurhash string directly from png files in pure javascript (i have not tested the 2nd code) but should work. Use it as guideline please. import * as fs from 'fs'
import encode as encodeBlurhash from 'blurhash';
import UPNG from 'upng-js';
fs.readFile(`demopic.png`, (err, data)=>{
var img = UPNG.decode(data);
let blurHashString = encodeBlurhash(img.data,img.width,img.height,4,4);
}) |
For people looking for node js implementation to create an image from your blurhash, here's a solution using Sharp. import { decode } from "blurhash";
import sharp from "sharp";
export const generateBlurhashURI = async (
hash: string,
width: number,
height: number,
options = {
size: 16,
quality: 40,
}
) => {
const hashWidth = options?.size;
const hashHeight = Math.round(hashWidth * (height / width));
const pixels = decode(hash, hashWidth, hashHeight);
const resizedImageBuf = await sharp(Buffer.from(pixels), {
raw: {
channels: 4,
width: hashWidth,
height: hashHeight,
},
})
.jpeg({
overshootDeringing: true,
quality: 40,
})
.toBuffer(); // Here also possible to do whatever with your image, e.g. save it or something else.
return `data:image/jpeg;base64,${resizedImageBuf.toString("base64")}`;
}; |
I like this approach, but found error: Error [ValidationError]: Width and height must match the pixels array |
canvas does not work for me with my new Mac M1 :( any workaround for M1 ? |
Thanks to everyone coming with great solutions! I believe both Anyone, feel free to create a package and open a PR here with a link 🙏🏼 However, I think this goes beyond the scope of this repo, so closing this. |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
I would try this algorithm but how to convert/use Uint8ClampedArray type in nodejs service.
Is it possible to have a more generic algorithm using only "basic" types ?
It seems that Uint8ClampedArray is an array of 8-bit unsigned integers clamped to 0-255
The text was updated successfully, but these errors were encountered: