silvia-odwyer / photon

⚡ Rust/WebAssembly image processing library
https://silvia-odwyer.github.io/photon
Apache License 2.0
2.72k stars 154 forks source link

photon usage on WebWorker #46

Open lu911 opened 4 years ago

lu911 commented 4 years ago

Hello, I want to use this library on Cloudflare workers. Cloudflare workers run on WebWorker environment.

I imported photon-rs on rust project and build with wasm-pack.

I get "RuntimeError: unreachable" error on some images converted into base64.

In docs, I saw an example utilizing canvas but are there other ways to store it on memory?

[Code]

const base64Encode = buf => {
  let string = '';
  (new Uint8Array(buf)).forEach(
    (byte) => {
      string += String.fromCharCode(byte)
    }
  );
  return btoa(string)
};

async function handleRequest(request) {
  const { PhotonImage } = wasm_bindgen;
  await wasm_bindgen(wasm);

  const url = `IMAGE_URL`;
  const headers = {};
  const originRequest = new Request(url, { headers: headers });
  const upstreamResponse = await fetch(originRequest);
  const base64 = base64Encode(await upstreamResponse.arrayBuffer());
  let data = base64.replace(/^data:image\/(png|jpg);base64,/, "");
  const image = PhotonImage.new_from_base64(data);
  return new Response('test', {status: 200})
}

[Error]

Uncaught (in promise)
RuntimeError: unreachable
    at <anonymous>:wasm-function[1829]:0x9b26a
    at <anonymous>:wasm-function[769]:0x7fc50
    at <anonymous>:wasm-function[1661]:0x99339
    at <anonymous>:wasm-function[1763]:0x9a7c9
    at <anonymous>:wasm-function[1120]:0x8dcfb
    at <anonymous>:wasm-function[499]:0x6e5a1
    at photonimage_new_from_base64 (<anonymous>:wasm-function[966]:0x88d97)
    at Function.new_from_base64 (worker.js:2618:24)
    at handleRequest (worker.js:3000:29)
Uncaught (in response)
Error: internal error
silvia-odwyer commented 4 years ago

Hi @YukSeungChan Thanks for submitting this issue! I've had a look at your code, and it appears that the issue is related to the manner in which you're fetching your image, since the result is encoded as a string rather than as a buffer.

I've coded a small example to help out. This issue has also cropped up for someone else, so I'll update the docs to include an example also.

await fetch(image_url)
    .then(data => data.buffer())
    .then(buffer => {
        let b64 = buffer.toString('base64'); 
        let photon_image = photon.PhotonImage.new_from_base64(b64);
        // photon.grayscale(photon_image);
    });

Hope this helps 😄 If you have any other questions, let me know!

lu911 commented 4 years ago

Thanks for the answer.

I can't use node-fetch. How can I encode the ArrayBuffer of Web API to base64 in the browser?

The code I wrote above doesn't work.

souravsaraf123 commented 3 years ago

I am not able to use this library in web workers 😥

Can you please show us a full example on how to achieve this. ( I am fairly new to wasm )

So far my index.html contains :

<html>
    <body>

        <h1>Demonstrates loading a local file using Photon on a WebWorker thread 2</h1>
        <p><input type="file" onchange="newFiles(this);" /></p>

        <script>

        async function newFiles(element)
        {
            for (var i=0; i<element.files.length; i++)
            {
                await readFileAndProcess(element.files[i]);
            }
        }

        async function readFileAndProcess(file)
        {
            let arrayBuffer = await file.arrayBuffer();

            const worker = new Worker('photon-worker.js', {
                type: 'module'
            });

            worker.onmessage = function(e)
            {
                var img = document.createElement("img");
                img.setAttribute("src", e.data);
                document.body.appendChild(img);
            };

            worker.postMessage(arrayBuffer);
        }

        </script>

    </body>
</html>

My photon-worker.js file contains :

// TODO: what to import here ?

self.addEventListener('message', e =>
{
    console.debug('event passed to web worker : ', e);
    console.debug('data passed to web worker : ', e.data);
    let arrayBuffer = e.data;

    // TODO: how to get photon object here , so that i can call the function photon.from_base64() here
});

Thanks 👍

dtruffaut commented 2 years ago

For converting buffer to dataUrl (b64), you can check: https://github.com/cloudflare/workerd/issues/54#issuecomment-1262659997

suragch commented 1 year ago

I tried creating a minimal project expressing the problem:

techwithdeo commented 1 year ago

I tried creating a minimal project expressing the problem:

Here is an example of using Photon Image Library on Cloudflare Workers: https://github.com/techwithdeo/cloudflare-workers

ccbikai commented 1 year ago

I tried creating a minimal project expressing the problem:

Here is an example of using Photon Image Library on Cloudflare Workers: https://github.com/techwithdeo/cloudflare-workers/tree/main/photon-library

Great Works! Can you publish as an npm package?

ccbikai commented 1 year ago

I tried creating a minimal project expressing the problem:

Here is an example of using Photon Image Library on Cloudflare Workers: https://github.com/techwithdeo/cloudflare-workers/tree/main/photon-library

Thanks, I deploy success

Support png: https://image.miantiao.me/?url=https%3A%2F%2Fstatic.miantiao.me%2Fbanner-big.jpeg&action=resize!820,400,1&format=png

Support jpg: https://image.miantiao.me/?url=https%3A%2F%2Fstatic.miantiao.me%2Fbanner-big.jpeg&action=resize!820,400,1&format=jpg

Support webp: https://image.miantiao.me/?url=https%3A%2F%2Fstatic.miantiao.me%2Fbanner-big.jpeg&action=resize!820,400,1&format=webp

techwithdeo commented 1 year ago

I tried creating a minimal project expressing the problem:

Here is an example of using Photon Image Library on Cloudflare Workers: https://github.com/techwithdeo/cloudflare-workers/tree/main/photon-library

Thanks, I deploy success

https://image.miantiao.me/?url=https%3A%2F%2Fstatic.miantiao.me%2Fbanner-big.jpeg&action=resize&options=820,400,1&format=png

https://image.miantiao.me/?url=https%3A%2F%2Fstatic.miantiao.me%2Fbanner-big.jpeg&action=resize&options=820,400,1&format=jpg

https://image.miantiao.me/?url=https%3A%2F%2Fstatic.miantiao.me%2Fbanner-big.jpeg&action=resize&options=820,400,1&format=webp

Glad to hear 😃

ccbikai commented 1 year ago

Support Watermark: https://image.miantiao.me/?url=https%3A%2F%2Fstatic.miantiao.me%2Fbanner-big.jpeg&action=watermark!https%3A%2F%2Fmt.ci%2Flogo.png,10,10 Support Pipe: https://image.miantiao.me/?url=https%3A%2F%2Fstatic.miantiao.me%2Fbanner-big.jpeg&action=resize!800,400,1|watermark!https%3A%2F%2Fmt.ci%2Flogo.png,10,10

techwithdeo commented 1 year ago

I

I tried creating a minimal project expressing the problem:

Here is an example of using Photon Image Library on Cloudflare Workers: https://github.com/techwithdeo/cloudflare-workers/tree/main/photon-library

Great Works! Can you publish as an npm package?

I published a npm package for cloudflare workers: https://www.npmjs.com/package/@cf-wasm/photon

techwithdeo commented 1 year ago

Support Watermark: https://image.miantiao.me/?url=https%3A%2F%2Fstatic.miantiao.me%2Fbanner-big.jpeg&action=watermark&options=https%3A%2F%2Fmt.ci%2Flogo.png,10,10 Support Pipe: https://image.miantiao.me/?url=https%3A%2F%2Fstatic.miantiao.me%2Fbanner-big.jpeg&pipe=resize!800,400,1|watermark!https%3A%2F%2Fmt.ci%2Flogo.png,10,10

Can you share the source code if you don't mind?

ccbikai commented 1 year ago

Support Watermark: https://image.miantiao.me/?url=https%3A%2F%2Fstatic.miantiao.me%2Fbanner-big.jpeg&action=watermark&options=https%3A%2F%2Fmt.ci%2Flogo.png,10,10 Support Pipe: https://image.miantiao.me/?url=https%3A%2F%2Fstatic.miantiao.me%2Fbanner-big.jpeg&pipe=resize!800,400,1|watermark!https%3A%2F%2Fmt.ci%2Flogo.png,10,10

Can you share the source code if you don't mind?

Let me sort it out this weekend

ccbikai commented 1 year ago

Support Watermark: https://image.miantiao.me/?url=https%3A%2F%2Fstatic.miantiao.me%2Fbanner-big.jpeg&action=watermark&options=https%3A%2F%2Fmt.ci%2Flogo.png,10,10 Support Pipe: https://image.miantiao.me/?url=https%3A%2F%2Fstatic.miantiao.me%2Fbanner-big.jpeg&pipe=resize!800,400,1|watermark!https%3A%2F%2Fmt.ci%2Flogo.png,10,10

Can you share the source code if you don't mind?

@suragch @techwithdeo Look Here https://github.com/ccbikai/cloudflare-worker-image

techwithdeo commented 1 year ago

Thank you :)

matbrgz commented 11 months ago

I tried creating a minimal project expressing the problem:

Here is an example of using Photon Image Library on Cloudflare Workers: https://github.com/techwithdeo/cloudflare-workers/tree/main/photon-library

Not working here :( Failed to compile. ▲ ./app/img/[collection]/[id]/photon/photon_rs_bg.wasm ▲ Module not found: Can't resolve 'wbg' ▲ ▲ https://nextjs.org/docs/messages/module-not-found ▲ ▲ Import trace for requested module: ▲ ./app/img/[collection]/[id]/photon/index.js ▲ ./app/img/[collection]/[id]/route.js ▲ ./node_modules/next/dist/build/webpack/loaders/next-edge-app-route-loader/index.js?absolutePagePath=private-next-app-dir%2Fimg%2F%5Bcollection%5D%2F%5Bid%5D%2Froute.js&page=%2Fimg%2F%5Bcollection%5D%2F%5Bid%5D%2Froute&appDirLoader=bmV4dC1hcHAtbG9hZGVyP25hbWU9YXBwJTJGaW1nJTJGJTVCY29sbGVjdGlvbiU1RCUyRiU1QmlkJTVEJTJGcm91dGUmcGFnZT0lMkZpbWclMkYlNUJjb2xsZWN0aW9uJTVEJTJGJTVCaWQlNUQlMkZyb3V0ZSZwYWdlUGF0aD1wcml2YXRlLW5leHQtYXBwLWRpciUyRmltZyUyRiU1QmNvbGxlY3Rpb24lNUQlMkYlNUJpZCU1RCUyRnJvdXRlLmpzJmFwcERpcj0lMkZob21lJTJGY29vcGVyJTJGZGV2JTJGbWV0YS11Y2xvY2slMkZhcHAmYXBwUGF0aHM9JTJGaW1nJTJGJTVCY29sbGVjdGlvbiU1RCUyRiU1QmlkJTVEJTJGcm91dGUmcGFnZUV4dGVuc2lvbnM9dHN4JnBhZ2VFeHRlbnNpb25zPXRzJnBhZ2VFeHRlbnNpb25zPWpzeCZwYWdlRXh0ZW5zaW9ucz1qcyZiYXNlUGF0aD0mYXNzZXRQcmVmaXg9Jm5leHRDb25maWdPdXRwdXQ9JnByZWZlcnJlZFJlZ2lvbj0mbWlkZGxld2FyZUNvbmZpZz1lMzAlM0Qh&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D! ▲ ▲ ./app/img/[collection]/[id]/pngs/pngs_bg.wasm ▲ Module not found: Can't resolve 'wbg' ▲ ▲ https://nextjs.org/docs/messages/module-not-found ▲ ▲ Import trace for requested module: ▲ ./app/img/[collection]/[id]/pngs/index.js ▲ ./app/img/[collection]/[id]/route.js ▲ ./node_modules/next/dist/build/webpack/loaders/next-edge-app-route-loader/index.js?absolutePagePath=private-next-app-dir%2Fimg%2F%5Bcollection%5D%2F%5Bid%5D%2Froute.js&page=%2Fimg%2F%5Bcollection%5D%2F%5Bid%5D%2Froute&appDirLoader=bmV4dC1hcHAtbG9hZGVyP25hbWU9YXBwJTJGaW1nJTJGJTVCY29sbGVjdGlvbiU1RCUyRiU1QmlkJTVEJTJGcm91dGUmcGFnZT0lMkZpbWclMkYlNUJjb2xsZWN0aW9uJTVEJTJGJTVCaWQlNUQlMkZyb3V0ZSZwYWdlUGF0aD1wcml2YXRlLW5leHQtYXBwLWRpciUyRmltZyUyRiU1QmNvbGxlY3Rpb24lNUQlMkYlNUJpZCU1RCUyRnJvdXRlLmpzJmFwcERpcj0lMkZob21lJTJGY29vcGVyJTJGZGV2JTJGbWV0YS11Y2xvY2slMkZhcHAmYXBwUGF0aHM9JTJGaW1nJTJGJTVCY29sbGVjdGlvbiU1RCUyRiU1QmlkJTVEJTJGcm91dGUmcGFnZUV4dGVuc2lvbnM9dHN4JnBhZ2VFeHRlbnNpb25zPXRzJnBhZ2VFeHRlbnNpb25zPWpzeCZwYWdlRXh0ZW5zaW9ucz1qcyZiYXNlUGF0aD0mYXNzZXRQcmVmaXg9Jm5leHRDb25maWdPdXRwdXQ9JnByZWZlcnJlZFJlZ2lvbj0mbWlkZGxld2FyZUNvbmZpZz1lMzAlM0Qh&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D! ▲ ▲ > Build failed because of webpack errors ▲ error Command failed with exit code 1.

I'm using Cloudflare Pages.

techwithdeo commented 10 months ago

@matbrgz

I recently updated @cf-wasm/photon, and now it supports Cloudflare Workers, Cloudflare Pages, Next.js and node environment.

Use @cf-wasm/photon for Next.js (Webpack) as shown:

import * as photon from "@cf-wasm/photon/next";
daggy1234 commented 10 months ago

Oh you should definetly add this as a feature to the README, do open a PR!

junteudjio commented 10 months ago

hi @techwithdeo @ccbikai , Thanks very much for posting your solutions. both work great!!! However, webp images become grayscale, any idea how to preserve the RGB colors for webp images? That would be very much appreciated. Thanks in advance.

fineshop commented 6 months ago

Web Workers (using Webpack bundler): https://github.com/fineshopdesign/cf-wasm/tree/main/packages/photon#web-worker or you can use esm.sh

Cloudflare Workers: https://github.com/fineshopdesign/cf-wasm/tree/main/packages/photon#cloudflare-workers

Next.js (App router + Edge Runtime): https://github.com/fineshopdesign/cf-wasm/tree/main/packages/photon#nextjs-app-router

Next.js (Pages router + Edge Runtime): https://github.com/fineshopdesign/cf-wasm/tree/main/packages/photon#nextjs-pages-router