Different QRCode in series of flyer with photoshop

94 views Asked by At

i need to print many flyer in photoshop. One of layer of psd file is a QRCode. I'd like import multiple qrcode jpeg that i have in a folder, to generate flyer with different qrcode. Is it possible ? How ?

1

There are 1 answers

0
Francesco Bellavita On

I make this script for generate fast vector QRCode in Photoshop. If you link it to a data text file you can automate all process https://drive.google.com/file/d/0BxUg62Dv9J7ZTUpQb1pBNG9IbkU/view?usp=sharing

//Script by [email protected]
//This script draw a QR code whit path
//QR code matrix is generated by "qrcode.js" included script, search it whit google
#include "includes/qrcode.js" 
var mydoc = app.documents.add( 600, 600, 72, "tmp", NewDocumentMode.RGB, DocumentFill.WHITE );
var bianco = new SolidColor;
bianco.rgb.red = 255;
bianco.rgb.green = 255;
bianco.rgb.blue = 255;
bianco.rgbcol = new RGBColor;
bianco.rgbcol.hexValue = "FFFFFF";
var nero = new SolidColor;
nero.rgb.red = 0;
nero.rgb.green = 0;
nero.rgb.blue = 0;
nero.rgbcol = new RGBColor;
nero.rgbcol.hexValue = "000000";
//  FOR TESTING CLEAR DOCUMENT EVERY TEST
/*    mydoc.pathItems.removeAll();
    mydoc.selection.selectAll();
    mydoc.selection.fill(bianco.rgbcol,ColorBlendMode.NORMAL);
    mydoc.selection.deselect();*/

function disegnaQR(x,y,dim,contenuto){                //DRAW QR FUNCTION

    var qr = new QRCode(-1, QRErrorCorrectLevel.L)
    qr.addData(contenuto);
    qr.make();
    var qrcode = qr.modules; //qrcode is the matrix array of modules (squares) of QR. Values of modules can be false if white, true if black.
    var rs = parseInt(qrcode.length*qrcode.length); //Total number of modules
    var riga = Math.floor(qrcode.length) //modules in a row
    var s = Math.floor((mydoc.width/riga));   //s is the value of every square of the qr in points unit. Path works only in points
    var PPI = new Array(); //array of all qr paths point. Is an Array of closed paths.
    var puntiFatti = new Array(); //array of points already done by the script
    var punt = 0 //counter for PPI points, it reset every time a path is closed
    var numPath = 0; //counter for PPI closed paths
    var lineSubPathArray = new Array() //the array formatted for create every single subpath
    for (iy = 0; iy < riga+1; iy++) { //for loop for assign false value to every element of "puntifatti". It become a void clone of qrcode.
        puntiFatti[iy] = new Array
        for (var ix = 0; ix < riga+1; ix++){
            puntiFatti[iy][ix] = false
        }
    }
    for (var iy = 0; iy < riga; iy++) { //Loop trought all value of qr code column
        for (var ix = 0; ix < riga; ix++){ //Loop trought all value of qr code row

            bordo = calcolaBordo(ix,iy,riga); //"calcolabordo" function return where every square [ix,iy] is situated: if is at one border or at an angle.
                                            //It need for assign "false" value to square near the points that is not into the qrcode matrix. Example, first point in the top left
                                            //of the qr code,  is surrounded by only 1 square, the first top left. The function "combinazione" need to know the pattern of
                                            //all 4 square that surrounding every point; by the result of calcolabordo, function "combinazione" assign false to the "virtual" squares
                                            //bottom left, top left and top right because qrcode has not that value (qrcode[-1,0],qrcode[-1,-1],qrcode[-1,0]).
            controlloPrimo = combinazione (ix, 0, iy, 0, bordo, qrcode, false); //combinazione function returns the direction of the path calculated from the pattern of 4 modules (squares)
                                                                            //around the point iy,ix
            if (qrcode[ix][iy] == true && puntiFatti[ix][iy] == false//if the module value is true (black square), if it is not done (var puntiFatti),
            && controlloPrimo != "bianco" && controlloPrimo != "no"){//if around the point there are not 4 black square or 4 white square. (sorry for "no" instead "nero" :)
                PPI[numPath] = new Array(); //declares that PPI[numPath] is an array
                var _x = (ix * s) + x; //move the start point of this module from the left
                var _y = (iy * s) + y; //move the start point of this module from the right
                
                var partenzax = _x; //save the first point x (is used for determinate when path is closed)
                var partenzay = _y; //save the first point y (is used for determinate when path is closed)
                PPI[numPath][punt] = new PathPointInfo;                     //create first point of the "numPath" path in the PPI array
                PPI[numPath][punt].kind = PointKind.CORNERPOINT;            //create first point of the "numPath" path in the PPI array
                PPI[numPath][punt].anchor = [_x,_y];                        //create first point of the "numPath" path in the PPI array
                PPI[numPath][punt].leftDirection = PPI[numPath][punt].anchor;//create first point of the "numPath" path in the PPI array
                PPI[numPath][punt].rightDirection = PPI[numPath][punt].anchor;//create first point of the "numPath" path in the PPI array
                puntiFatti[ix][iy] = true;    //save the first point as done
                punt++; //increase point counter of PPI
                var xt = 0;    //used in the while loop that follow the path around all black square. increase if direction is right, decrease if direction is left
                var yt = 0;    //used in the while loop that follow the path around all black square. Increase if direction is down, decrease if direction is up
                var direzione = null;
                var chiuso = false;
                while(chiuso == false){ //while the path is not closed
                    bordo = calcolaBordo(ix+xt,iy+yt,riga);
                    direzione = combinazione(ix,xt,iy,yt,bordo,qrcode,false)
                    switch(direzione){ //this switch make every point of the path only if there is an angle. In this mode path has a lot less points
                        case "no": puntiFatti[ix+xt][iy+yt] = true; //This situation never occurs, but i add just for the devil :D
                                   chiuso = true;    //end the while loop
                                   PPI.splice(punt-1, 1); //remove last point (the first path point)
                        break;
                        case "su":  //case direction is up
                            var ultimaDirezione = "su"; //ultimaDirezione (lastdirection) is used in particular cases.
                            bordo = calcolaBordo(ix+xt,iy+yt-1,riga);
                            prossimaDirezione = combinazione(ix,xt,iy,yt,bordo,qrcode,direzione); //this go look the next direction to decide if make a point or not
                            if(prossimaDirezione == "su"){ //if the next direction is up again
                                puntiFatti[ix+xt][iy+yt-1] = true;//save the point as don but dont make it
                                yt = yt -1; //move the point to analyze
                            }
                            else{
                                PPI[numPath][punt] = new PathPointInfo; //create the point
                                PPI[numPath][punt].kind = PointKind.CORNERPOINT;
                                PPI[numPath][punt].anchor = [_x+(xt*s),_y+(yt*s)-s]; //position x,y-1
                                PPI[numPath][punt].leftDirection = PPI[numPath][punt].anchor;
                                PPI[numPath][punt].rightDirection = PPI[numPath][punt].anchor;
                                punt++;
                                puntiFatti[ix+xt][iy+yt-1] = true;//save the point as done
                                yt = yt - 1;
                            }
                        break;
                        case "dx":    //case direction is right
                            var ultimaDirezione = "dx";
                            bordo = calcolaBordo(ix+xt+1,iy+yt,riga);
                            prossimaDirezione = combinazione(ix,xt,iy,yt,bordo,qrcode,direzione);
                            if(prossimaDirezione == "dx"){
                                puntiFatti[ix+xt+1][iy+yt] = true;
                                xt = xt + 1;
                            }
                            else{
                                PPI[numPath][punt] = new PathPointInfo; 
                                PPI[numPath][punt].kind = PointKind.CORNERPOINT;
                                PPI[numPath][punt].anchor = [_x+(xt*s)+s,_y+(yt*s)];
                                PPI[numPath][punt].leftDirection = PPI[numPath][punt].anchor;
                                PPI[numPath][punt].rightDirection = PPI[numPath][punt].anchor;
                                punt++;
                                puntiFatti[ix+xt+1][iy+yt] = true;
                                xt = xt + 1;
                            }
                        break;
                        case "sx":    //case direction is left
                            var ultimaDirezione = "sx";
                            bordo = calcolaBordo(ix+xt-1,iy+yt,riga);
                            prossimaDirezione = combinazione(ix,xt,iy,yt,bordo,qrcode,direzione); 
                            if(prossimaDirezione == "sx"){
                                puntiFatti[ix+xt-1][iy+yt] = true;
                                xt = xt - 1;
                            }
                            else{
                                PPI[numPath][punt] = new PathPointInfo;
                                PPI[numPath][punt].kind = PointKind.CORNERPOINT;
                                PPI[numPath][punt].anchor = [_x+(xt*s)-s,_y+(yt*s)];
                                PPI[numPath][punt].leftDirection = PPI[numPath][punt].anchor;
                                PPI[numPath][punt].rightDirection = PPI[numPath][punt].anchor;
                                punt++;
                                puntiFatti[ix+xt-1][iy+yt] = true;
                                xt = xt - 1;
                            }
                        break;
                        case "giu":    //case direction is down
                            var ultimaDirezione = "giu";
                            bordo = calcolaBordo(ix+xt,iy+yt+1,riga);
                            prossimaDirezione = combinazione(ix,xt,iy,yt,bordo,qrcode,direzione);
                            if(prossimaDirezione == "giu"){
                                puntiFatti[ix+xt][iy+yt+1] = true;
                                yt = yt + 1;
                            }
                            else{
                                PPI[numPath][punt] = new PathPointInfo;
                                PPI[numPath][punt].kind = PointKind.CORNERPOINT;
                                PPI[numPath][punt].anchor = [_x+(xt*s),_y+(yt*s)+s];
                                PPI[numPath][punt].leftDirection = PPI[numPath][punt].anchor;
                                PPI[numPath][punt].rightDirection = PPI[numPath][punt].anchor;
                                punt++;
                                puntiFatti[ix+xt][iy+yt+1] = true;
                                yt = yt + 1;
                            }
                        break;
                        case "sugiu":    //case direction is up/down... hard to explain. Often the pattern has, in clockwise order, black white black white square.
                                        //in this cases "ultimaDirezione" is used to know the next direction.
                            switch(ultimaDirezione){
                                case "dx":
                                    var ultimaDirezione = "giu";
                                    bordo = calcolaBordo(ix+xt,iy+yt+1,riga);
                                    prossimaDirezione = combinazione(ix,xt,iy,yt,bordo,qrcode,ultimaDirezione);
                                    if(prossimaDirezione == "giu"){
                                        puntiFatti[ix+xt][iy+yt+1] = true;
                                        yt = yt + 1;
                                    }
                                    else{
                                        PPI[numPath][punt] = new PathPointInfo;
                                        PPI[numPath][punt].kind = PointKind.CORNERPOINT;
                                        PPI[numPath][punt].anchor = [_x+(xt*s),_y+(yt*s)+s];
                                        PPI[numPath][punt].leftDirection = PPI[numPath][punt].anchor;
                                        PPI[numPath][punt].rightDirection = PPI[numPath][punt].anchor;
                                        punt++;
                                        puntiFatti[ix+xt][iy+yt+1] = true;
                                        yt = yt + 1;
                                    }
                                break;
                                case "sx":
                                    var ultimaDirezione = "su";
                                    bordo = calcolaBordo(ix+xt,iy+yt-1,riga);
                                    prossimaDirezione = combinazione(ix,xt,iy,yt,bordo,qrcode,ultimaDirezione);
                                    if(prossimaDirezione == "su"){
                                        puntiFatti[ix+xt][iy+yt-1] = true;
                                        yt = yt -1;
                                    }
                                    else{
                                        PPI[numPath][punt] = new PathPointInfo;
                                        PPI[numPath][punt].kind = PointKind.CORNERPOINT;
                                        PPI[numPath][punt].anchor = [_x+(xt*s),_y+(yt*s)-s];
                                        PPI[numPath][punt].leftDirection = PPI[numPath][punt].anchor;
                                        PPI[numPath][punt].rightDirection = PPI[numPath][punt].anchor;
                                        punt++;
                                        puntiFatti[ix+xt][iy+yt-1] = true;
                                        yt = yt - 1;
                                    }
                                break;
                            }
                        break;
                        case "sxdx":
                            switch(ultimaDirezione){
                                case "su":
                                    var ultimaDirezione = "dx";
                                    bordo = calcolaBordo(ix+xt+1,iy+yt,riga);
                                    prossimaDirezione = combinazione(ix,xt,iy,yt,bordo,qrcode,ultimaDirezione); //va a vedere la prossima direzione
                                    if(prossimaDirezione == "dx"){ //se la direzione prevista per il prossimo punto รจ sempre dx
                                        puntiFatti[ix+xt+1][iy+yt] = true;//salva il punto come fatto e non lo scrive
                                        xt = xt + 1;
                                    }
                                    else{
                                        PPI[numPath][punt] = new PathPointInfo; //fa il puntio
                                        PPI[numPath][punt].kind = PointKind.CORNERPOINT;
                                        PPI[numPath][punt].anchor = [_x+(xt*s)+s,_y+(yt*s)]; //posizione x+1,y
                                        PPI[numPath][punt].leftDirection = PPI[numPath][punt].anchor;
                                        PPI[numPath][punt].rightDirection = PPI[numPath][punt].anchor;
                                        punt++;
                                        puntiFatti[ix+xt+1][iy+yt] = true;//salva il punto come fatto
                                        xt = xt + 1;
                                    }
                                break;
                                case "giu":
                                    var ultimaDirezione = "sx";
                                    bordo = calcolaBordo(ix+xt-1,iy+yt,riga);
                                    prossimaDirezione = combinazione(ix,xt,iy,yt,bordo,qrcode,ultimaDirezione);
                                    if(prossimaDirezione == "sx"){
                                        bordo = calcolaBordo(ix+xt+1,iy+yt+1,riga);
                                        switch(bordo){ //this is a special case.... very very hard to explain. it happend whe there are a single black square
                                                      //bottom right where the path go down then go left. Without this switch the single square topleft point
                                                      //become done and then, when the iy,ix value is thath square, the script jump it because its done....
                                                      //sorry is difficult to explain in english!! Leave this switch and see what append :D
                                            case "dx":
                                                if(qrcode[ix+xt][iy+yt] == true && qrcode[ix+xt][iy+yt+1] == false){
                                                    puntiFatti[ix+xt][iy+yt] = false;
                                                }
                                            break;
                                            case "giu":
                                                if(qrcode[ix+xt][iy+yt] == true && qrcode[ix+xt+1][iy+yt] == false){
                                                    puntiFatti[ix+xt][iy+yt] = false;
                                                }
                                            break;
                                            case "dxgiu":
                                                if(qrcode[ix+xt][iy+yt] == true){
                                                    puntiFatti[ix+xt][iy+yt] = false;
                                                }
                                            break;
                                            default:
                                                if(qrcode[ix+xt][iy+yt] == true && qrcode[ix+xt][iy+yt+1] == false && qrcode[ix+xt+1][iy+yt] == false){
                                                    puntiFatti[ix+xt][iy+yt] = false;
                                                }
                                            break;
                                        }
                                        puntiFatti[ix+xt-1][iy+yt] = true;
                                        xt = xt - 1;
                                    }
                                    else{
                                        PPI[numPath][punt] = new PathPointInfo;
                                        PPI[numPath][punt].kind = PointKind.CORNERPOINT;
                                        PPI[numPath][punt].anchor = [_x+(xt*s)-s,_y+(yt*s)];
                                        PPI[numPath][punt].leftDirection = PPI[numPath][punt].anchor;
                                        PPI[numPath][punt].rightDirection = PPI[numPath][punt].anchor;
                                        punt++;
                                        bordo = calcolaBordo(ix+xt+1,iy+yt+1,riga);
                                        switch(bordo){
                                            case "dx":
                                                if(qrcode[ix+xt][iy+yt] == true && qrcode[ix+xt][iy+yt+1] == false){
                                                    puntiFatti[ix+xt][iy+yt] = false;
                                                }
                                            break;
                                            case "giu":
                                                if(qrcode[ix+xt][iy+yt] == true && qrcode[ix+xt+1][iy+yt] == false){
                                                    puntiFatti[ix+xt][iy+yt] = false;
                                                }
                                            break;
                                            case "dxgiu":
                                                if(qrcode[ix+xt][iy+yt] == true){
                                                    puntiFatti[ix+xt][iy+yt] = false;
                                                }
                                            break;
                                            default:
                                                if(qrcode[ix+xt][iy+yt] == true && qrcode[ix+xt][iy+yt+1] == false && qrcode[ix+xt+1][iy+yt] == false){
                                                    puntiFatti[ix+xt][iy+yt] = false;
                                                }
                                            break;
                                        }
                                        puntiFatti[ix+xt-1][iy+yt] = true;
                                        xt = xt - 1;
                                    }
                                break;
                            }
                        break;
                    }
                    if(xt==0 && yt==0){chiuso = true; ultimaDirezione = "su";} //when xt and yt return to 0 the path is closed. "ultimaDirezione" is set to up
                }

                lineSubPathArray[numPath] = new SubPathInfo(); //create subpathinfo
                lineSubPathArray[numPath].closed = true;
                lineSubPathArray[numPath].operation = ShapeOperation.SHAPEXOR;
                lineSubPathArray[numPath].entireSubPath = PPI[numPath];
                numPath++; //increase numPath counter
                punt = 0; //reset point counter
            }
        }
    }
    var myPathItem = mydoc.pathItems.add("pathname", lineSubPathArray); //when all the paths of qr code are drawed it add the path to photoshop document
    myPathItem.fillPath(bianco, ColorBlendMode.DIFFERENCE,100,true,0,true,true) //and fill it of white in difference.
    //mydoc.pathItems.removeAll(); //uncomment for remove all paths when the work is done
    function calcolaBordo(ix,iy,riga){
        if(iy == 0 && ix == 0)       {return "sxsu";}//
        if(iy == 0 && ix == riga)    {return "dxsu";}//
        if(iy == riga && ix == riga) {return "dxgiu";}//
        if(iy == riga && ix == 0)    {return "sxgiu";}//
        if(iy == 0 && ix != 0 && ix != riga)    {return "su";}//
        if(iy != 0 && ix == riga && iy != riga) {return "dx";}//
        if(iy == riga && ix != 0 && ix != riga) {return "giu";}//
        if(ix == 0 && iy != 0 && iy != riga)    {return "sx";}//
        if(ix =! 0 && iy !=0 && ix != riga && iy != riga){return "no";}//    
    }
    
    function combinazione(ix,xt,iy,yt,bordo,qrcode,direzione){
        switch (direzione){ //switch the point to analyze in base of the direction. in this mode the function can analyze the 4 point near ix,iy to determinate next direction
            case false: var px = 0; var py = 0; break;
            case "su": var px = 0; var py = -1; break;
            case "giu": var px = 0; var py = 1; break;
            case "sx": var px = -1; var py = 0; break;
            case "dx": var px = 1; var py = 0;  break;
        }
        switch (bordo){ //assign the value of the squares around the ix,iy point.
                       //if the point is at a border or at an angle, the squares that is out the qrcode matrix assume false value
            case "sxsu": 
                var a = false;
                var b = false;
                var c = qrcode[ix+xt+px][iy+yt+py];
                var d = false;
            break;
            case "dxsu": 
                var a = false;
                var b = false;
                var c = false;
                var d = qrcode[ix+xt-1+px][iy+yt+py];
            break;
            case "dxgiu":
                var a = qrcode[ix+xt-1+px][iy+yt-1+py];
                var b = false;
                var c = false;
                var d = false;
            break;
            case "sxgiu":
                var a = false;
                var b = qrcode[ix+xt+px][iy+yt-1+py];
                var c = false;
                var d = false;
            break;
            case "su":
                var a = false;
                var b = false;
                var c = qrcode[ix+xt+px][iy+yt+py];
                var d= qrcode[ix+xt-1+px][iy+yt+py];
            break;
            case "dx":
                var a = qrcode[ix+xt-1+px][iy+yt-1+py];
                var b = false;
                var c = false;
                var d = qrcode[ix+xt-1+px][iy+yt+py];
            break;
            case "giu":
                var a = qrcode[ix+xt-1+px][iy+yt-1+py];
                var b = qrcode[ix+xt+px][iy+yt-1+py];
                var c = false;
                var d = false;
            break;
            case "sx":
                var a = false;
                var b = qrcode[ix+xt+px][iy+yt-1+py];
                var c = qrcode[ix+xt+px][iy+yt+py];
                var d = false; 
            break;
            case "no":
                var a = qrcode[ix+xt-1+px][iy+yt-1+py];
                var b = qrcode[ix+xt+px][iy+yt-1+py];
                var c = qrcode[ix+xt+px][iy+yt+py];
                var d = qrcode[ix+xt-1+px][iy+yt+py];
        }
        //this is the patterns used for know the direction of the path
        if(a == true && b == true && c == true && d == true){return "no"}//A
    
        if(a == false && b == true && c == true && d == true){return "su"}//B
        if(a == true && b == false && c == true && d == true){return "dx"}//C
        if(a == true && b == true && c == false && d == true){return "giu"}//D
        if(a == true && b == true && c == true && d == false){return "sx"}//E
    
        if(a == false && b == false && c == true && d == true){return "dx"}//F
        if(a == true && b == false && c == false && d == true){return "giu"}//G
        if(a == true && b == true && c == false && d == false){return "sx"}//H
        if(a == false && b == true && c == true && d == false){return "su"}//I
    
        if(a == false && b == false && c == false && d == true){return "giu"}//L
        if(a == true && b == false && c == false && d == false){return "sx"}//M
        if(a == false && b == true && c == false && d == false){return "su"}//N
        if(a == false && b == false && c == true && d == false){return "dx"}//O
        
        if(a == false && b == true && c == false && d == true){return "sugiu"}//P
        if(a == true && b == false && c == true && d == false){return "sxdx"}//Q
        if(a == false && b == false && c == false && d == false){return "bianco"}//R
    }

}
var testoQR = prompt("testoQR","qrcode for photoshop by Fr4nZ82");    
disegnaQR(0,0,600,testoQR);

/*This is the pattern explained. Imagine the point is in the center surrounded by the for square.
  Depend on pattern the script decides where to move
        legend: # = black square
                0 = white square

##    0#    #0    ##    ##    00    #0    ##    0#    00    #0    0#    00    0#       #0     00
##    ##    ##    #0    0#    ##    #0    00    0#    #0    00    00    0#    #0       0#     00
A     B     C     D     E     F     G     H     I     L     M     N     O     P        Q      R
no    up    right down  left  right down  left  up    down  left  up    right up/down  lf/rg  white(no)*/