Idea: blurhash and humbhash auto generated for images #11
Replies: 2 comments 4 replies
-
Good idea in general. Although, unlazy is intended as a client-first library at the moment. Only the Nuxt module has meta-framework context and would be able to convert an image into a hash. A better fit is probably to find a way to include unlazy into the Nuxt Image module, respectively the to-go solution in the Next.js world (which I'm not familiar with). |
Beta Was this translation helpful? Give feedback.
-
I have achieved something similar to this by wraping the In this particular code example, I am not having it render the Thumbhash but instead using the In a similar way, you may be able to integrate the Custom Image Component to do stuff between NiyamaImage & UnLazyImage<script setup lang="ts">
import type { ImageModifiers, ImageSizes } from '@nuxt/image';
import { consola } from 'consola';
import type { BlurHashObject } from '~~/types/database';
const { src, sizes, preset, densities, provider, modifiers, thumbhash, blurhash, preload, lazyLoad } = withDefaults(defineProps<{
src?: string
preload?: boolean
lazyLoad?: boolean
preset?: string
densities?: string
provider?: string
modifiers?: Partial<ImageModifiers>
sizes?: string
thumbhash?: string
blurhash?: BlurHashObject
ssr?: boolean
}>(), {
ssr: true,
})
const logger = consola.withTag('Component/NiyamaImage')
// logger.debug('🛠️ Setup')
const img = useImage()
const presets = img.options.presets
const _srcset = computedEager(() => {
const _preset = preset ? presets[preset] : undefined
const _sizes = (!sizes && _preset) ? _preset?.sizes : sizes
const _modifiers = (!modifiers && _preset) ? _preset.modifiers : modifiers
if (!src) {
return {
srcset: '',
sizes: '',
src: '',
} as ImageSizes
}
return img.getSizes(src, {
sizes: _sizes,
modifiers: _modifiers,
preset,
densities,
provider,
}, _sizes)
})
const _blurhash = computedEager(() => ({
hash: blurhash?.hash || '',
size: blurhash?.width || 0,
ratio: blurhashRatio(blurhash) || 1,
}))
</script>
<template>
<UnLazyImage
:key="_srcset.src || src"
:src="_srcset.src || src"
:src-set="_srcset.srcset"
:sizes="_srcset.sizes"
:thumbhash="thumbhash"
:blurhash="_blurhash.hash"
:placeholder-size="_blurhash.size"
:placeholder-ratio="_blurhash.ratio"
:selectable="false"
:draggable="false"
:preload="preload || false"
:loading="lazyLoad ? 'lazy' : ''"
:ssr="ssr"
/>
</template>
Custom Function to Generate ThumbhashThis code would obviously have to be wrapped to only execute on the server. import { Buffer } from 'node:buffer'
import { createCanvas, loadImage } from '@napi-rs/canvas'
import { rgbaToThumbHash } from 'thumbhash'
export async function generateThumbhash(bufferBody, maxSize = 100) {
const image = await loadImage(bufferBody)
const { width, height } = image
const scale = Math.min(maxSize / width, maxSize / height)
const resizedWidth = Math.floor(width * scale)
const resizedHeight = Math.floor(height * scale)
const canvas = createCanvas(resizedWidth, resizedHeight)
const context = canvas.getContext('2d')
context.drawImage(image, 0, 0, resizedWidth, resizedHeight)
const imageData = context.getImageData(0, 0, resizedWidth, resizedHeight)
const rgba = new Uint8Array(imageData.data.buffer)
const binaryThumbHash = rgbaToThumbHash(imageData.width, imageData.height, rgba)
return {
hash: Buffer.from(binaryThumbHash).toString('base64'),
width: imageData.width,
height: imageData.height,
}
} |
Beta Was this translation helpful? Give feedback.
-
From what I can tell, the
thumbhash
(andblurhash
) must be provided a string. It would be a great feature if this was generated automatically either server or client side. (Similar to what Gatsby Image did years ago)Thanks!
Beta Was this translation helpful? Give feedback.
All reactions