jankovicsandras / imagetracerjs

Simple raster image tracer and vectorizer written in JavaScript.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Incompatible with images that lack alpha channel?

quinton-ashley opened this issue · comments

I'm using sharp to load images as a raw buffer. This works for images with an alpha channel. Images without an alpha channel won't cause imagetracerjs to throw errors but will produce svg files with colored dots at the top and black space. Could support for images without alpha channels be added or is there something I could do to make it work?

I'm trying to use imagetracerjs as part of a script that will batch process frames for video :)
ffmpeg video to frame outputs to the input directory frames without alpha channels

	let projDir = args[0];
	if (!fs.statSync(projDir).isDirectory()) {
		throw 'project must be a directory';
	}
	if (!fs.statSync(projDir + '/in').isDirectory()) {
		throw 'must contain input dir with og frames';
	}

	async function frameGenerator(file) {
		let img = sharp(file);
		const {
			data,
			info
		} = await img.raw().toBuffer({
			resolveWithObject: true
		});
		let imageData = {
			width: info.width,
			height: info.height,
			data: data
		};
		let svgstring = ImageTracer.imagedataToSVG(imageData, 'Detailed');
		file = path.parse(file);
		let svg = projDir + '/svg/' + file.name + '.svg';
		fs.outputFileSync(svg, svgstring);
		fs.ensureDirSync(projDir + '/out');

		await spawn('inkscape', [svg, '--export-png=' + projDir + '/out/' + file.name + '.png', '-b', '#000', '-h', (opt.h || 2160)], {
			stdio: 'inherit'
		});
	}

	let files = fs.readdirSync(projDir + '/in');
	files.forEach((file) => {
		frameGenerator(projDir + '/in/' + file);
	});

Hi,

ImageTracer uses ImageData , which has RGBA (8888 bit) buffer. The buffer you get from sharp might be only RGB, so the pixel addressing is wrong. Can you try to convert the buffer to srgb colorspace with sharp before tracing it? http://sharp.pixelplumbing.com/en/stable/api-colour/#tocolorspace

Thanks, I will look into it. It would be nice if image tracer could work for images without an alpha channel since I'm sure this would increase the processing speed of those images.

Colors are only used in colorquantization and the related samplepalette , samplepalette2 and generatepalette functions (and SVG rendering, but I think that would be fine with fixed alpha=255). I'm not sure there would be significant difference in speed processing RGB vs RGBA. But I suggest you forking, making these changes and giving me feedback.

Two types of changes are required:

  1. color component indexing should use * 3 (for RGB) instead of * 4 (for RGBA).
  2. color object alfa should be set to 255 {... a: 255 }

Here are the list of changes, but I haven't tested them:

Line 241

a: 255 };

Line 255

idx = (j*imgd.width+i)*3;

Line 262

cd = Math.abs(palette[k].r-imgd.data[idx]) + Math.abs(palette[k].g-imgd.data[idx+1]) + Math.abs(palette[k].b-imgd.data[idx+2]);

Line 273

paletteacc[ci].a += 255;

Line 292

idx = Math.floor( Math.random() * imgd.data.length / 3 ) * 3;

Line 293

palette.push({ r:imgd.data[idx ], g:imgd.data[idx+1], b:imgd.data[idx+2], a:255 });

Line 307

idx = Math.floor( ((j+1)*vy) * imgd.width + ((i+1)*vx) ) * 3;

Line 308

palette.push( { r:imgd.data[idx], g:imgd.data[idx+1], b:imgd.data[idx+2], a:255 } );

Line 340

for(rcnt=0; rcnt<rndnum; rcnt++){ palette.push({ r:Math.floor(Math.random()*255), g:Math.floor(Math.random()*255), b:Math.floor(Math.random()*255), a:255 }); }

I hope these worked, please reopen the issue, if not.