Replies: 9 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
) |
Beta Was this translation helpful? Give feedback.
-
Tx for your help. |
Beta Was this translation helpful? Give feedback.
-
It would be nice, but for now this seems to work OK. |
Beta Was this translation helpful? Give feedback.
-
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);
}); |
Beta Was this translation helpful? Give feedback.
-
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);
}) |
Beta Was this translation helpful? Give feedback.
-
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")}`;
}; |
Beta Was this translation helpful? Give feedback.
-
I like this approach, but found error: Error [ValidationError]: Width and height must match the pixels array |
Beta Was this translation helpful? Give feedback.
-
canvas does not work for me with my new Mac M1 :( any workaround for M1 ? |
Beta Was this translation helpful? Give feedback.
-
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. |
Beta Was this translation helpful? Give feedback.
-
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
Beta Was this translation helpful? Give feedback.
All reactions