Outils pour utilisateurs


Pixel 2 Vector

Convertir une image en un ensemble de hachures vectorielles à passer au plotter.

TODO commenter, boite de dialoge choix de fichier, parametres sur l'UI.

px2vector.pde

import java.util.*;

long MAX_LEVEL = 195075;
long HIGH_LEVEL = 194000;
long LOW_LEVEL = 0;
long CLEAR_LEVEL = 10;

int LEVEL_DIV = 16;
long SUB = (long) Math.round((HIGH_LEVEL - LOW_LEVEL)/LEVEL_DIV);

float ANGLE = QUARTER_PI+QUARTER_PI/4;

PImage image;
int[] mix;

List<PVector> starts = new ArrayList();
List<PVector> ends = new ArrayList();

void setup(){
	size(1920,1080);
	// surface.setResizable(true);
	image = loadImage("test.png");

	mix = mixup();
	strokeWeight(0.3);


	for(int i = 0; i < LEVEL_DIV; i ++){
		println("mix["+ i +"]: "+ mix[i]);
	}

	starts = new ArrayList();
	ends = new ArrayList();


	for(int i = 0; i < image.width; i ++){
		ray(i, 0);
	}
	for(int i = image.height; i >= 0; i --){
		ray(0, i);
	}

	saveSvg();
}


void draw(){

	if(mousePressed){
		exit();
		
	}

	stroke(0XFF000000);
	int index = 0;
	for(PVector s : starts){
		PVector e = ends.get(index);
		line(s.x, s.y, e.x, e.y);
		index ++;
	}

}

void ray(int x, int y){
	long RAY_LEVEL = LOW_LEVEL + mix[Math.max(x, y) % LEVEL_DIV]*SUB;
	boolean started = false;
	while(x < image.width && y < image.height){
		x += Math.round(Math.cos(ANGLE)*Math.tan(ANGLE));
		y += Math.round(Math.sin(ANGLE)*Math.tan(ANGLE));
		long pixlv = pipette(x, y);
		if((pixlv < RAY_LEVEL && pixlv > CLEAR_LEVEL) && !started){
			started = true;
			starts.add(new PVector(x, y));
		}else if((pixlv > RAY_LEVEL || pixlv < CLEAR_LEVEL) && started){
			started = false;
			ends.add(new PVector(x, y));
		}	
	}
	if(started){
		started = false;
		ends.add(new PVector(x, y));	
	}
}

/* return level of pixel x;y from 0 to 195075

	195075 = 3 * ( 255 ^ 2 )
	
*/

long pipette(int x, int y){
	int rsc = image.get(x, y);
	long trueLevel = (long) sq(red(rsc));
	trueLevel += (long) sq(green(rsc));
	trueLevel += (long) sq(red(rsc));

	return trueLevel;
}

/*  */

int[] mixup(){
	int[] mix = new int [LEVEL_DIV];
	int middle = ceil(LEVEL_DIV / 2);
	boolean dir = LEVEL_DIV % 2 == 0;
	int offset = 0;

	for(int i = 0; i < LEVEL_DIV; i ++){
		if(dir){
			mix[i] = middle + offset;
			dir = !dir;
		}else{
			mix[i] = offset;
			offset ++;
			dir = !dir;
		}
	}

	return mix;
}

void saveSvg(){
	int index = 0;

	String svg = "<svg width='"+ image.width +"' height='"+ image.height +"' viewBox='0 0 "+ image.width +" "+ image.height +"' xmlns='http://www.w3.org/2000/svg'>\n";
	
	for(PVector s : starts){
		PVector e = ends.get(index);
		svg+="<line x1='"+s.x+"' y1='"+s.y+"' x2='"+e.x+"' y2='"+e.y+"' stroke-width='0.5' stroke='black'/>\n";
		index ++;
	}
	svg +="</svg>";


	PrintWriter output = createWriter("positions.svg");
	output.print(svg);
	output.flush(); 
	output.close();
}