• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

QRCode too slow to generate. There are alternative methods?

Community Beginner ,
Sep 11, 2015 Sep 11, 2015

Copy link to clipboard

Copied

Hi, i write a code for make a QR code.

First i write it using selection... this is the relevant part:

  for (var iy = 0; iy < riga; iy++){ //riga is the number of modules in a row of the QR

       for (var ix = 0; ix < riga; ix++){ //QR is a square, same modules in a columns

            if (qrcode[ix][iy] == true){  //qrcode is an array of an array... a matrix where the value is true if the square in that position is black

                 var _x = ix * s;     //s is the size of qr code little squares unit, in this case its value is 8 pixel

                 var _y = iy * s;

                 selectedRegion =

                 [

                 [_x + 0 + x, _y + 0 + y],

                 [_x + 0 + x, _y + s + y],

                 [_x + s + x, _y + s + y],

                 [_x + s + x, _y + 0 + y]

                 ];

                 //Add to selection

                 mydoc.selection.select(selectedRegion, SelectionType.EXTEND);

            }

       }

  }

  //Fill selection with solid color

  var squareColor = new RGBColor;

  squareColor.hexValue = "000000";

  mydoc.selection.fill(squareColor);

  mydoc.selection.deselect();

This work, but is very slow because it must create a selection square for more than 3000 times.

Now i'm trying to use path and crate all the path before drawing it in the document.

This is the code, but no work

/*
var lineArray = [];
var arrn = 0

    for (iy = 0; iy < riga; iy++) {

for (var ix = 0; ix < riga; ix++){
if (qrcode[ix][iy] == true){
var _x = ix * s;
var _y = iy * s;
for (i=0;i<4;i++){
//alert(ix)
//alert(i)
lineArray[arrn+i] = new PathPointInfo;
lineArray[arrn+i].kind = PointKind.CORNERPOINT;
switch(i){
case 0: lineArray[arrn+i].anchor = [ parseInt(x + _x) , parseInt(y + _y)];
break;
case 1: lineArray[arrn+i].anchor = [ parseInt(x + _x ), parseInt(y + _y + s)];
break;
case 2: lineArray[arrn+i].anchor = [ parseInt(x + _x + s) , parseInt(y + _y + s)];
break;
case 3: lineArray[arrn+i].anchor = [ parseInt(x + _x + s) , parseInt(y + _y)];
break;
}
//alert(lineArray[arrn+i].anchor)
lineArray[arrn+i].leftDirection = lineArray[arrn+i].anchor;
lineArray[arrn+i].rightDirection = lineArray[arrn+i].anchor;
}
//alert(arrn)
arrn = arrn + 4;
}
}
    }

    var lineSubPathArray = new SubPathInfo();

    lineSubPathArray.closed = true;

    lineSubPathArray.operation = ShapeOperation.SHAPEADD;

    lineSubPathArray.entireSubPath = lineArray;

    var myPathItem = mydoc.pathItems.add("myPath", [lineSubPathArray]);*/

the error is parameter not valid in the last row. I know that it is incomplete because diagonal lines from a square to another...

i want only know if is possible or you have any idea to make this qr code generation more fast.. whit any method

Sorry for my poor english!

TOPICS
Actions and scripting

Views

1.3K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 2 Correct answers

Community Beginner , Sep 20, 2015 Sep 20, 2015

I answer myself.

This work fine

//Script by Fr4nZ82@gmail.com

//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;

...

Votes

Translate

Translate
Community Beginner , Aug 02, 2021 Aug 02, 2021

script

 

qrcode.js:

//---------------------------------------------------------------------
// QRCode for JavaScript
//
// Copyright (c) 2009 Kazuhiko Arase
//
// URL: http://www.d-project.com/
//
// Licensed under the MIT license:
//   http://www.opensource.org/licenses/mit-license.php
//
// The word "QR Code" is registered trademark of 
// DENSO WAVE INCORPORATED
//   http://www.denso-wave.com/qrcode/faqpatent-e.html
//
//---------------------------------------------------------------------

/
...

Votes

Translate

Translate
Adobe
Community Beginner ,
Sep 20, 2015 Sep 20, 2015

Copy link to clipboard

Copied

I answer myself.

This work fine

//Script by Fr4nZ82@gmail.com

//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 😄

                                   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 😄

                                            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)*/

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Aug 02, 2021 Aug 02, 2021

Copy link to clipboard

Copied

script

 

qrcode.js:

//---------------------------------------------------------------------
// QRCode for JavaScript
//
// Copyright (c) 2009 Kazuhiko Arase
//
// URL: http://www.d-project.com/
//
// Licensed under the MIT license:
//   http://www.opensource.org/licenses/mit-license.php
//
// The word "QR Code" is registered trademark of 
// DENSO WAVE INCORPORATED
//   http://www.denso-wave.com/qrcode/faqpatent-e.html
//
//---------------------------------------------------------------------

//---------------------------------------------------------------------
// QR8bitByte
//---------------------------------------------------------------------

function QR8bitByte(data) {
	this.mode = QRMode.MODE_8BIT_BYTE;
	this.data = data;
}

QR8bitByte.prototype = {

	getLength : function(buffer) {
		return this.data.length;
	},
	
	write : function(buffer) {
		for (var i = 0; i < this.data.length; i++) {
			// not JIS ...
			buffer.put(this.data.charCodeAt(i), 8);
		}
	}
};

//---------------------------------------------------------------------
// QRCode
//---------------------------------------------------------------------

function QRCode(typeNumber, errorCorrectLevel) {
	this.typeNumber = typeNumber;
	this.errorCorrectLevel = errorCorrectLevel;
	this.modules = null;
	this.moduleCount = 0;
	this.dataCache = null;
	this.dataList = new Array();
}

QRCode.prototype = {
	
	addData : function(data) {
		var newData = new QR8bitByte(data);
		this.dataList.push(newData);
		this.dataCache = null;
	},
	
	isDark : function(row, col) {
		if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
			throw new Error(row + "," + col);
		}
		return this.modules[row][col];
	},

	getModuleCount : function() {
		return this.moduleCount;
	},
	
	make : function() {
		// Calculate automatically typeNumber if provided is < 1
		if (this.typeNumber < 1 ){
			var typeNumber = 1;
			for (typeNumber = 1; typeNumber < 40; typeNumber++) {
				var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel);

				var buffer = new QRBitBuffer();
				var totalDataCount = 0;
				for (var i = 0; i < rsBlocks.length; i++) {
					totalDataCount += rsBlocks[i].dataCount;
				}

				for (var i = 0; i < this.dataList.length; i++) {
					var data = this.dataList[i];
					buffer.put(data.mode, 4);
					buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber) );
					data.write(buffer);
				}
				if (buffer.getLengthInBits() <= totalDataCount * 8)
					break;
			}
			this.typeNumber = typeNumber;
		}
		this.makeImpl(false, this.getBestMaskPattern() );
	},
	
	makeImpl : function(test, maskPattern) {
		
		this.moduleCount = this.typeNumber * 4 + 17;
		this.modules = new Array(this.moduleCount);
		
		for (var row = 0; row < this.moduleCount; row++) {
			
			this.modules[row] = new Array(this.moduleCount);
			
			for (var col = 0; col < this.moduleCount; col++) {
				this.modules[row][col] = null;//(col + row) % 3;
			}
		}
	
		this.setupPositionProbePattern(0, 0);
		this.setupPositionProbePattern(this.moduleCount - 7, 0);
		this.setupPositionProbePattern(0, this.moduleCount - 7);
		this.setupPositionAdjustPattern();
		this.setupTimingPattern();
		this.setupTypeInfo(test, maskPattern);
		
		if (this.typeNumber >= 7) {
			this.setupTypeNumber(test);
		}
	
		if (this.dataCache == null) {
			this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList);
		}
	
		this.mapData(this.dataCache, maskPattern);
	},

	setupPositionProbePattern : function(row, col)  {
		
		for (var r = -1; r <= 7; r++) {
			
			if (row + r <= -1 || this.moduleCount <= row + r) continue;
			
			for (var c = -1; c <= 7; c++) {
				
				if (col + c <= -1 || this.moduleCount <= col + c) continue;
				
				if ( (0 <= r && r <= 6 && (c == 0 || c == 6) )
						|| (0 <= c && c <= 6 && (r == 0 || r == 6) )
						|| (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {
					this.modules[row + r][col + c] = true;
				} else {
					this.modules[row + r][col + c] = false;
				}
			}		
		}		
	},
	
	getBestMaskPattern : function() {
	
		var minLostPoint = 0;
		var pattern = 0;
	
		for (var i = 0; i < 8; i++) {
			
			this.makeImpl(true, i);
	
			var lostPoint = QRUtil.getLostPoint(this);
	
			if (i == 0 || minLostPoint >  lostPoint) {
				minLostPoint = lostPoint;
				pattern = i;
			}
		}
	
		return pattern;
	},
	
	createMovieClip : function(target_mc, instance_name, depth) {
	
		var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);
		var cs = 1;
	
		this.make();

		for (var row = 0; row < this.modules.length; row++) {
			
			var y = row * cs;
			
			for (var col = 0; col < this.modules[row].length; col++) {
	
				var x = col * cs;
				var dark = this.modules[row][col];
			
				if (dark) {
					qr_mc.beginFill(0, 100);
					qr_mc.moveTo(x, y);
					qr_mc.lineTo(x + cs, y);
					qr_mc.lineTo(x + cs, y + cs);
					qr_mc.lineTo(x, y + cs);
					qr_mc.endFill();
				}
			}
		}
		
		return qr_mc;
	},

	setupTimingPattern : function() {
		
		for (var r = 8; r < this.moduleCount - 8; r++) {
			if (this.modules[r][6] != null) {
				continue;
			}
			this.modules[r][6] = (r % 2 == 0);
		}
	
		for (var c = 8; c < this.moduleCount - 8; c++) {
			if (this.modules[6][c] != null) {
				continue;
			}
			this.modules[6][c] = (c % 2 == 0);
		}
	},
	
	setupPositionAdjustPattern : function() {
	
		var pos = QRUtil.getPatternPosition(this.typeNumber);
		
		for (var i = 0; i < pos.length; i++) {
		
			for (var j = 0; j < pos.length; j++) {
			
				var row = pos[i];
				var col = pos[j];
				
				if (this.modules[row][col] != null) {
					continue;
				}
				
				for (var r = -2; r <= 2; r++) {
				
					for (var c = -2; c <= 2; c++) {
					
						if (r == -2 || r == 2 || c == -2 || c == 2 
								|| (r == 0 && c == 0) ) {
							this.modules[row + r][col + c] = true;
						} else {
							this.modules[row + r][col + c] = false;
						}
					}
				}
			}
		}
	},
	
	setupTypeNumber : function(test) {
	
		var bits = QRUtil.getBCHTypeNumber(this.typeNumber);
	
		for (var i = 0; i < 18; i++) {
			var mod = (!test && ( (bits >> i) & 1) == 1);
			this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
		}
	
		for (var i = 0; i < 18; i++) {
			var mod = (!test && ( (bits >> i) & 1) == 1);
			this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
		}
	},
	
	setupTypeInfo : function(test, maskPattern) {
	
		var data = (this.errorCorrectLevel << 3) | maskPattern;
		var bits = QRUtil.getBCHTypeInfo(data);
	
		// vertical		
		for (var i = 0; i < 15; i++) {
	
			var mod = (!test && ( (bits >> i) & 1) == 1);
	
			if (i < 6) {
				this.modules[i][8] = mod;
			} else if (i < 8) {
				this.modules[i + 1][8] = mod;
			} else {
				this.modules[this.moduleCount - 15 + i][8] = mod;
			}
		}
	
		// horizontal
		for (var i = 0; i < 15; i++) {
	
			var mod = (!test && ( (bits >> i) & 1) == 1);
			
			if (i < 8) {
				this.modules[8][this.moduleCount - i - 1] = mod;
			} else if (i < 9) {
				this.modules[8][15 - i - 1 + 1] = mod;
			} else {
				this.modules[8][15 - i - 1] = mod;
			}
		}
	
		// fixed module
		this.modules[this.moduleCount - 8][8] = (!test);
	
	},
	
	mapData : function(data, maskPattern) {
		
		var inc = -1;
		var row = this.moduleCount - 1;
		var bitIndex = 7;
		var byteIndex = 0;
		
		for (var col = this.moduleCount - 1; col > 0; col -= 2) {
	
			if (col == 6) col--;
	
			while (true) {
	
				for (var c = 0; c < 2; c++) {
					
					if (this.modules[row][col - c] == null) {
						
						var dark = false;
	
						if (byteIndex < data.length) {
							dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);
						}
	
						var mask = QRUtil.getMask(maskPattern, row, col - c);
	
						if (mask) {
							dark = !dark;
						}
						
						this.modules[row][col - c] = dark;
						bitIndex--;
	
						if (bitIndex == -1) {
							byteIndex++;
							bitIndex = 7;
						}
					}
				}
								
				row += inc;
	
				if (row < 0 || this.moduleCount <= row) {
					row -= inc;
					inc = -inc;
					break;
				}
			}
		}
		
	}

};

QRCode.PAD0 = 0xEC;
QRCode.PAD1 = 0x11;

QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) {
	
	var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
	
	var buffer = new QRBitBuffer();
	
	for (var i = 0; i < dataList.length; i++) {
		var data = dataList[i];
		buffer.put(data.mode, 4);
		buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber) );
		data.write(buffer);
	}

	// calc num max data.
	var totalDataCount = 0;
	for (var i = 0; i < rsBlocks.length; i++) {
		totalDataCount += rsBlocks[i].dataCount;
	}

	if (buffer.getLengthInBits() > totalDataCount * 8) {
		throw new Error("code length overflow. ("
			+ buffer.getLengthInBits()
			+ ">"
			+  totalDataCount * 8
			+ ")");
	}

	// end code
	if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
		buffer.put(0, 4);
	}

	// padding
	while (buffer.getLengthInBits() % 8 != 0) {
		buffer.putBit(false);
	}

	// padding
	while (true) {
		
		if (buffer.getLengthInBits() >= totalDataCount * 8) {
			break;
		}
		buffer.put(QRCode.PAD0, 8);
		
		if (buffer.getLengthInBits() >= totalDataCount * 8) {
			break;
		}
		buffer.put(QRCode.PAD1, 8);
	}

	return QRCode.createBytes(buffer, rsBlocks);
}

QRCode.createBytes = function(buffer, rsBlocks) {

	var offset = 0;
	
	var maxDcCount = 0;
	var maxEcCount = 0;
	
	var dcdata = new Array(rsBlocks.length);
	var ecdata = new Array(rsBlocks.length);
	
	for (var r = 0; r < rsBlocks.length; r++) {

		var dcCount = rsBlocks[r].dataCount;
		var ecCount = rsBlocks[r].totalCount - dcCount;

		maxDcCount = Math.max(maxDcCount, dcCount);
		maxEcCount = Math.max(maxEcCount, ecCount);
		
		dcdata[r] = new Array(dcCount);
		
		for (var i = 0; i < dcdata[r].length; i++) {
			dcdata[r][i] = 0xff & buffer.buffer[i + offset];
		}
		offset += dcCount;
		
		var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
		var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1);

		var modPoly = rawPoly.mod(rsPoly);
		ecdata[r] = new Array(rsPoly.getLength() - 1);
		for (var i = 0; i < ecdata[r].length; i++) {
            var modIndex = i + modPoly.getLength() - ecdata[r].length;
			ecdata[r][i] = (modIndex >= 0)? modPoly.get(modIndex) : 0;
		}

	}
	
	var totalCodeCount = 0;
	for (var i = 0; i < rsBlocks.length; i++) {
		totalCodeCount += rsBlocks[i].totalCount;
	}

	var data = new Array(totalCodeCount);
	var index = 0;

	for (var i = 0; i < maxDcCount; i++) {
		for (var r = 0; r < rsBlocks.length; r++) {
			if (i < dcdata[r].length) {
				data[index++] = dcdata[r][i];
			}
		}
	}

	for (var i = 0; i < maxEcCount; i++) {
		for (var r = 0; r < rsBlocks.length; r++) {
			if (i < ecdata[r].length) {
				data[index++] = ecdata[r][i];
			}
		}
	}

	return data;

}

//---------------------------------------------------------------------
// QRMode
//---------------------------------------------------------------------

var QRMode = {
	MODE_NUMBER :		1 << 0,
	MODE_ALPHA_NUM : 	1 << 1,
	MODE_8BIT_BYTE : 	1 << 2,
	MODE_KANJI :		1 << 3
};

//---------------------------------------------------------------------
// QRErrorCorrectLevel
//---------------------------------------------------------------------
 
var QRErrorCorrectLevel = {
	L : 1,
	M : 0,
	Q : 3,
	H : 2
};

//---------------------------------------------------------------------
// QRMaskPattern
//---------------------------------------------------------------------

var QRMaskPattern = {
	PATTERN000 : 0,
	PATTERN001 : 1,
	PATTERN010 : 2,
	PATTERN011 : 3,
	PATTERN100 : 4,
	PATTERN101 : 5,
	PATTERN110 : 6,
	PATTERN111 : 7
};

//---------------------------------------------------------------------
// QRUtil
//---------------------------------------------------------------------
 
var QRUtil = {

    PATTERN_POSITION_TABLE : [
	    [],
	    [6, 18],
	    [6, 22],
	    [6, 26],
	    [6, 30],
	    [6, 34],
	    [6, 22, 38],
	    [6, 24, 42],
	    [6, 26, 46],
	    [6, 28, 50],
	    [6, 30, 54],		
	    [6, 32, 58],
	    [6, 34, 62],
	    [6, 26, 46, 66],
	    [6, 26, 48, 70],
	    [6, 26, 50, 74],
	    [6, 30, 54, 78],
	    [6, 30, 56, 82],
	    [6, 30, 58, 86],
	    [6, 34, 62, 90],
	    [6, 28, 50, 72, 94],
	    [6, 26, 50, 74, 98],
	    [6, 30, 54, 78, 102],
	    [6, 28, 54, 80, 106],
	    [6, 32, 58, 84, 110],
	    [6, 30, 58, 86, 114],
	    [6, 34, 62, 90, 118],
	    [6, 26, 50, 74, 98, 122],
	    [6, 30, 54, 78, 102, 126],
	    [6, 26, 52, 78, 104, 130],
	    [6, 30, 56, 82, 108, 134],
	    [6, 34, 60, 86, 112, 138],
	    [6, 30, 58, 86, 114, 142],
	    [6, 34, 62, 90, 118, 146],
	    [6, 30, 54, 78, 102, 126, 150],
	    [6, 24, 50, 76, 102, 128, 154],
	    [6, 28, 54, 80, 106, 132, 158],
	    [6, 32, 58, 84, 110, 136, 162],
	    [6, 26, 54, 82, 110, 138, 166],
	    [6, 30, 58, 86, 114, 142, 170]
    ],

    G15 : (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
    G18 : (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
    G15_MASK : (1 << 14) | (1 << 12) | (1 << 10)	| (1 << 4) | (1 << 1),

    getBCHTypeInfo : function(data) {
	    var d = data << 10;
	    while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
		    d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) ) ); 	
	    }
	    return ( (data << 10) | d) ^ QRUtil.G15_MASK;
    },

    getBCHTypeNumber : function(data) {
	    var d = data << 12;
	    while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
		    d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) ) ); 	
	    }
	    return (data << 12) | d;
    },

    getBCHDigit : function(data) {

	    var digit = 0;

	    while (data != 0) {
		    digit++;
		    data >>>= 1;
	    }

	    return digit;
    },

    getPatternPosition : function(typeNumber) {
	    return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
    },

    getMask : function(maskPattern, i, j) {
	    
	    switch (maskPattern) {
		    
	    case QRMaskPattern.PATTERN000 : return (i + j) % 2 == 0;
	    case QRMaskPattern.PATTERN001 : return i % 2 == 0;
	    case QRMaskPattern.PATTERN010 : return j % 3 == 0;
	    case QRMaskPattern.PATTERN011 : return (i + j) % 3 == 0;
	    case QRMaskPattern.PATTERN100 : return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0;
	    case QRMaskPattern.PATTERN101 : return (i * j) % 2 + (i * j) % 3 == 0;
	    case QRMaskPattern.PATTERN110 : return ( (i * j) % 2 + (i * j) % 3) % 2 == 0;
	    case QRMaskPattern.PATTERN111 : return ( (i * j) % 3 + (i + j) % 2) % 2 == 0;

	    default :
		    throw new Error("bad maskPattern:" + maskPattern);
	    }
    },

    getErrorCorrectPolynomial : function(errorCorrectLength) {

	    var a = new QRPolynomial([1], 0);

	    for (var i = 0; i < errorCorrectLength; i++) {
		    a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0) );
	    }

	    return a;
    },

    getLengthInBits : function(mode, type) {

	    if (1 <= type && type < 10) {

		    // 1 - 9

		    switch(mode) {
		    case QRMode.MODE_NUMBER 	: return 10;
		    case QRMode.MODE_ALPHA_NUM 	: return 9;
		    case QRMode.MODE_8BIT_BYTE	: return 8;
		    case QRMode.MODE_KANJI  	: return 8;
		    default :
			    throw new Error("mode:" + mode);
		    }

	    } else if (type < 27) {

		    // 10 - 26

		    switch(mode) {
		    case QRMode.MODE_NUMBER 	: return 12;
		    case QRMode.MODE_ALPHA_NUM 	: return 11;
		    case QRMode.MODE_8BIT_BYTE	: return 16;
		    case QRMode.MODE_KANJI  	: return 10;
		    default :
			    throw new Error("mode:" + mode);
		    }

	    } else if (type < 41) {

		    // 27 - 40

		    switch(mode) {
		    case QRMode.MODE_NUMBER 	: return 14;
		    case QRMode.MODE_ALPHA_NUM	: return 13;
		    case QRMode.MODE_8BIT_BYTE	: return 16;
		    case QRMode.MODE_KANJI  	: return 12;
		    default :
			    throw new Error("mode:" + mode);
		    }

	    } else {
		    throw new Error("type:" + type);
	    }
    },

    getLostPoint : function(qrCode) {
	    
	    var moduleCount = qrCode.getModuleCount();
	    
	    var lostPoint = 0;
	    
	    // LEVEL1
	    
	    for (var row = 0; row < moduleCount; row++) {

		    for (var col = 0; col < moduleCount; col++) {

			    var sameCount = 0;
			    var dark = qrCode.isDark(row, col);

				for (var r = -1; r <= 1; r++) {

				    if (row + r < 0 || moduleCount <= row + r) {
					    continue;
				    }

				    for (var c = -1; c <= 1; c++) {

					    if (col + c < 0 || moduleCount <= col + c) {
						    continue;
					    }

					    if (r == 0 && c == 0) {
						    continue;
					    }

					    if (dark == qrCode.isDark(row + r, col + c) ) {
						    sameCount++;
					    }
				    }
			    }

			    if (sameCount > 5) {
				    lostPoint += (3 + sameCount - 5);
			    }
		    }
	    }

	    // LEVEL2

	    for (var row = 0; row < moduleCount - 1; row++) {
		    for (var col = 0; col < moduleCount - 1; col++) {
			    var count = 0;
			    if (qrCode.isDark(row,     col    ) ) count++;
			    if (qrCode.isDark(row + 1, col    ) ) count++;
			    if (qrCode.isDark(row,     col + 1) ) count++;
			    if (qrCode.isDark(row + 1, col + 1) ) count++;
			    if (count == 0 || count == 4) {
				    lostPoint += 3;
			    }
		    }
	    }

	    // LEVEL3

	    for (var row = 0; row < moduleCount; row++) {
		    for (var col = 0; col < moduleCount - 6; col++) {
			    if (qrCode.isDark(row, col)
					    && !qrCode.isDark(row, col + 1)
					    &&  qrCode.isDark(row, col + 2)
					    &&  qrCode.isDark(row, col + 3)
					    &&  qrCode.isDark(row, col + 4)
					    && !qrCode.isDark(row, col + 5)
					    &&  qrCode.isDark(row, col + 6) ) {
				    lostPoint += 40;
			    }
		    }
	    }

	    for (var col = 0; col < moduleCount; col++) {
		    for (var row = 0; row < moduleCount - 6; row++) {
			    if (qrCode.isDark(row, col)
					    && !qrCode.isDark(row + 1, col)
					    &&  qrCode.isDark(row + 2, col)
					    &&  qrCode.isDark(row + 3, col)
					    &&  qrCode.isDark(row + 4, col)
					    && !qrCode.isDark(row + 5, col)
					    &&  qrCode.isDark(row + 6, col) ) {
				    lostPoint += 40;
			    }
		    }
	    }

	    // LEVEL4
	    
	    var darkCount = 0;

	    for (var col = 0; col < moduleCount; col++) {
		    for (var row = 0; row < moduleCount; row++) {
			    if (qrCode.isDark(row, col) ) {
				    darkCount++;
			    }
		    }
	    }
	    
	    var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
	    lostPoint += ratio * 10;

	    return lostPoint;		
    }

};


//---------------------------------------------------------------------
// QRMath
//---------------------------------------------------------------------

var QRMath = {

	glog : function(n) {
	
		if (n < 1) {
			throw new Error("glog(" + n + ")");
		}
		
		return QRMath.LOG_TABLE[n];
	},
	
	gexp : function(n) {
	
		while (n < 0) {
			n += 255;
		}
	
		while (n >= 256) {
			n -= 255;
		}
	
		return QRMath.EXP_TABLE[n];
	},
	
	EXP_TABLE : new Array(256),
	
	LOG_TABLE : new Array(256)

};
	
for (var i = 0; i < 8; i++) {
	QRMath.EXP_TABLE[i] = 1 << i;
}
for (var i = 8; i < 256; i++) {
	QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4]
		^ QRMath.EXP_TABLE[i - 5]
		^ QRMath.EXP_TABLE[i - 6]
		^ QRMath.EXP_TABLE[i - 8];
}
for (var i = 0; i < 255; i++) {
	QRMath.LOG_TABLE[QRMath.EXP_TABLE[i] ] = i;
}

//---------------------------------------------------------------------
// QRPolynomial
//---------------------------------------------------------------------

function QRPolynomial(num, shift) {

	if (num.length == undefined) {
		throw new Error(num.length + "/" + shift);
	}

	var offset = 0;


	while (offset < num.length && num[offset] == 0) {
		offset++;
	}

	this.num = new Array(num.length - offset + shift);
	for (var i = 0; i < num.length - offset; i++) {
		this.num[i] = num[i + offset];
	}
}

QRPolynomial.prototype = {

	get : function(index) {
		return this.num[index];
	},
	
	getLength : function() {
		return this.num.length;
	},
	
	multiply : function(e) {
	
		var num = new Array(this.getLength() + e.getLength() - 1);
	
		for (var i = 0; i < this.getLength(); i++) {
			for (var j = 0; j < e.getLength(); j++) {
				num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i) ) + QRMath.glog(e.get(j) ) );
			}
		}
	
		return new QRPolynomial(num, 0);
	},
	
	mod : function(e) {
	
		if (this.getLength() - e.getLength() < 0) {
			return this;
		}
	
		var ratio = QRMath.glog(this.get(0) ) - QRMath.glog(e.get(0) );
	
		var num = new Array(this.getLength() );
		
		for (var i = 0; i < this.getLength(); i++) {
			num[i] = this.get(i);
		}
		
		for (var i = 0; i < e.getLength(); i++) {
			num[i] ^= QRMath.gexp(QRMath.glog(e.get(i) ) + ratio);
		}
	
		// recursive call
		return new QRPolynomial(num, 0).mod(e);
	}
};

//---------------------------------------------------------------------
// QRRSBlock
//---------------------------------------------------------------------

function QRRSBlock(totalCount, dataCount) {
	this.totalCount = totalCount;
	this.dataCount  = dataCount;
}

QRRSBlock.RS_BLOCK_TABLE = [

	// L
	// M
	// Q
	// H

	// 1
	[1, 26, 19],
	[1, 26, 16],
	[1, 26, 13],
	[1, 26, 9],
	
	// 2
	[1, 44, 34],
	[1, 44, 28],
	[1, 44, 22],
	[1, 44, 16],

	// 3
	[1, 70, 55],
	[1, 70, 44],
	[2, 35, 17],
	[2, 35, 13],

	// 4		
	[1, 100, 80],
	[2, 50, 32],
	[2, 50, 24],
	[4, 25, 9],
	
	// 5
	[1, 134, 108],
	[2, 67, 43],
	[2, 33, 15, 2, 34, 16],
	[2, 33, 11, 2, 34, 12],
	
	// 6
	[2, 86, 68],
	[4, 43, 27],
	[4, 43, 19],
	[4, 43, 15],
	
	// 7		
	[2, 98, 78],
	[4, 49, 31],
	[2, 32, 14, 4, 33, 15],
	[4, 39, 13, 1, 40, 14],
	
	// 8
	[2, 121, 97],
	[2, 60, 38, 2, 61, 39],
	[4, 40, 18, 2, 41, 19],
	[4, 40, 14, 2, 41, 15],
	
	// 9
	[2, 146, 116],
	[3, 58, 36, 2, 59, 37],
	[4, 36, 16, 4, 37, 17],
	[4, 36, 12, 4, 37, 13],
	
	// 10		
	[2, 86, 68, 2, 87, 69],
	[4, 69, 43, 1, 70, 44],
	[6, 43, 19, 2, 44, 20],
	[6, 43, 15, 2, 44, 16],

	// 11
	[4, 101, 81],
	[1, 80, 50, 4, 81, 51],
	[4, 50, 22, 4, 51, 23],
	[3, 36, 12, 8, 37, 13],

	// 12
	[2, 116, 92, 2, 117, 93],
	[6, 58, 36, 2, 59, 37],
	[4, 46, 20, 6, 47, 21],
	[7, 42, 14, 4, 43, 15],

	// 13
	[4, 133, 107],
	[8, 59, 37, 1, 60, 38],
	[8, 44, 20, 4, 45, 21],
	[12, 33, 11, 4, 34, 12],

	// 14
	[3, 145, 115, 1, 146, 116],
	[4, 64, 40, 5, 65, 41],
	[11, 36, 16, 5, 37, 17],
	[11, 36, 12, 5, 37, 13],

	// 15
	[5, 109, 87, 1, 110, 88],
	[5, 65, 41, 5, 66, 42],
	[5, 54, 24, 7, 55, 25],
	[11, 36, 12],

	// 16
	[5, 122, 98, 1, 123, 99],
	[7, 73, 45, 3, 74, 46],
	[15, 43, 19, 2, 44, 20],
	[3, 45, 15, 13, 46, 16],

	// 17
	[1, 135, 107, 5, 136, 108],
	[10, 74, 46, 1, 75, 47],
	[1, 50, 22, 15, 51, 23],
	[2, 42, 14, 17, 43, 15],

	// 18
	[5, 150, 120, 1, 151, 121],
	[9, 69, 43, 4, 70, 44],
	[17, 50, 22, 1, 51, 23],
	[2, 42, 14, 19, 43, 15],

	// 19
	[3, 141, 113, 4, 142, 114],
	[3, 70, 44, 11, 71, 45],
	[17, 47, 21, 4, 48, 22],
	[9, 39, 13, 16, 40, 14],

	// 20
	[3, 135, 107, 5, 136, 108],
	[3, 67, 41, 13, 68, 42],
	[15, 54, 24, 5, 55, 25],
	[15, 43, 15, 10, 44, 16],

	// 21
	[4, 144, 116, 4, 145, 117],
	[17, 68, 42],
	[17, 50, 22, 6, 51, 23],
	[19, 46, 16, 6, 47, 17],

	// 22
	[2, 139, 111, 7, 140, 112],
	[17, 74, 46],
	[7, 54, 24, 16, 55, 25],
	[34, 37, 13],

	// 23
	[4, 151, 121, 5, 152, 122],
	[4, 75, 47, 14, 76, 48],
	[11, 54, 24, 14, 55, 25],
	[16, 45, 15, 14, 46, 16],

	// 24
	[6, 147, 117, 4, 148, 118],
	[6, 73, 45, 14, 74, 46],
	[11, 54, 24, 16, 55, 25],
	[30, 46, 16, 2, 47, 17],

	// 25
	[8, 132, 106, 4, 133, 107],
	[8, 75, 47, 13, 76, 48],
	[7, 54, 24, 22, 55, 25],
	[22, 45, 15, 13, 46, 16],

	// 26
	[10, 142, 114, 2, 143, 115],
	[19, 74, 46, 4, 75, 47],
	[28, 50, 22, 6, 51, 23],
	[33, 46, 16, 4, 47, 17],

	// 27
	[8, 152, 122, 4, 153, 123],
	[22, 73, 45, 3, 74, 46],
	[8, 53, 23, 26, 54, 24],
	[12, 45, 15, 28, 46, 16],

	// 28
	[3, 147, 117, 10, 148, 118],
	[3, 73, 45, 23, 74, 46],
	[4, 54, 24, 31, 55, 25],
	[11, 45, 15, 31, 46, 16],

	// 29
	[7, 146, 116, 7, 147, 117],
	[21, 73, 45, 7, 74, 46],
	[1, 53, 23, 37, 54, 24],
	[19, 45, 15, 26, 46, 16],

	// 30
	[5, 145, 115, 10, 146, 116],
	[19, 75, 47, 10, 76, 48],
	[15, 54, 24, 25, 55, 25],
	[23, 45, 15, 25, 46, 16],

	// 31
	[13, 145, 115, 3, 146, 116],
	[2, 74, 46, 29, 75, 47],
	[42, 54, 24, 1, 55, 25],
	[23, 45, 15, 28, 46, 16],

	// 32
	[17, 145, 115],
	[10, 74, 46, 23, 75, 47],
	[10, 54, 24, 35, 55, 25],
	[19, 45, 15, 35, 46, 16],

	// 33
	[17, 145, 115, 1, 146, 116],
	[14, 74, 46, 21, 75, 47],
	[29, 54, 24, 19, 55, 25],
	[11, 45, 15, 46, 46, 16],

	// 34
	[13, 145, 115, 6, 146, 116],
	[14, 74, 46, 23, 75, 47],
	[44, 54, 24, 7, 55, 25],
	[59, 46, 16, 1, 47, 17],

	// 35
	[12, 151, 121, 7, 152, 122],
	[12, 75, 47, 26, 76, 48],
	[39, 54, 24, 14, 55, 25],
	[22, 45, 15, 41, 46, 16],

	// 36
	[6, 151, 121, 14, 152, 122],
	[6, 75, 47, 34, 76, 48],
	[46, 54, 24, 10, 55, 25],
	[2, 45, 15, 64, 46, 16],

	// 37
	[17, 152, 122, 4, 153, 123],
	[29, 74, 46, 14, 75, 47],
	[49, 54, 24, 10, 55, 25],
	[24, 45, 15, 46, 46, 16],

	// 38
	[4, 152, 122, 18, 153, 123],
	[13, 74, 46, 32, 75, 47],
	[48, 54, 24, 14, 55, 25],
	[42, 45, 15, 32, 46, 16],

	// 39
	[20, 147, 117, 4, 148, 118],
	[40, 75, 47, 7, 76, 48],
	[43, 54, 24, 22, 55, 25],
	[10, 45, 15, 67, 46, 16],

	// 40
	[19, 148, 118, 6, 149, 119],
	[18, 75, 47, 31, 76, 48],
	[34, 54, 24, 34, 55, 25],
	[20, 45, 15, 61, 46, 16]
];

QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) {
	
	var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
	
	if (rsBlock == undefined) {
		throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel);
	}

	var length = rsBlock.length / 3;
	
	var list = new Array();
	
	for (var i = 0; i < length; i++) {

		var count = rsBlock[i * 3 + 0];
		var totalCount = rsBlock[i * 3 + 1];
		var dataCount  = rsBlock[i * 3 + 2];

		for (var j = 0; j < count; j++) {
			list.push(new QRRSBlock(totalCount, dataCount) );	
		}
	}
	
	return list;
}

QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) {

	switch(errorCorrectLevel) {
	case QRErrorCorrectLevel.L :
		return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
	case QRErrorCorrectLevel.M :
		return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
	case QRErrorCorrectLevel.Q :
		return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
	case QRErrorCorrectLevel.H :
		return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
	default :
		return undefined;
	}
}

//---------------------------------------------------------------------
// QRBitBuffer
//---------------------------------------------------------------------

function QRBitBuffer() {
	this.buffer = new Array();
	this.length = 0;
}

QRBitBuffer.prototype = {

	get : function(index) {
		var bufIndex = Math.floor(index / 8);
		return ( (this.buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;
	},
	
	put : function(num, length) {
		for (var i = 0; i < length; i++) {
			this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);
		}
	},
	
	getLengthInBits : function() {
		return this.length;
	},
	
	putBit : function(bit) {
	
		var bufIndex = Math.floor(this.length / 8);
		if (this.buffer.length <= bufIndex) {
			this.buffer.push(0);
		}
	
		if (bit) {
			this.buffer[bufIndex] |= (0x80 >>> (this.length % 8) );
		}
	
		this.length++;
	}
};

 

PhotoshopQRvector.jsx:

//Script by Fr4nZ82@gmail.com
//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)*/

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Aug 31, 2022 Aug 31, 2022

Copy link to clipboard

Copied

Thanks this works great!
How can I change the dimensions and resolution of the file?
Simply changing the numbers in app.documents.add doesn't seem to do the trick.

var mydoc = app.documents.add( 600, 600, 72, "tmp", NewDocumentMode.RGB, DocumentFill.WHITE );

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Aug 31, 2022 Aug 31, 2022

Copy link to clipboard

Copied

LATEST

Only change the dimensions (not the resolution) e.g:

 

var mydoc = app.documents.add(1200, 1200, 72, "tmp", NewDocumentMode.RGB, DocumentFill.WHITE );

 

And at the end of the script change the resolution e.g.:

 

mydoc.resizeImage(undefined, undefined, 600, ResampleMethod.NONE);

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines