kleisauke / wasm-vips Goto Github PK
View Code? Open in Web Editor NEWlibvips for the browser and Node.js, compiled to WebAssembly with Emscripten.
Home Page: https://kleisauke.github.io/wasm-vips/
License: MIT License
libvips for the browser and Node.js, compiled to WebAssembly with Emscripten.
Home Page: https://kleisauke.github.io/wasm-vips/
License: MIT License
Steps to reproduce: Just follow the Browser setup in the documentation
Use node express as a simple webserver to serve index.html
As per directions set appropriate headers for SharedArrayBuffer
Run index.html and you will get stated error
In dev mode
Failed to resolve entry for package "/Users/user/projects/astro-vips/node_modules/.vite/deps". The package may have incorrect main/module/exports specified in its package.json.
9:04:39 PM [vite] Internal server error: Failed to resolve entry for package "/Users/user/projects/astro-vips/node_modules/.vite/deps". The package may have incorrect main/module/exports specified in its package.json.
Plugin: vite:asset-import-meta-url
File: /Users/user/projects/astro-vips/node_modules/.vite/deps/wasm-vips.js?v=c3cd4bc3
at packageEntryFailure (file:///Users/user/projects/astro-vips/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:28725:11)
at resolvePackageEntry (file:///Users/user/projects/astro-vips/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:28722:5)
at tryCleanFsResolve (file:///Users/user/projects/astro-vips/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:28381:28)
at tryFsResolve (file:///Users/user/projects/astro-vips/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:28328:17)
at TransformContext.transform (file:///Users/user/projects/astro-vips/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:43235:32)
at Object.transform (file:///Users/user/projects/astro-vips/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:44352:62)
at async loadAndTransform (file:///Users/user/projects/astro-vips/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:55026:29)
at async viteTransformMiddleware (file:///Users/user/projects/astro-vips/node_modules/vite/dist/node/chunks/dep-bb8a8339.js:64430:32)
09:07:28 PM [astro] Configuration updated. Restarting...
While dev mode starts to work with
optimizeDeps: {
exclude: ["wasm-vips"],
},
This causes errors in build
vite v4.5.0 building for production...
transforming (11) node_modules/react/cjs/react-jsx-runtime.production.min.jsUnexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:
(commonjs--resolver) resolveId "wasm-vips" "/Users/user/projects/astro-vips/src/components/VipsExample.tsx"
(vite:worker-import-meta-url) transform "/Users/user/projects/astro-vips/node_modules/wasm-vips/lib/vips-es6.js"
✓ 30 modules transformed.
✓ built in 526ms
file:///Users/user/projects/astro-vips/node_modules/rollup/dist/es/shared/node-entry.js:25902
reject(new Error(`Unexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:\n` +
^
Error: Unexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:
(commonjs--resolver) resolveId "./vips-es6.js" "/Users/user/projects/astro-vips/node_modules/wasm-vips/lib/vips-es6.worker.js"
(vite:worker-import-meta-url) transform "/Users/user/projects/astro-vips/node_modules/wasm-vips/lib/vips-es6.js"
at process.handleBeforeExit (file:///Users/user/projects/astro-vips/node_modules/rollup/dist/es/shared/node-entry.js:25902:28)
at Object.onceWrapper (node:events:629:26)
at process.emit (node:events:514:28) {
code: 'PLUGIN_ERROR',
plugin: 'commonjs--resolver',
hook: 'resolveId',
id: '/Users/user/projects/astro-vips/node_modules/wasm-vips/lib/vips-es6.js',
watchFiles: [
'\x00astro-entry:/Users/user/projects/astro-vips/src/components/VipsExample',
'/Users/user/projects/astro-vips/node_modules/@astrojs/react/client.js',
'/Users/user/projects/astro-vips/src/components/VipsExample.tsx',
'/Users/user/projects/astro-vips/node_modules/react/index.js',
'/Users/user/projects/astro-vips/node_modules/react-dom/client.js',
'/Users/user/projects/astro-vips/node_modules/@astrojs/react/static-html.js',
'/Users/user/projects/astro-vips/node_modules/react/cjs/react.production.min.js',
'/Users/user/projects/astro-vips/node_modules/react-dom/index.js',
'/Users/user/projects/astro-vips/package.json',
'/Users/user/projects/astro-vips/node_modules/react/jsx-runtime.js',
'/Users/user/projects/astro-vips/node_modules/wasm-vips/lib/vips-es6.js',
'\x00commonjsHelpers.js',
'\x00/Users/user/projects/astro-vips/node_modules/react/index.js?commonjs-module',
'\x00/Users/user/projects/astro-vips/node_modules/react/cjs/react.production.min.js?commonjs-proxy',
'\x00/Users/user/projects/astro-vips/node_modules/react/cjs/react.production.min.js?commonjs-exports',
'/Users/user/projects/astro-vips/node_modules/react-dom/cjs/react-dom.production.min.js',
'/Users/user/projects/astro-vips/node_modules/react/cjs/react-jsx-runtime.production.min.js',
'/Users/user/projects/astro-vips/node_modules/scheduler/index.js',
'\x00/Users/user/projects/astro-vips/node_modules/react/jsx-runtime.js?commonjs-module',
'\x00/Users/user/projects/astro-vips/node_modules/react/cjs/react-jsx-runtime.production.min.js?commonjs-proxy',
'\x00/Users/user/projects/astro-vips/node_modules/react/cjs/react-jsx-runtime.production.min.js?commonjs-exports',
'\x00/Users/user/projects/astro-vips/node_modules/react/index.js?commonjs-proxy',
'/Users/user/projects/astro-vips/node_modules/scheduler/cjs/scheduler.production.min.js',
'\x00/Users/user/projects/astro-vips/node_modules/react-dom/client.js?commonjs-exports',
'\x00/Users/user/projects/astro-vips/node_modules/react-dom/index.js?commonjs-proxy',
'\x00/Users/user/projects/astro-vips/node_modules/react-dom/index.js?commonjs-module',
'\x00/Users/user/projects/astro-vips/node_modules/react-dom/cjs/react-dom.production.min.js?commonjs-proxy',
'\x00/Users/user/projects/astro-vips/node_modules/react-dom/cjs/react-dom.production.min.js?commonjs-exports',
'\x00/Users/user/projects/astro-vips/node_modules/scheduler/index.js?commonjs-proxy',
'\x00/Users/user/projects/astro-vips/node_modules/scheduler/index.js?commonjs-module',
'\x00/Users/user/projects/astro-vips/node_modules/scheduler/cjs/scheduler.production.min.js?commonjs-proxy',
'\x00/Users/user/projects/astro-vips/node_modules/scheduler/cjs/scheduler.production.min.js?commonjs-exports'
]
}
I would love to use wasm-vips
, I just need to figure out how to import and use it
const vips = await Vips();
const image = vips.Image.text("test");
Run this code,I got blow errors:
Error: no such operation text
VipsOperation: class "text" not found
I'm not sure if this is a bug, I only want to add some font watermask to my picture.Do you have a better way?
Hello, I want to use this library to complete the following tasks: combine multiple small images into one large image in the browser and download it to the user's local.
So I write a demo, here are some main code snippets:
const urls = [have 1000 urls]
console.log('urls.length', urls.length)
const WIDTH = 1000
const HEIGHT = 720
const colNum = ~~Math.sqrt(urls.length)
const rowNum = ~~(urls.length / colNum)
window.startMerge = async () => {
const images = await Promise.all(
urls.map(async (url, index) => {
return vips.Image.newFromBuffer(await fetch(url).then(res => res.arrayBuffer()))
})
)
// merge images
let mergeImage = await vips.Image.black(WIDTH * colNum, HEIGHT * rowNum)
for (let i = 0; i < rowNum; i++) {
for (let j = 0; j < colNum; j++) {
const image = images[i * colNum + j]
mergeImage = await mergeImage.insert(image, j * WIDTH, i * HEIGHT)
// dispose image
image.delete()
}
}
console.log('mergeImage', mergeImage)
const buffer = await mergeImage.writeToBuffer('.jpg') // OOM happened
// const blob = new Blob([buffer], { type: 'image/jpeg' })
// const url = URL.createObjectURL(blob)
// const img = document.createElement('img')
// img.src = url
// img.style.position = 'fixed'
// img.style.top = '0'
// img.style.left = '0'
// img.style.zIndex = '9999'
// document.body.appendChild(img)
}
Does this mean that large files need to be streamed out? Instead of the overall output as it is now.
For some images such as https://github.com/swissspidy/media-experiments/blob/f6a7f9f26694b79a25ae2b844d2cc9a344d356a7/tests/e2e/assets/wordpress-logo-512x512.png I am getting this error when trying to convert to AVIF:
Existing issues with same error:
Weird thing is that this is a PNG / AVIF situation, so not sure why HEIF would be involved here.
Here's a playground repro:
I saw a previous query about using wasm-vips
in a web worker - but the op closed it due to realising that the lib opens its own web worker. #7
Would it be possible to use this lib inside a custom webworker? if so - any guidance would be greatly appreciated.
Is it possible to have a custom build of wasm-vips without SharedArrayBuffer
and Workers / concurrency ?
We wrap wasm-vips to build an internal texture compressor, it becomes slightly harder to package this as a library with the Worker Pattern.
Hi. I have the following situation. I'm working with an admin panel. Some images and scripts come from an external CDN. The main project is not a NodeJS app. I use Vite as a bundler for CSS and some scripts.
I want to use this library to crop images, generate webp and thumbnails on client side but when I add the required headers for cross-origin isolation, all the images and scripts from the CDN stop working. The same happen with my assets from my local Vite Dev Server.
I am currently still looking for a solution to this and I would be very grateful if you know of any strategies, tricks or anything you can share to solve this problem.
Hi, I'm really excited to try this project, but couldn't seem to get it running locally (Firefox & Chrome)
This was my minimum attempt:
<!DOCTYPE html>
<html>
<head>
<title>wasm-vips</title>
</head>
<body>
</body>
<script src="./vips.js"></script>
<script type="module">
const vips = await Vips();
</script>
</html>
Folder structure:
libvips
┣ index.html
┣ vips-jxl.wasm
┣ vips.js
┣ vips.wasm
┗ vips.worker.js
Console output:
Uncaught (in promise) DOMException: Failed to execute 'open' on 'XMLHttpRequest': Invalid URL
at oa (http://127.0.0.1:5555/vips.js:12:500)
at http://127.0.0.1:5555/vips.js:116:217
at new Promise (<anonymous>)
at e (http://127.0.0.1:5555/vips.js:116:191)
at f (http://127.0.0.1:5555/vips.js:116:467)
at fd (http://127.0.0.1:5555/vips.js:117:361)
at http://127.0.0.1:5555/vips.js:118:327
worker sent an error! http://127.0.0.1:5555/vips.worker.js:1: Uncaught SyntaxError: Failed to execute 'open' on 'XMLHttpRequest': Invalid URL
Lb.a.onerror @ vips.js:101
Hi! 👋
Firstly, thanks for your work on this project! 🙂
Today I used patch-package to patch [email protected]
for the project I'm working on.
I wanted to use types from .*saveBuffer functions to generate yup validators, but it wasn't possible because exports don't exist. So I added some improvements for types
example of usage:
import { useEffect, useState } from 'react';
import VipsWASM from 'wasm-vips';
type VipsTypes = typeof VipsWASM;
export const useVips = () => {
const [vips, setVips] = useState<VipsTypes | undefined>(undefined);
const [cleanup, setCleanup] = useState<(() => void) | undefined>(undefined);
useEffect(() => {
if (vips) return;
VipsWASM({
// TODO: check does it affect loading speed
// dynamicLibraries: ['vips-jxl.wasm', 'vips-heif.wasm', 'vips-resvg.wasm'],
// Workers need to import the unbundled version of `vips.js`
mainScriptUrlOrBlob: './vips.js',
// wasm-vips is served from the public directory
locateFile: (fileName) => fileName,
preRun: (module) => {
module.setAutoDeleteLater(false);
// TODO: figure out how to make this work
// module.setAutoDeleteLater(true);
module.setDelayFunction((fn: () => void) => setCleanup(fn));
},
}).then((vips) => {
vips.concurrency(10);
setVips(vips);
});
return () => {
if (!vips) return;
type ImageAutoGen = VipsWASM.ImageAutoGen;
type webpsaveBufferType = ImageAutoGen['webpsaveBuffer'];
type webpsaveBufferParams = Parameters<webpsaveBufferType>;
type webpsaveBufferOptions = webpsaveBufferParams[0];
const object: webpsaveBufferOptions = {};
if (vips) {
// @ts-ignore don't understand why it throws error
// it doesn't catch types narrowing
return vips.shutdown();
}
};
}, []);
return { vips, cleanup };
};
Here is the diff that solved my problem:
diff --git a/node_modules/wasm-vips/lib/vips.d.ts b/node_modules/wasm-vips/lib/vips.d.ts
index e97c352..6754e55 100644
--- a/node_modules/wasm-vips/lib/vips.d.ts
+++ b/node_modules/wasm-vips/lib/vips.d.ts
@@ -1,4 +1,4 @@
-declare function Vips(config?: Partial<EmscriptenModule>): Promise<NonNullable<typeof Vips>>;
+export declare function Vips(config?: Partial<EmscriptenModule>): Promise<NonNullable<typeof Vips>>;
type ModuleCallback = { (module?: any): void };
@@ -26,7 +26,7 @@ interface EmscriptenModule {
workaroundCors: boolean;
}
-declare module Vips {
+export declare module Vips {
// Allow single pixels/images as input.
type SingleOrArray<T> = T | T[];
This issue body was partially generated by patch-package.
I understand that I shoud've probably updated this - https://github.com/kleisauke/wasm-vips/blob/master/build/gen_type_declarations.py, but i'm not fluent enough in python to do it currently. Thanks
Exciting project! Thanks for working on this and sharing it.
In this comment it is mentioned that the browser files can be downloaded from here:
Would it be possible to publish these in such a way that they can be accessed via unpkg.com or deno.land/x with a simple import like e.g. this?
import vips from "https://unpkg.com/[email protected]/web/vips.js"
Loading the image like this works fine.
const vips = await Vips();
let im = vips.Image.newFromFile('in.jpg');
What I do not know is the syntax for resampling and upscaling an image using lanzcos3.
It looks like I need to use vips.affine as shown in the vips docs. What would my javascript statement be in order to resample upscale my image.
Thanks,
Dan
Hey, thanks once again for your library.
I believe I'm facing a bug. Specifically, library doesn't finish command if I call writeToBuffer for a PNG file with parameters palette and Q.
Example of the same command but via vips CLI (works well)
vips pngsave sample_5184×3456.png worked.png --Q 50 --vips-progress
Example of code that's freezing on the playground
let im = vips.Image.newFromFile('owl.png');
// Finally, write the result to a blob
const t0 = performance.now();
const outBuffer = im.writeToBuffer('.png', {
Q: 50,
palette: true
});
const t1 = performance.now();
const blob = new Blob([outBuffer], { type: 'image/jpeg' });
const blobURL = URL.createObjectURL(blob);
const img = document.createElement('img');
img.src = blobURL;
document.getElementById('output').appendChild(img);
Link to the file that's causing the problem, can't attach here because it has 35+mb in size
Also, the UI is totally freezing when writeToBuffer processes any images, but for bigger images, it's more visible, I understand it's basically CPU calculations, but I can't even add a loader because it won't spin as the UI is freezing, if it's possible to do something with this behavior would really appreciate suggestions, thanks
let image = vips.Image.newFromBuffer(arrayBuff);
image = image.hist_norm()
image.hist_norm() results in error is not a function.
const vipsImage = vips.Image.pdfloadBuffer(attachment, {page: pageNumber});
const image = vipsImage.pngsaveBuffer();
I wanted to create preview image for pdf with same scale in node js, but seems like it's not working, throws me an error
ab [vips::Error]: no such operation pdfload_buffer VipsOperation: class "pdfload_buffer" not found
I am using
Node - v18.16.0
"wasm-vips": "^0.0.5"
Is this something that is not developed or is it a bug
It seems some images (for now, only jpg) don't work.
For example, this image:
https://wellom.nyc3.digitaloceanspaces.com/media/bugs/annie-spratt-hX_hf2lPpUU.jpg
You can reproduce the issue in the playground by using the image link to load the image in the fetch.
Playground
vips.Image.newFromBuffer
works.
But writeToBuffer
stalls.
Original image: https://unsplash.com/photos/green-leaf-hX_hf2lPpUU
Several images from the same author have the same problem. I'm trying to figure out what it is. Maybe there is a known issue about this matter.
My build fails when compiling newer versions of wasm-vips. It fails when generating the node-es6 bindings with the following errors:
wasm-ld: error: /src/build/target/lib/libz.a(crc32.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `crc_table`; recompile with -fPIC
wasm-ld: error: /src/build/target/lib/libz.a(crc32.o): relocation R_WASM_MEMORY_ADDR_LEB cannot be used against symbol `functable`; recompile with -fPIC
wasm-ld: error: /src/build/target/lib/libz.a(functable.o): relocation R_WASM_TABLE_INDEX_SLEB cannot be used against symbol `insert_string_c`; recompile with -fPIC
wasm-ld: error: /src/build/target/lib/libz.a(functable.o): relocation R_WASM_MEMORY_ADDR_LEB cannot be used against symbol `cpu_check_features.features_checked`; recompile with -fPIC
wasm-ld: error: /src/build/target/lib/libz.a(functable.o): relocation R_WASM_TABLE_INDEX_SLEB cannot be used against symbol `quick_insert_string_c`; recompile with -fPIC
There are many more lines that are all similar to the ones above.
I am building this in the Docker container by running npm run build
, so I would be surprised if this issue is specific to my computer.
I am happy to test a fix for you. I am trying to figure one out myself, but so far have not found anything.
Build with npm run build
on Mac, I always got this:
[ 80%] Linking CXX executable ../../../../lib/web/vips.js
wasm-ld: error: unable to find library -lUSE_PTHREADS=1
wasm-ld: error: unable to find library -lUSE_PTHREADS=1
wasm-ld: error: unable to find library -lUSE_PTHREADS=1
ReferenceError: Worker is not defined
at Object.nb (https://cdn.jsdelivr.net/npm/wasm-vips/lib/vips-es6.js:102:450)
at Object.Fc (https://cdn.jsdelivr.net/npm/wasm-vips/lib/vips-es6.js:99:127)
at Object.init (https://cdn.jsdelivr.net/npm/wasm-vips/lib/vips-es6.js:99:58)
at https://cdn.jsdelivr.net/npm/wasm-vips/lib/vips-es6.js:348:221
at file:///src/main.ts:11:20
Need to simply know if wasm-vips will work without SharedArrayBuffer with some efforts?
Background:
I am working on a desktop application. as it's a desktop application, there's no 'server' per se. so I can't really set the headers to make SharedArrayBuffer available easily. I have been digging into other alternatives to make this work but it's been a long time and I haven't found anything substantial.
Is there any way I will be able to make wasm-vips work without SAB api? I am fine with performance hit. or any other vips lib that you are aware of that doesn't use SAB api? any help is appreciated I have been chasing this for a long time
Hi.
I'm trying to compile the library using the docker file but I get the next error:
=============================================
Compiling JS bindings
=============================================
configure: cmake /src -DCMAKE_BUILD_TYPE=Release -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/src/lib -DENVIRONMENT=web;node -DENABLE_MODULES=true -DENABLE_WASMFS=false -DCMAKE_TOOLCHAIN_FILE=/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_CROSSCOMPILING_EMULATOR=/usr/bin/node
-- Found PkgConfig: /usr/bin/pkg-config (found version "1.8.0")
-- Checking for module 'vips>=8.14'
-- Found vips, version 8.14.2
-- Configuring done
-- Generating done
-- Build files have been written to: /src/build/deps/wasm-vips
[ 10%] Building CXX object src/CMakeFiles/wasm-vips.dir/bindings/connection.cpp.o
[ 20%] Building CXX object src/CMakeFiles/wasm-vips.dir/bindings/image.cpp.o
[ 30%] Building CXX object src/CMakeFiles/wasm-vips.dir/bindings/interpolate.cpp.o
[ 40%] Building CXX object src/CMakeFiles/wasm-vips.dir/bindings/option.cpp.o
[ 50%] Building CXX object src/CMakeFiles/wasm-vips.dir/bindings/utils.cpp.o
[ 60%] Building CXX object src/CMakeFiles/wasm-vips.dir/vips-emscripten.cpp.o
/src/src/bindings/connection.cpp:41:9: error: use of undeclared identifier 'EM_FUNC_SIG_JPJ'
EM_FUNC_SIG_JPJ, self->read_callback, buffer, length);
^
/src/src/bindings/connection.cpp:52:9: error: use of undeclared identifier 'EM_FUNC_SIG_JJI'
EM_FUNC_SIG_JJI, self->seek_callback, offset, whence);
^
/src/src/bindings/connection.cpp:95:9: error: use of undeclared identifier 'EM_FUNC_SIG_JPJ'
EM_FUNC_SIG_JPJ, self->write_callback, buffer, length);
^
/src/src/bindings/connection.cpp:109:9: error: use of undeclared identifier 'EM_FUNC_SIG_JPJ'
EM_FUNC_SIG_JPJ, self->read_callback, buffer, length);
^
/src/src/bindings/connection.cpp:120:9: error: use of undeclared identifier 'EM_FUNC_SIG_JJI'
EM_FUNC_SIG_JJI, self->seek_callback, offset, whence);
^
5 errors generated.
em++: error: '/emsdk/upstream/bin/clang++ -target wasm32-unknown-emscripten -fvisibility=default -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-cxx-exceptions -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr -D__EMSCRIPTEN_SHARED_MEMORY__=1 -DEMSCRIPTEN --sysroot=/emsdk/upstream/emscripten/cache/sysroot -Xclang -iwithsysroot/include/fakesdl -Xclang -iwithsysroot/include/compat -O3 -pthread -fexceptions -mnontrapping-fptoint -msimd128 -fPIC -O3 -std=c++11 -DG_DISABLE_ASSERT -DG_DISABLE_CAST_CHECKS -DG_DISABLE_CHECKS -I/src/build/target/include/glib-2.0 -I/src/build/target/lib/glib-2.0/include -I/src/build/target/include/webp -DWASM_SIMD_COMPAT_SLOW -DWASM_BIGINT -DNDEBUG -c -MD -MT src/CMakeFiles/wasm-vips.dir/bindings/connection.cpp.o -MF CMakeFiles/wasm-vips.dir/bindings/connection.cpp.o.d -matomics -mbulk-memory /src/src/bindings/connection.cpp -o CMakeFiles/wasm-vips.dir/bindings/connection.cpp.o' failed (returned 1)
make[2]: *** [src/CMakeFiles/wasm-vips.dir/build.make:77: src/CMakeFiles/wasm-vips.dir/bindings/connection.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [CMakeFiles/Makefile2:106: src/CMakeFiles/wasm-vips.dir/all] Error 2
make: *** [Makefile:91: all] Error 2
Do you know what the issue could be?
Thanks in advance.
Hi. First, your lib is a game changer! I'm a big fan.
This is the possible bug I'm talking about:
const outputBuffer = image.jpegsaveBuffer({ Q: 90, interlace: true })
const blob = new Blob([outputBuffer], { type: 'image/jpeg' })
const url = URL.createObjectURL(blob)
// <a href="${url}" download="image.jpg" rel="download">Download image</a>
The image produced this way still loads top to bottom.
What should I do to make my jpegs progressive using wasm-vips?
I've been trying saving to the various image formats supported by libvips and most work without issue.
However, when I try to save to a JPEG 2000, I get the error:
no such operation jp2ksave_buffer
VipsOperation: class "jp2ksave_buffer" not found
I'd assume this is due to JPEG 2000 support not currently being built into the binary. Would it be possible to add support for JPEG 2000? Thanks.
This repo is awesome!
At this stage it looks like simd support is necessary, is it possible to build no simd version for lower version browsers (those that don't support simd)?
I am using wasm-vips
as a dependency for a CLI tool. Currently, if vips
encounters a warning, it will output it directly to the console. This is pretty annoying because the CLI tool already is outputting information to the console, so now there are random fragments of vips
warnings cluttered in with the rest of the information.
I would like to be able to receive the warnings in a function, where I can write my own logic for when and where the output should be logged.
If that is not possible, the next best thing would be to tell wasm-vips
to never output anything.
Maybe this is already supported? But I can't seem to figure out how it works. I have already tried this, as an attempt to make it stop outputting to the CLI, but it did not work:
import newVips from "wasm-vips";
const vips = await newVips({
print: (stdout) => {return ""},
printErr: (stderr) => {return ""},
preRun: module => {
module.print = (stdout) => {return ""};
module.printErr = (stderr) => {return ""};
},
});
Title.
I'd love to see the result of some operations on my own pictures <3
it would be nice for this to happen :)
also found this
I am trying to perform certain operations on a multi-page tiff image using the sharp package. Except for trim
, flip
and rotate
, all needed operations are successfully performed by sharp.
For flip
, sharp flips the whole image and its order too. For trim
and rotate
, it simply throws an error. This is a known issue, lovell/sharp#1580.
Using the vips.Image.arrayjoin
function, I was able to get the desired output, but overtime it increases my rss
memory size drastically, eventually killing the process. The heap is not increasing as the GC
works promptly. The memory jump happens at the writeToBuffer
function call.
Is there any different way of getting the same results, without the rss
size jump?
Attaching the code and the input image. Thank you.
import { readFileSync } from "node:fs";
import Vips from "wasm-vips";
import sharp from "sharp";
function log(msg) {
const obj = {};
for (const [key, value] of Object.entries(process.memoryUsage())) {
obj[key] = Math.round(value / (1024 * 1024))
}
console.log(msg, "\n" + JSON.stringify(obj, null, 4) + "\n");
}
async function createMultiPageImage(buffer, op, ...params) {
const buffers = [];
const { pages: pageCount } = await sharp(buffer, { pages: -1 }).metadata();
for (let i = 0; i < pageCount; i++) {
buffers.push(sharp(buffer, { pages: 1, page: i })[op](...params).toBuffer());
}
const results = await Promise.allSettled(buffers);
const pages = [];
for (const { status, value, reason } of results) {
if (status === "fulfilled") {
pages.push(value);
} else {
throw reason;
}
}
const vips = await Vips();
vips.concurrency(1);
vips.Cache.max(0);
const vipsPages = pages.map((page) => vips.Image.newFromBuffer(page, "", { access: vips.Access.sequential }));
const vipsImage = vips.Image.arrayjoin(vipsPages, { across: 1 });
const { height, format } = await sharp(pages[0]).metadata(); // height changes can occur
const vipsBuffer = vipsImage.writeToBuffer("." + format, { page_height: height }).buffer;
vipsPages.map((vipsPage) => vipsPage.delete());
vipsImage.delete();
vips.shutdown();
return Buffer.from(vipsBuffer);
}
let buffer = readFileSync("./multi_page_images/multipage.tiff");
buffer = await sharp(buffer, { pages: -1 }).flop().toBuffer();
log("flop");
buffer = await sharp(buffer, { pages: -1 }).negate().toBuffer();
log("negate");
buffer = await createMultiPageImage(buffer, "flip");
log("flip");
buffer = await createMultiPageImage(buffer, "rotate", 30);
log("rotate");
buffer = await createMultiPageImage(buffer, "trim");
log("trim");
process.exit();
flop
{
"rss": 62,
"heapTotal": 12,
"heapUsed": 7,
"external": 1,
"arrayBuffers": 0
}
negate
{
"rss": 65,
"heapTotal": 12,
"heapUsed": 7,
"external": 1,
"arrayBuffers": 0
}
flip
{
"rss": 314,
"heapTotal": 32,
"heapUsed": 17,
"external": 8,
"arrayBuffers": 7
}
rotate
{
"rss": 447,
"heapTotal": 36,
"heapUsed": 25,
"external": 18,
"arrayBuffers": 17
}
trim
{
"rss": 500,
"heapTotal": 58,
"heapUsed": 21,
"external": 24,
"arrayBuffers": 24
}
Image file multipage.tiff
Hello,
This is a cool project, and I was thinking of using it in Cloudflare Workers and saw your card here https://github.com/kleisauke/wasm-vips/projects/1#card-44661973
There's a hurdle, however, that prevents this from being possible: "The module and script together must be under 1MB after gzip compression" - https://community.cloudflare.com/t/what-is-the-maximum-allowed-size-of-a-webassembly-module/66453/2
The .wasm file is ~4.3 MB uncompressed, and ~1.41MB (gzip 9) compressed. Maybe a slimmed version of the library could still be used, with some support for formats dropped?
Node has recently made a change to the WASM interpreter that is causing errors in wasm-vips
. The errors seem completely random and affect many modules, but the most affected module seems to be libspng
which cannot decode even a simple png file.
The issue was introduced in Node 18.14.2
and 19.4.0
. I was not able to reproduce this error in the Chromium browser, version 110.0.5481.177
and 112.0.5615.20
.
The issue does not affect wasm-vips
version 0.0.4
, although I am not sure when exactly the issue was "introduced". Maybe with the switch to Meson for libvips
? I know for sure that b24ca0b and later is affected.
I hope this is not OS-specific, but FYI I have only run these tests on Ubuntu 22.04, on an Intel 10th-gen x64 chip.
I noticed the errors while working on EWAB, but the test suite also reports errors on these versions:
1) colour
cmyk:
vips::Error: unable to call colourspace
vips__file_open_read: unable to open file "cmyk" for reading
unix error: No such file or directory
profile_load: unable to load profile "cmyk"
at Wc (file:///home/anton/Documents/GitHub/wasm-vips/lib/vips-node.mjs:125:428)
at wasm://wasm/0152235e:wasm-function[4260]:0x1ae91f
at Nd.Image$colourspace (eval at Ge (file:///home/anton/Documents/GitHub/wasm-vips/lib/vips-node.mjs:162:242), <anonymous>:10:10)
at a.<computed> [as colourspace] (file:///home/anton/Documents/GitHub/wasm-vips/lib/vips-node.mjs:152:259)
at Context.<anonymous> (file:///home/anton/Documents/GitHub/wasm-vips/test/unit/test_colour.js:212:21)
at process.processImmediate (node:internal/timers:475:21)
2) connection
image
writeToTarget
custom:
AssertionError: expected 242 to equal +0
+ expected - actual
-242
+0
at Context.<anonymous> (file:///home/anton/Documents/GitHub/wasm-vips/test/unit/test_connection.js:161:55)
at process.processImmediate (node:internal/timers:475:21)
3) foreign
png:
AssertionError: expected +0 to be close to 38671 +/- 0.0001
at file:///home/anton/Documents/GitHub/wasm-vips/test/unit/helpers.js:181:33
at Array.forEach (<anonymous>)
at Module.assertAlmostEqualObjects (file:///home/anton/Documents/GitHub/wasm-vips/test/unit/helpers.js:180:19)
at pngValid (file:///home/anton/Documents/GitHub/wasm-vips/test/unit/test_foreign.js:396:15)
at fileLoader (file:///home/anton/Documents/GitHub/wasm-vips/test/unit/test_foreign.js:79:5)
at Context.<anonymous> (file:///home/anton/Documents/GitHub/wasm-vips/test/unit/test_foreign.js:402:5)
at process.processImmediate (node:internal/timers:475:21)
4) foreign
svgload:
vips::Error: unable to load from file ./images/logo.svgz
VipsForeignLoad: "./images/logo.svgz" is not a known file format
at Wc (file:///home/anton/Documents/GitHub/wasm-vips/lib/vips-node.mjs:125:428)
at wasm://wasm/0152235e:wasm-function[1301]:0x7e5ec
at Function.Image$newFromFile (eval at Ge (file:///home/anton/Documents/GitHub/wasm-vips/lib/vips-node.mjs:162:242), <anonymous>:8:10)
at a.<computed> [as newFromFile] (file:///home/anton/Documents/GitHub/wasm-vips/lib/vips-node.mjs:152:259)
at fileLoader (file:///home/anton/Documents/GitHub/wasm-vips/test/unit/test_foreign.js:80:21)
at Context.<anonymous> (file:///home/anton/Documents/GitHub/wasm-vips/test/unit/test_foreign.js:883:5)
at process.processImmediate (node:internal/timers:475:21)
5) resample
thumbnail:
AssertionError: expected 48.23111979166666 to be below 1
+ expected - actual
-48.23111979166666
+1
at Context.<anonymous> (file:///home/anton/Documents/GitHub/wasm-vips/test/unit/test_resample.js:268:82)
at process.processImmediate (node:internal/timers:475:21)
Pending fixes:
In Deno, vips.Image.newFromBuffer(buffer)
works well! But opening local files directly for example vips.Image.newFromFile('sample.jpg')
always complains:
error: vips::Error: unable to load from file sample.jpg
VipsForeignLoad: file "sample.jpg" does not exist
I thought it would be an issue of relative paths, but I tried all kinds of absolute and relative paths (relative to Deno.cwd(), or import.meta.url, or the directory where vips-es6.js is stored), with and without file://
prefix, with no luck.
Furthermore I tried a simple filename without path, and put a sample.jpg in every directory I could think of where it might try to load it. No luck.
Am I missing something, or is this is a bug with wasm-vips on deno?
Deno 1.38.5, wasm-vips version is i guess 0.0.7 (or whatever it is that jsdelivr is giving - I manually downloaded vips-es6.js and all the other JS and WASM file from jsdelivr in order to install and import locally since it seems using jsdelivr the wasm files are loaded again over the net every run? - could we perhaps somehow have these zipped on new releases?)
PS:
I'm running on VPS's with limited RAM, so while ArrayBuffers work, I'm hoping passing file paths directly would negate the need for allocating big in and out buffers, and perhaps allow vips to process data in a more streaming manner (if it does that, or does it need to load the full file data in memory?).
Ideally for Deno, it would be great if we were able to work with ReadableStream
in and WritableStream
out, but that does not appear possible at the moment. That's why I'm looking into passing file paths instead of ArrayBuffer
This test program:
import Vips from './lib/vips-node.mjs';
const vips = await Vips({
dynamicLibraries: ['vips-resvg.wasm']
});
const svg =
'<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" id="svg-root" />';
const im = vips.Image.newFromBuffer(svg);
im.writeToFile('x.png');
Fails with:
$ node test.mjs
wasm://wasm/00561afe:1
TypeError: type incompatibility when transforming from/to JS
at wasm://wasm/00561afe:wasm-function[616]:0x7a3aa
at gh (lib/vips-node.mjs:314:433)
at wasm://wasm/00561afe:wasm-function[1113]:0xeafb9
at wasm://wasm/00561afe:wasm-function[201]:0xcf95
at wasm://wasm/00561afe:wasm-function[1304]:0x119fa2
at wasm://wasm/0169d79e:wasm-function[6279]:0x474c27
at wasm://wasm/0169d79e:wasm-function[311]:0x1ca8a
at wasm://wasm/0169d79e:wasm-function[1465]:0xfbd6f
at wasm://wasm/0169d79e:wasm-function[6208]:0x46ab34
at sh (lib/vips-node.mjs:315:262)
Node.js v18.16.0
1) SVG input
Convert SVG with embedded images to PNG, respecting dimensions, autoconvert to PNG:
Uncaught TypeError: type incompatibility when transforming from/to JS
at rosvgtree::parse::parse::h46e668755e5e4dd7 (wasm://wasm/030b2c16:wasm-function[1098]:0xe5bf3)
at invoke_vii (build/Release/sharp-emscripten-wasm32.node.js:7803:27)
at _$LT$usvg_tree..Tree$u20$as$u20$usvg_parser..TreeParsing$GT$::from_str::h2ad984f34c8b8916 (wasm://wasm/030b2c16:wasm-function[1699]:0x161843)
at _$LT$usvg_tree..Tree$u20$as$u20$usvg_parser..TreeParsing$GT$::from_data::hb74bbe40b8ecb9f0 (wasm://wasm/030b2c16:wasm-function[596]:0x60ca1)
at invoke_viiii (build/Release/sharp-emscripten-wasm32.node.js:7936:27)
at resvg_parse_tree_from_file (wasm://wasm/030b2c16:wasm-function[594]:0x60283)
at vips_foreign_load_svg_file_header (wasm://wasm/030b2c16:wasm-function[5339]:0x2b4596)
at vips_foreign_load_build (wasm://wasm/030b2c16:wasm-function[4480]:0x21e4af)
at vips_object_build (wasm://wasm/030b2c16:wasm-function[4667]:0x2313ac)
at vips_cache_operation_buildp (wasm://wasm/030b2c16:wasm-function[4227]:0x1ea98a)
When wasm-vips was build with LTO enabled, i.e:
$ npm run build -- --enable-lto
It looks like this error orginates from V8:
https://github.com/nodejs/node/blob/v18.16.0/deps/v8/src/common/message-template.h#L600
Building without LTO or removing id="svg-root"
from this particular SVG seems to fix this.
This was found while trying to update wasm-vips in lovell/sharp#3522.
No idea why I am suddenly getting the following error:
I have used this library about a year ago, and it worked fine for me, today I upgraded deps and the lib is not working anymore.
I am using vite+react +typescript. do I need specific vite config? I get the same error regardless how I import vips in index.html (es6 or not).
PS: it works just fine if I import wasm-vips in the react component where I need vips. But then I can't get to build the project, it crashes with JS heap out of memory. So importing in index is my only option, I believe.
import Vips from 'wasm-vips';
const vips = await Vips();
let im = vips.Image.newFromFile('test.4.jpg');
im.heifsave('testoutput.avif');
This fails on wasm-vips 0.0.4, perhaps some build flag is missing?
Does libvips-wasm support HEIC decoding? From the announcement it's not very clear: JPG, PNG, TIFF, WebP are mentioned, but it's not clear if the list is exhaustive.
It would be very useful for creating an in-browser HEIC->JPG converter. Modern iPhone photos are in HEIC and Windows often has broken HEIC decoding.
With libtiff 4.5.0, some new build options are introduced which may help compile times:
--disable-tools
--disable-tests
--disable-contrib
--disable-docs
Certain parameters on jpegSaveBuffer
operation are ignored and I can't seem to find why that's the case?
If you could help me figure out what the bug I might be, I could help contribute?
(process:42): VIPS-WARNING **: 01:55:30.646: ignoring quant_table
(process:42): VIPS-WARNING **: 01:55:30.865: ignoring trellis_quant
(process:42): VIPS-WARNING **: 01:55:30.865: ignoring overshoot_deringing
(process:42): VIPS-WARNING **: 01:55:30.866: ignoring optimize_scans
I am using the latest version of wasm-vips
but in production I am getting the following error:
requested a shared WebAssembly.Memory but the returned buffer is not a SharedArrayBuffer, indicating that while the browser has SharedArrayBuffer it does not have WebAssembly threads support - you may need to set a flag
I am setting the headers correctly:
I also get the vips.js correctly. Also the console doesn't exactly print anything. I got it by breaking on all exceptions.
I am on latest version on mac, using it in native webview.
I've installed this npm package in a repo using storybook, as I'm trying to experiment with it in React but I'm unable to get it working in the browser. Of course, it downloads a version of the package for node use only, so I'm wondering how to get this working in a browser, since the files provided by the npm package use things specific to node.
I know the playground works, so do I have to grab a copy of this repo and build things locally?
First I want to say thank you for this project!
I was hoping to use it in a web worker to move image processing off of the main thread. However, when new Vips()
is instantiated a ReferenceError: window is not defined
is thrown because window is not available to workers. It looks to be coming from emscripten.
Any ideas on how to compile for a worker?
First off, let me say how impressed I am with wasm-vips — amazing job 🤩👏🥳 Can't tell you how great your lib "just works" in comparison to about 8 other browser-based image manipulation libs I've tried, despite its supposed alpha quality. (If this is alpha quality, all the other libs are laughably early pre-alphas!)
The suggestion here is around more modular loading. The dynamicLibraries
option is super helpful and shaves off quite a few unnecessary MB. However, I was wondering whether we could extend the concept to some of the more "core" Vips functionality. For instance, I only need webp resizing and encoding. I realize tree-shaking WASM is not yet a thing and may never be, but perhaps it's possible to further granulate wasm-vips analogously to dynamicLibraries
. For instance I can imagine passing only features: ["resize", "web-encode"]
or however the API might look.
Probably a big ask because ostensibly libvips itself isn't modular in the way I'm describing, but worth a discussion, I think.
Thanks again!
First of all would like to thank for your job, it's awesome that people making possible projects like this one. I think it has bright future.
So I was working with node.js sharp library, wrapper around libvips. Found out that everything now can be done even without backend, found out about your project and started trying to work but stuck. I have no problems when using it on backend (I didn't try much because it's not what I wanted). But it produces different errors each time I'm trying to make it work with next.js
For example I'm constantly getting this error:
Link to my project: https://github.com/serafimsanvol/my-app/blob/main/src/app/page.tsx
It's just basic next starter project so I'm sure that there is something with library configuration but I don't know what are workarounds here, can you help/explain/tell me that it's bug and actually unexpected behaviour?
On different project with slightly different setup and set headers as required it shows different error:
Any help/suggestions appreciated, thanks
Is there some sort of memory freeing function that I need to call after processing an image? Here's a playground link that produces an OOM error after processing (resize+crop) 131 images on my machine using Chrome. Here's a version that downloads the images in parallel - just to make it faster to reproduce (Edit: This seems like it causes fetch to return 503 errors sometimes - might be hitting reddit's rate limit. Maybe best to stick with the serial version). Here's the code for the serial-download version in case the link stops working for whatever reason (just processes some random images a reddit crawl):
(async function() {
let urls = ["https://i.redd.it/da5l9vs50pw41.jpg","https://i.redd.it/m3pio5xwpza11.jpg","https://i.redd.it/e4n4xfdcrn171.jpg","https://i.redd.it/8lyhh8ll8cz61.jpg","https://i.redd.it/6xmxo1sgww461.jpg","https://i.redd.it/e04r96pyu7661.jpg","https://i.redd.it/onv6ztoviia81.jpg","https://i.redd.it/9gmzytttqoz61.jpg","https://i.redd.it/qmi6atan2lw51.jpg","https://i.redd.it/wc2gn9zi68j81.jpg","https://i.redd.it/c7mu1mh0x3j81.jpg","https://i.redd.it/j6mseiw6fae51.jpg","https://i.redd.it/7bb8np8gd9341.jpg","https://i.redd.it/un7khlbn9p511.jpg","https://i.redd.it/uelrbrwoylb71.jpg","https://i.redd.it/zan3igrsyhe61.jpg","https://i.redd.it/zz5vhf9elwo51.jpg","https://i.redd.it/4k2jcjnu9jt61.jpg","https://i.redd.it/xostagonpk661.jpg","https://i.redd.it/zy1q562nsad51.jpg","https://i.redd.it/6tii7d8si6l51.jpg","https://i.redd.it/2gefr7z8jhk31.jpg","https://i.redd.it/v9j5oesxq7061.jpg","https://i.redd.it/kzrr5a1odty31.jpg","https://i.redd.it/cpnmvysw0v971.jpg","https://i.redd.it/qfhfj8lej5o31.jpg","https://i.redd.it/efivkxyyvau61.jpg","https://i.redd.it/im0h47syytp61.jpg","https://i.redd.it/mxnmde2ub4z41.jpg","https://i.redd.it/4woa9fqlmem81.jpg","https://i.redd.it/9q6yww7396h71.jpg","https://i.redd.it/rd0apaws6li71.jpg","https://i.redd.it/pquhc2vwkzi31.jpg","https://i.redd.it/omnzun6ck1c71.jpg","https://i.redd.it/i85e5rrnjze51.jpg","https://i.redd.it/6nauzstwtpz71.jpg","https://i.redd.it/azs0s9vsv5651.png","https://i.redd.it/yekcl9gh84m41.jpg","https://i.redd.it/rzw5wyyvhzm51.jpg","https://i.redd.it/5e8f00nykd351.jpg","https://i.redd.it/jvf0bavwidr51.jpg","https://i.redd.it/5cc6e70uuw071.jpg","https://i.redd.it/whijm0y3wm771.png","https://i.redd.it/vcr6hi6pdzj21.jpg","https://i.redd.it/jg0c505rkn031.jpg","https://i.redd.it/6r8i57hmzk151.jpg","https://i.redd.it/p953j6senj911.jpg","https://i.redd.it/ehm99ecd4hj31.jpg","https://i.redd.it/fyuj8gve8wv61.jpg","https://i.redd.it/hhzi0bohsux51.jpg","https://i.redd.it/nnt5h8uft8e71.jpg","https://i.redd.it/s1hkx7o3ish41.jpg","https://i.redd.it/pk1ync3eisd61.jpg","https://i.redd.it/ncixvdyv98ry.jpg","https://i.redd.it/f2kxutvlknt41.jpg","https://i.redd.it/5de989avicr61.jpg","https://i.redd.it/2vi4gig59xg61.jpg","https://i.redd.it/u0rw3lwc3eq51.jpg","https://i.redd.it/52zy9xfgzbe71.jpg","https://i.redd.it/3q8dt1x554d61.png","https://i.redd.it/tvt3pusbxzf51.png","https://i.redd.it/7jd7q7vj3uv61.jpg","https://i.redd.it/7mctpdtlyxj71.png","https://i.redd.it/gyp3t225yv771.png","https://i.redd.it/60pgr9krn3f61.jpg","https://i.redd.it/x85vmjyi9pm41.jpg","https://i.redd.it/zot5tf1px4s61.png","https://i.redd.it/hxr41ui0wua71.jpg","https://i.redd.it/hmntbgxuqrf71.jpg","https://i.redd.it/el8mrm7hb6l61.png","https://i.redd.it/uazqlebns0s61.jpg","https://i.redd.it/ai3p7lqsdza71.jpg","https://i.redd.it/ktn8uzhclfj31.jpg","https://i.redd.it/4ztf3ghst0551.jpg","https://i.redd.it/fmz9q8r7sq751.png","https://i.redd.it/gtuu82nfu4m51.jpg","https://i.redd.it/ca61jlh16t061.jpg","https://i.redd.it/xfuply7inyv41.jpg","https://i.redd.it/il2zmku6kws51.jpg","https://i.redd.it/0x3f9vzpdtl31.jpg","https://i.redd.it/3sxvu3rdz0e71.jpg","https://i.redd.it/sghsuxblrv121.jpg","https://i.redd.it/n64d18rzs3o11.jpg","https://i.redd.it/hxw9izutyly21.jpg","https://i.redd.it/ayqmdfh721561.jpg","https://i.redd.it/ukal69gn59541.jpg","https://i.redd.it/j9sisg2qpp961.jpg","https://i.redd.it/4o5sl7e9hsl11.jpg","https://i.redd.it/gbpgulwdzpj01.png","https://i.redd.it/idrqrrb22uq21.jpg","https://i.redd.it/uif309pkp8o41.jpg","https://i.redd.it/7ez4zax0oxe41.jpg","https://i.redd.it/v9ej47demvu71.jpg","https://i.redd.it/9khfanlv6td81.jpg","https://i.redd.it/84ntovzvc8l81.jpg","https://i.redd.it/320vwt255k741.jpg","https://i.redd.it/n7csnrox12u41.jpg","https://i.redd.it/yic7vl8aejw31.jpg","https://i.redd.it/84y8a6203t281.jpg","https://i.redd.it/mtoris57v0x21.jpg","https://i.redd.it/sxy849qiz7n61.jpg","https://i.redd.it/yog1jyhjf8z41.jpg","https://i.redd.it/s4b6svg4lxl51.jpg", "https://i.redd.it/hdk4b5xtuzn61.jpg", "https://i.redd.it/tgko381hb8v31.jpg","https://i.redd.it/8uacm87m29pz.jpg","https://i.redd.it/8z7s1nq3c8x51.jpg","https://i.redd.it/09fwaqmy4u861.jpg","https://i.redd.it/lly5zy9utgt51.jpg","https://i.redd.it/m3oj6bnvciw51.jpg","https://i.redd.it/kzqgzlf5dn671.jpg","https://i.redd.it/vrgnyz6t6d031.jpg","https://i.redd.it/n8pr3mcqcrp61.jpg","https://i.redd.it/2vwvsbvd4wk71.png","https://i.redd.it/h7g4vq7k2ua51.jpg","https://i.redd.it/pok5vf0oyw951.jpg","https://i.redd.it/cz4io1enf9u71.jpg","https://i.redd.it/yva1g21hud651.jpg","https://i.redd.it/ag6fy2rhlxy61.jpg","https://i.redd.it/q8dp44mi00j51.jpg","https://i.redd.it/3x4ts386p2o21.jpg","https://i.redd.it/uza17i9f4kf61.png","https://i.redd.it/0d9dc3843k351.jpg","https://i.redd.it/5wx9saod3an71.jpg","https://i.redd.it/wiher0wk9i971.jpg","https://i.redd.it/x74dmusde7d71.jpg","https://i.redd.it/lpyevf1h86m71.jpg","https://i.redd.it/d7mi2ht1f5e81.jpg","https://i.redd.it/1cfmqym7hgk31.jpg","https://i.redd.it/hff40ikq83yy.jpg","https://i.redd.it/jexqfabxjp101.jpg","https://i.redd.it/t4sy6nsm8k961.jpg","https://i.redd.it/dunc1rs1xen51.jpg","https://i.redd.it/uya09vdouco51.png","https://i.redd.it/vmp6ahqncjj71.jpg","https://i.redd.it/0y2qh0j1ipx51.jpg","https://i.redd.it/fzzh0503i1o41.jpg","https://i.redd.it/i2v0ewtw9td31.png","https://i.redd.it/967oyqgk45451.jpg","https://i.redd.it/4fm6k26yvet01.jpg","https://i.redd.it/ashh5e519w981.jpg","https://i.redd.it/u9buu31s1if41.jpg","https://i.redd.it/zs1xwvzfx6961.jpg","https://i.redd.it/n8qul0zl0c761.jpg","https://i.redd.it/pav1vhsi9lh81.jpg","https://i.redd.it/vne1mqo7fcb41.jpg","https://i.redd.it/frqsmby8wd961.jpg","https://i.redd.it/pafsyxk60yt51.jpg","https://i.redd.it/l6ruqz9k5yr41.jpg","https://i.redd.it/e8q0vcpiq1161.jpg","https://i.redd.it/bor84tyj94881.jpg","https://i.redd.it/9cljma8x5do51.jpg","https://i.redd.it/mlt6vezh62h71.jpg","https://i.redd.it/iz4lpfbcosy41.jpg","https://i.redd.it/6z31hza0eui51.jpg","https://i.redd.it/54cgeaqrrs461.jpg","https://i.redd.it/a8z6uua2nn021.jpg","https://i.redd.it/k0z8cdcongr71.jpg","https://i.redd.it/7o7kgcv9oip41.jpg","https://i.redd.it/6i547mkjjvu31.jpg","https://i.redd.it/bn8639lchue51.jpg","https://i.redd.it/ntsd1gl4l1z51.jpg","https://i.redd.it/jc1cf51xgg521.jpg","https://i.redd.it/dp0arkzf2fq41.jpg","https://i.redd.it/xcefk2s3dnl81.jpg","https://i.redd.it/bgxdyio9qs471.jpg","https://i.redd.it/f2rlgow542c51.png","https://i.redd.it/v7f2018phxz71.jpg","https://i.redd.it/mvgclpc9phw51.jpg"];
let nProcessed = 0;
for(let url of urls) {
let blob = await fetch(`https://temporary-restricted-cors-proxy.glitch.me?url=${url}`, {referrer:""}).then(r => r.blob());
blob = await bicubicResizeAndCenterCrop(blob);
const blobURL = URL.createObjectURL(blob);
const img = document.createElement('img');
img.src = blobURL;
img.title = url;
document.getElementById('output').appendChild(img);
console.log(nProcessed++, url);
}
console.log("FINISHED");
})();
async function bicubicResizeAndCenterCrop(blob) {
let im = vips.Image.newFromBuffer(await blob.arrayBuffer());
// Resize so smallest side is 224px:
let resizeFactor = 1;
if(im.width > im.height) {
resizeFactor = 224/im.height;
} else {
resizeFactor = 224/im.width;
}
im = im.resize(resizeFactor, {kernel:vips.Kernel.cubic});
// crop to 224x224:
let left = (im.width - 224)/2;
let top = (im.height - 224)/2;
im = im.crop(left, top, 224, 224)
let outBuffer = new Uint8Array(im.writeToBuffer('.png'));
return new Blob([outBuffer], { type: 'image/png' });
}
Here's the error I'm seeing in Chrome DevTools:
Aborted(OOM)
Pe @ vips.js?ad40afff8535a54512ad:1
Wa @ vips.js?ad40afff8535a54512ad:1
$func731 @ vips.wasm?ad40afff8535a54512ad:0x353b3
$mb @ vips.wasm?ad40afff8535a54512ad:0x9489
$func373 @ vips.wasm?ad40afff8535a54512ad:0x1930f
$func1635 @ vips.wasm?ad40afff8535a54512ad:0xb9d30
...
...
$func4883 @ vips.wasm?ad40afff8535a54512ad:0x281093
n.invokeEntryPoint @ vips.js?ad40afff8535a54512ad:1
self.onmessage @ vips.worker.js?ad40afff8535a54512ad:1
Show 47 more frames
vips.worker.js?ad40afff8535a54512ad:1 worker.js onmessage() captured an uncaught exception: RuntimeError: Aborted(OOM). Build with -s ASSERTIONS=1 for more info.
threadPrintErr @ vips.worker.js?ad40afff8535a54512ad:1
self.onmessage @ vips.worker.js?ad40afff8535a54512ad:1
vips.worker.js?ad40afff8535a54512ad:1 RuntimeError: Aborted(OOM). Build with -s ASSERTIONS=1 for more info.
at Pe (vips.js?ad40afff8535a54512ad:1:5312)
at Wa (vips.js?ad40afff8535a54512ad:1:79304)
at vips.wasm?ad40afff8535a54512ad:0x353b3
...
...
at vips.wasm?ad40afff8535a54512ad:0xa746
at r (vips.js?ad40afff8535a54512ad:1:81710)
threadPrintErr @ vips.worker.js?ad40afff8535a54512ad:1
self.onmessage @ vips.worker.js?ad40afff8535a54512ad:1
vips.js?ad40afff8535a54512ad:1 worker sent an error! https://wasm-vips.kleisauke.nl/lib/vips.worker.js?ad40afff8535a54512ad:1: Uncaught RuntimeError: Aborted(OOM). Build with -s ASSERTIONS=1 for more info.
t.onerror @ vips.js?ad40afff8535a54512ad:1
error (async)
ce @ vips.js?ad40afff8535a54512ad:1
(anonymous) @ vips.js?ad40afff8535a54512ad:1
e @ vips.js?ad40afff8535a54512ad:1
t @ vips.js?ad40afff8535a54512ad:1
Promise.then (async)
(anonymous) @ vips.js?ad40afff8535a54512ad:1
Promise.then (async)
(anonymous) @ vips.js?ad40afff8535a54512ad:1
(anonymous) @ vips.js?ad40afff8535a54512ad:1
(anonymous) @ playground-runner.html:104
vips.js?ad40afff8535a54512ad:1 Uncaught ErrorEvent {isTrusted: true, message: 'Uncaught RuntimeError: Aborted(OOM). Build with -s ASSERTIONS=1 for more info.', filename: 'https://wasm-vips.kleisauke.nl/lib/vips.worker.js?ad40afff8535a54512ad', lineno: 1, colno: 1925, …}
t.onerror @ vips.js?ad40afff8535a54512ad:1
error (async)
ce @ vips.js?ad40afff8535a54512ad:1
(anonymous) @ vips.js?ad40afff8535a54512ad:1
e @ vips.js?ad40afff8535a54512ad:1
t @ vips.js?ad40afff8535a54512ad:1
Promise.then (async)
(anonymous) @ vips.js?ad40afff8535a54512ad:1
Promise.then (async)
(anonymous) @ vips.js?ad40afff8535a54512ad:1
(anonymous) @ vips.js?ad40afff8535a54512ad:1
(anonymous) @ playground-runner.html:104
vips.worker.js?ad40afff8535a54512ad:1 Uncaught RuntimeError: Aborted(OOM). Build with -s ASSERTIONS=1 for more info.
at Pe (vips.js?ad40afff8535a54512ad:1:5312)
at Wa (vips.js?ad40afff8535a54512ad:1:79304)
at vips.wasm?ad40afff8535a54512ad:0x353b3
...
...
at vips.wasm?ad40afff8535a54512ad:0xa746
at r (vips.js?ad40afff8535a54512ad:1:81710)
Any idea what's happening here?
Was just looking at this library, to be used in my react app with typescript. turns out the type definition that comes with library are like
declare namespace vips { ... }
i.e. they are not exported. you need to export them so that the lib is usable in other TS projects.
export namespace vips
otherwise we get following error:
File 'x/node_modules/wasm-vips/lib/vips.d.ts' is not a module.ts(2306)
This works fine if I put it in my index.html
<script src="vips.js"></script>
<script type="module">
const vips = await Vips();
</script>
But how do I use the variable vips from a vue component?
Example
myVueComp.vue
template
stuff here....
template
export default {
name: 'SideNav',
setup() {
return {}
},
methods: {
updateStats() {
//In this method I want to access Vips
}
}
So in the updateStats method I want to access the const vips
variable I declared in my idex.html <script type="module"></script>
I have tried using the standard import * as Vips from 'wasm-vips' but it throws errors.
Any ideas?
Thanks,
Dan
See https://github.com/kleisauke/wasm-vips/projects/1 for things that should be done before we could declare a stable release.
Hello,
I'm trying to setup wasm-vips but I fail to do so. Given the following example:
<script type="module">
import Vips from './node_modules/wasm-vips/lib/vips-es6.js';
function resolved(result) {
console.log(result); // never displayed
}
function rejected(result) {
console.error(result); // never displayed
}
let prms = Vips();
prms.then(resolved, rejected);
console.log(prms); // is a pending Promise
setInterval(function(){
console.log(prms); // always pending
}, 2000)
</script>
Browser is Firefox 120.0.1 and index.html is served with those headers:
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
I'm a bit stuck, surely I did something wrong (I'm no full-time JS dev).
Any idea for me ?
On the command line --vips-progress
runs a progress indicator during computation. It can be useful to see where libvips is looping and how often.
I wonder if it's possible to expose progress in a similar way in wasm-vips, for example by adding an option to provide a callback function that gets called with the current progress. That way, if an operation takes a bit longer, one can display a progress bar to users as well.
Running the await Vips() snippet form the README on Deno results in the following:
Deno 1.32.1
exit using ctrl+d, ctrl+c, or close()
REPL is running with all permissions allowed.
To specify permissions, run `deno repl` with allow flags.
> import Vips from 'https://cdn.jsdelivr.net/npm/wasm-vips/lib/vips-es6.js';
undefined
> const vips = await Vips();
error: Uncaught (in worker "") TypeError: na is not a function
at https://cdn.jsdelivr.net/npm/wasm-vips/lib/vips-es6.js:116:217
at new Promise (<anonymous>)
at e (https://cdn.jsdelivr.net/npm/wasm-vips/lib/vips-es6.js:116:191)
at f (https://cdn.jsdelivr.net/npm/wasm-vips/lib/vips-es6.js:116:467)
at dd (https://cdn.jsdelivr.net/npm/wasm-vips/lib/vips-es6.js:117:361)
at https://cdn.jsdelivr.net/npm/wasm-vips/lib/vips-es6.js:118:327
There was an issue submitted to sharp
requesting support for wasm (see this issue).
In that issue, the author links to this repo (see this comment).
Is there a way to use wasm-vips
with the sharp
API? (probably needs ArrayBuffer input instead of file path)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.