photon icon indicating copy to clipboard operation
photon copied to clipboard

Create image using Blob

Open garygreen opened this issue 3 years ago • 13 comments

At the moment it seems photon relies on loading an image into a canvas in order to then pass onto photon.

Isn't this inefficent and potentially causes loss of quality?

open_image | Convert a HTML5 Canvas Element to a PhotonImage.

Is there any way to pass just a raw Blob to photon and have it pass that onto the WASM for decoding + transforming, etc? This would be useful for image uploads where you can receive a blob file.

Loading onto a canvas seems like an unnecessary transformation/step...

garygreen avatar Dec 04 '20 16:12 garygreen

Atm blob loading is not supported.

daggy1234 avatar Dec 05 '20 16:12 daggy1234

@silvia-odwyer any thoughts on this? Would this be easy to add or is it not so straight forward?

garygreen avatar May 05 '21 00:05 garygreen

@garygreen This is definitely a feature I'd like to add, and is in the works. I'm currently working on adding functionality which converts a Buffer to a PhotonImage as well as ArrayBuffers, and once this is implemented, support can then be added for Blobs too.

silvia-odwyer avatar May 05 '21 00:05 silvia-odwyer

@silvia-odwyer woahh that's awsome dude! I really would love to use this program on our site, so once this is added can't wait to give it a try 😁

garygreen avatar May 05 '21 14:05 garygreen

@garygreen If you need this functionality quickly (and since using file Blobs w/ photon is still in development), I'd recommend image-blob-reduce for this, it's a library which uses WebAssembly to resize photos also! It's definitely worth trying out, and is incredibly performant overall. https://github.com/nodeca/image-blob-reduce

silvia-odwyer avatar May 06 '21 03:05 silvia-odwyer

we do have support for just raw bytes, so you could hypothetically do something. I think the Buffer might work. Someone would have to try it tho.

daggy1234 avatar May 07 '21 14:05 daggy1234

@silvia-odwyer thanks for the recommendation. I did check out that library which uses pica under the hood - this is a pure javascript library and doesn't use wasm. I think there was issues when we were trying it as well, for example it didn't support EXIF orientation markers / rotations out the box. Overall it seemed like a poor fit for our use case, so wondered if phonton being a proper WASM and resize support etc would be a better choice.

@Daggy1234 hmm interesting. Do you mind setting up a code sample on Codepen or something?

garygreen avatar May 07 '21 14:05 garygreen

Sure I'll definitely put something together by the end of the week!

daggy1234 avatar May 12 '21 20:05 daggy1234

Just wondering if there's any updates on this? :)

bentron2000 avatar Apr 22 '22 09:04 bentron2000

Oh so sorry! I got caught up with stuff. I'll try something this weekend 100%

daggy1234 avatar Apr 22 '22 12:04 daggy1234

I have something rudimentary working, I'll finetune and make a PR soon!

daggy1234 avatar Apr 29 '22 08:04 daggy1234

Once #121 is merged you should be able to use blobs. Ex:

Opening Blob:

import fs from 'fs';
import photon from "@silvia-odwyer/photon-node";
import fetch from 'node-fetch';


async function process() {
const img = await fetch("https://daggy.tech/daggy.png");
const blolb = await img.blob();
const array_buff = await blolb.arrayBuffer();
let data = new Uint8Array(array_buff);
var phtn_img = photon.PhotonImage.new_from_byteslice(data)
photon.grayscale(phtn_img);
}
process().then(() => console.log("done"));

Once the export bytes function is added, you can write the produced buffer to a file.

daggy1234 avatar Apr 30 '22 12:04 daggy1234

Final example once #125 is merged

import fs from 'fs';
import photon from "photon-rs";
import fetch from 'node-fetch';


async function process() {

	// Fetch imaage and get blob
	const img = await fetch("https://daggy.tech/daggy.png");
	const blolb = await img.blob();

	// Blob into array buffer and Uint8array for photon
	const array_buff = await blolb.arrayBuffer();
	let data = new Uint8Array(array_buff);

	// Photon Open and Process
	var phtn_img = photon.PhotonImage.new_from_byteslice(data)
	photon.grayscale(phtn_img);

	// Get Bytes
	const output_image_name = "outputa.png";
	const byt = phtn_img.get_bytes();

	// Write to file
	fs.createWriteStream(output_image_name).write(Buffer.from(byt));
	console.log(`Saved ${output_image_name}`);

}

process().then(() => console.log("done"));

daggy1234 avatar May 02 '22 12:05 daggy1234