Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * @version 1.0
- * @package Color Analysis for Colorchecker. color-analysis.jsx
- * @copyright Copyright (C) 2013 José Pereira (www.jpereira.net). All rights reserved.
- * @license GNU/GPL
- * color-analysis.jsx is free software. This version may have been modified pursuant
- * to the GNU General Public License, and as distributed it includes or
- * is derivative of works licensed under the GNU General Public License or
- * other free or open source software licenses.
- * http://www.gnu.org/copyleft/lgpl.html
- */
- var arrayPatches = new Array(
- Array(37.99, 13.56, 14.06),
- Array(65.71, 18.13, 17.81),
- Array(49.93, -4.88, -21.93),
- Array(43.14, -13.10, 21.91),
- Array(55.11, 8.84, -25.40),
- Array(70.72, -33.40, -0.20),
- Array(62.66, 36.07, 57.10),
- Array(40.02, 10.41, -45.96),
- Array(51.12, 48.24, 16.25),
- Array(30.33, 22.98, -21.59),
- Array(72.53, -23.71, 57.26),
- Array(71.94, 19.36, 67.86),
- Array(28.78, 14.18, -50.30),
- Array(55.26, -38.34, 31.37),
- Array(42.10, 53.38, 28.19),
- Array(81.73, 4.04, 79.82),
- Array(51.94, 49.99, -14.57),
- Array(51.04, -28.63, -28.64),
- Array(96.54, -0.43, 1.19),
- Array(81.26, -0.64, -0.34),
- Array(66.77, -0.73, -0.50),
- Array(50.87, -0.15, -0.27),
- Array(35.66, -0.42, -1.23),
- Array(20.46, -0.08, -0.97)
- );
- if (documents.length == 0) {
- alert("No hay documentos abiertos!");
- }
- else {
- var docRef = activeDocument;
- var profile = getDocProfile();
- app.preferences.rulerUnits = Units.PIXELS;
- app.preferences.typeUnits = TypeUnits.PIXELS;
- if (docRef.mode != DocumentMode.LAB) {
- docRef.changeMode(ChangeMode.LAB);
- }
- var artLayerRef = docRef.artLayers.add();
- artLayerRef.name = "Patches"
- try {
- var cc = new ColorChecker();
- cc.FindPatchesFromActiveDoc();
- }catch (e) {
- var hs = docRef.historyStates;
- docRef.activeHistoryState = hs[hs.length-4];
- }
- }
- function getSelectionColor( x, y, sampleSize ){
- try{
- x = x - ( sampleSize / 2 );
- y = y - ( sampleSize / 2 );
- activeDocument.selection.select([[x, y], [x+sampleSize, y], [x+sampleSize, y+sampleSize], [x, y+sampleSize]], SelectionType.REPLACE, 0, false);
- //activeDocument.activeLayer.applyAverage();
- activeDocument.backgroundLayer.applyAverage();
- var re = RegExp( '[123456789]' );
- var sColor = new SolidColor();
- if ( activeDocument.mode == DocumentMode.LAB ) {
- var lv = re.exec(activeDocument.channels[0].histogram.toString() ).index/2;
- sColor.lab.l = 100 * ( lv/255 );
- sColor.lab.a = ( re.exec( activeDocument.channels[1].histogram.toString() ).index/2 ) - 128;
- sColor.lab.b = ( re.exec( activeDocument.channels[2].histogram.toString() ).index/2 ) - 128;
- }
- executeAction( charIDToTypeID('undo'), undefined, DialogModes.NO );
- return sColor;
- }catch(e){}
- }
- // -------------------------------------------------------
- // 'FindPatchesFromActiveDoc' and 'ComputePatchCoordinates'
- // are inspired by the work of Thomas Fors (Copyright (c) 2007).
- // from the script AcrCalibrator.
- // -------------------------------------------------------
- function ColorChecker() {
- this.x = new Array(); // array of x-axis pixel coordinates of patches
- this.y = new Array(); // array of y-axiz pixel coordinates of patches
- this.refColor = new Array(); // array of reference patch colors
- this.measColor = new Array(); // array of measured patch colors
- ColorChecker.prototype['FindPatchesFromActiveDoc'] = function () {
- var tlX, tlY, blX, blY, brX, brY, trX, trY;
- // Read path to find corner patches
- if ( activeDocument.pathItems.length == 1 ) {
- // document contains a single path
- if ( activeDocument.pathItems[0].subPathItems[0].pathPoints.length == 4 ) {
- // path has exactly four points
- tlX = activeDocument.pathItems[0].subPathItems[0].pathPoints[0].anchor[0];
- tlY = activeDocument.pathItems[0].subPathItems[0].pathPoints[0].anchor[1];
- blX = activeDocument.pathItems[0].subPathItems[0].pathPoints[1].anchor[0];
- blY = activeDocument.pathItems[0].subPathItems[0].pathPoints[1].anchor[1];
- brX = activeDocument.pathItems[0].subPathItems[0].pathPoints[2].anchor[0];
- brY = activeDocument.pathItems[0].subPathItems[0].pathPoints[2].anchor[1];
- trX = activeDocument.pathItems[0].subPathItems[0].pathPoints[3].anchor[0];
- trY = activeDocument.pathItems[0].subPathItems[0].pathPoints[3].anchor[1];
- }
- else {
- alert("Path must have exactly four points");
- }
- }
- else {
- alert ("You must define the chart area. See intructions!!");
- }
- this.patchCornerString = "("+Math.round(tlX)+","+Math.round(tlY)+") ";
- this.patchCornerString += "("+Math.round(blX)+","+Math.round(blY)+") ";
- this.patchCornerString += "("+Math.round(brX)+","+Math.round(brY)+") ";
- this.patchCornerString += "("+Math.round(trX)+","+Math.round(trY)+")";
- // X,Y coords of corner patches (tl, bl, br, tr)
- this.ComputePatchCoordinates(tlX,tlY, blX,blY, brX,brY, trX,trY);
- }
- ColorChecker.prototype['ComputePatchCoordinates'] = function (tlX,tlY, blX,blY, brX,brY, trX,trY) {
- var row, col,px,py;
- var fin = new Array();
- var salida = new Array();
- var dif = new Array();
- var cielab= new Array();
- var arrDif = new Array();
- var sampleColor=new SolidColor();
- var area = 30;
- ancho = trX - tlX;
- alto = blY - tlY;
- indiceX = Math.round(ancho/6);
- indiceY = Math.round(alto/4);
- i = 1;
- for ( row = 1; row < 5; row++ ) {
- for ( col = 1; col<7; col++ ) {
- idx = row * 6 + col; // patch index
- lX = row * (blX - tlX) / 4 + tlX; // left x coord of row
- rX = row * (brX - trX) / 4 + trX; // right x coord of row
- this.x[idx] = col * (rX - lX) / 6 + lX; // x coord of patch
- this.x[idx] = Math.round(this.x[idx]);
- tY = col * (trY - tlY) / 6 + tlY; // top y coord of col
- bY = col * (brY - blY) / 6 + blY; // top y coord of col
- this.y[idx] = row * (bY - tY) / 4 + tY; // y coord of patch
- this.y[idx] = Math.round(this.y[idx]);
- x = this.x[idx] - (indiceX/2)
- y = this.y[idx] - (indiceY/2)
- sampleColor = getSelectionColor(x,y,area);
- Circle(y-15,x-15,y+area,x+area);
- salida[i] = Array(sampleColor.lab.l, sampleColor.lab.a, sampleColor.lab.b );
- i++;
- }
- }
- informe( salida);
- }
- }
- function informe(finArray){
- var valoresCIELAB = "";
- var valoresDiferencia = "";
- var valoresPromedioParches = "";
- var valoresPromedioGlobal = "";
- var valorPromedioTotal00 = 0;
- var si = s();
- var lumas = "";
- var patchCoor = Array("A", "B", "C", "D");
- var valorDeltaE = "";
- var valoresOriginales = "";
- var valorPromedioTotal = 0;
- var SumLumDiff = 0;
- var promedioDeC = 0;
- var promedioDeT = 0;
- var salida = "";
- var j = 0;
- var h = 1;
- var dt = new Date();
- var Name = app.activeDocument.name.replace(/\.[^\.]+$/, '');
- var Path = app.activeDocument.path;
- var contenido = "";
- var f = new File(Path + "/" + Name +"_color_analysis.txt");
- f.open("a+");
- for(i=1; i < 25; i++) {
- if ((i -1)% 6 == 0) {
- j++;
- h = 1;
- }
- parche = patchCoor[j-1]+h;
- h++;
- valorDeltaE = deltae(arrayPatches[i-1][0],finArray[i][0],arrayPatches[i-1][1],finArray[i][1],arrayPatches[i-1][2],finArray[i][2]);
- valorPromedioTotal += parseFloat( valorDeltaE );
- valoresCIELAB = redondea(finArray[i][0],2) +"\t"+ fmtPos(finArray[i][1]) +"\t"+ fmtPos(finArray[i][2]);
- valoresOriginales = redondea(arrayPatches[i-1][0],2)+"\t"+fmtPos(redondea(arrayPatches[i-1][1],2))+"\t"+fmtPos(redondea(arrayPatches[i-1][2],2));
- valorDeltaE00 = deltaE2000(arrayPatches[i-1], finArray[i]);
- valorPromedioTotal00 += parseFloat( valorDeltaE00 );
- cr1 = croma(finArray[i][1], finArray[i][2]);
- tn1 = tono(finArray[i][1], finArray[i][2]);
- cr2 = croma(arrayPatches[i-1][1], arrayPatches[i-1][2]);
- tn2 = tono(arrayPatches[i-1][1], arrayPatches[i-1][2]);
- DeC = deltaCroma(cr1, cr2);
- promedioDeC += parseFloat( DeC );
- DeT = deltaTono( (arrayPatches[i-1][0] - finArray[i][0]), DeC, valorDeltaE)
- promedioDeT += parseFloat( DeT );
- if (i > 18){
- lumIM = lab2luma(finArray[i]);
- lumCK = lab2luma( arrayPatches[i-1]);
- lumDiff = lumIM - lumCK;
- SumLumDiff += parseFloat(lumDiff);
- lumas += "\t"+parche +"\t\t"+Math.round(lumIM)+"\t\t"+Math.round(lumCK)+"\t\t"+fmtPos(redondea(lumDiff,1))+"\r"
- }
- salida += "\t"+parche +"\t"+valoresCIELAB+ "\t\t"+ valoresOriginales+ "\t\t"+DeC+"\t\t"+DeT+"\t\t"+ valorDeltaE+"\t\t"+ valorDeltaE00 +"\r"
- }
- var CAVG = redondea(promedioDeC/24,2)
- var TAVG = redondea(promedioDeT/24,2)
- var CIE76AVG = redondea(valorPromedioTotal/24,2);
- var CIE00AVG = redondea(valorPromedioTotal00/24,2);
- var LUMADIFF = redondea(SumLumDiff/6,2);
- f.write ( "\r" ) ;
- f.write ( "IMAGE SUMMARY\r");
- f.write ( "----------------------------------------------------------------------------------------------------\r" ) ;
- f.write ( "\r\r" ) ;
- f.write ( "\tProfile: "+profile+"\r");
- f.write ( "\tPath: "+Path+"\r");
- f.write ( "\tName: "+app.activeDocument.name+"\r");
- f.write ( "\tDate: "+dt.getDate()+ "/" + dt.getMonth() + 1 + "/" +dt.getFullYear()+"\r");
- f.write ( "\r" ) ;
- f.write ( "\r" ) ;
- f.write ( "COLOR ANALYSIS\r");
- f.write ( "----------------------------------------------------------------------------------------------------\r" ) ;
- f.write ( "\r\r" ) ;
- f.write ( "\t\tResults\t\t\t\tReferences\r");
- f.write ( "Sample\tL\t\t a\t b\t\tL\t\t a\t\t b\t\t\tdC\t\t\tdH\t\t\tCIE76\t\tCIE00\r");
- f.write ( salida ) ;
- f.write ( "\r" ) ;
- f.write ( "Average\t\t\t\t\t\t\t\t\t\t\t\t\t"+CAVG+"\t\t"+TAVG+"\t\t"+CIE76AVG+"\t\t"+CIE00AVG ) ;
- f.write ( "\r\r" ) ;
- f.write ( "OECF ANALYSIS\r");
- f.write ( "----------------------------------------------------------------------------------------------------\r" ) ;
- f.write ( "\r\r" ) ;
- f.write ( "Sample\t\tRes\t\tRef\t\tDif\r" ) ;
- f.write ( lumas ) ;
- f.write ( "Average\t\t\t\t\t\t"+LUMADIFF ) ;
- f.write ( "\r\r\r\r\t\t\t\t\t\t\t\t"+si ) ;
- try {
- var myWindow = new Window ("dialog", "Delta Report :: "+si);
- var myInputGroup = myWindow.add ("panel");
- myInputGroup.alignChildren = "left";
- myInputGroup.add ("statictext", undefined, "ΔChroma Average:"+CAVG);
- myInputGroup.add ("statictext", undefined, "ΔHue Average:"+TAVG);
- myInputGroup.add ("statictext", undefined, "ΔCIE76 Average:"+CIE76AVG);
- myInputGroup.add ("statictext", undefined, "ΔCIE00 Average:"+CIE00AVG);
- myInputGroup.add ("statictext", undefined, "ΔLuminance Average:"+LUMADIFF);
- var myButtonGroup = myWindow.add ("group");
- myButtonGroup.alignment = "center";
- myButtonGroup.add ("button", undefined, "OK");
- myWindow.show ();
- }catch (e) { alert(e)}
- }
- Array.prototype.max = function() {
- var max = this[0];
- var len = this.length;
- for (var i = 1; i < len; i++) if (this[i] > max) max = this[i];
- return max;
- }
- function getDocProfile(){
- var res = undefined;
- try{
- res =app.activeDocument.colorProfileName;
- }catch(e){}
- return res;
- }
- function Circle(Top,Left,Bottom,Right) {
- var docRef = activeDocument;
- docRef.activeLayer=docRef.artLayers["Patches"];
- var Black = new SolidColor();
- Black.rgb.hexValue = '000000';
- var desc3 = new ActionDescriptor();
- var ref1 = new ActionReference();
- ref1.putProperty( charIDToTypeID('Chnl'), charIDToTypeID('fsel') );
- desc3.putReference( charIDToTypeID('null'), ref1 );
- var desc4 = new ActionDescriptor();
- desc4.putUnitDouble( charIDToTypeID('Top '), charIDToTypeID('#Pxl'), Top );
- desc4.putUnitDouble( charIDToTypeID('Left'), charIDToTypeID('#Pxl'), Left );
- desc4.putUnitDouble( charIDToTypeID('Btom'), charIDToTypeID('#Pxl'), Bottom );
- desc4.putUnitDouble( charIDToTypeID('Rght'), charIDToTypeID('#Pxl'), Right );
- desc3.putObject( charIDToTypeID('T '), charIDToTypeID('Elps'), desc4 );
- desc3.putBoolean( charIDToTypeID('AntA'), true );
- executeAction( charIDToTypeID('setd'), desc3, DialogModes.NO );
- activeDocument.selection.stroke (Black, 2, StrokeLocation.INSIDE, ColorBlendMode.NORMAL, 100, false);
- }
- function redondea(rnum, rlength) {
- var newnumber = Math.round(rnum*Math.pow(10,rlength))/Math.pow(10,rlength);
- //fmt = padding_right(newnumber, '0', 2);
- //return parseFloat(newnumber);
- return newnumber.toFixed(2);
- //return fmt;
- }
- function padding_right(s, c, n) {
- if (! s || ! c || s.length >= n) {
- return s;
- }
- var max = (n - s.length)/c.length;
- for (var i = 0; i < max; i++) {
- s += c;
- }
- return s;
- }
- function fmtPos(n){
- //añade un espacio a los valores positivos
- //para nivelarlos con los negativos
- if (n >= 0){
- return " "+n;
- }else{
- return n;
- }
- }
- function porcentage(a, b){
- var valor = 0;
- valor = parseFloat(a)*(parseFloat(b)/100);
- return Math.abs(valor);
- }
- function promedio (a){
- var output = 0;
- for(var q=0; q< a.length; q++) {
- output += parseFloat( a[q] ) ;
- }
- output = output/3;
- return output.toFixed(2);
- }
- function deltae(l1,l2,a1,a2,b1,b2) {
- //CIE76 formula
- var salida = 0;
- salida = Math.sqrt( Math.pow(l1-l2,2) + Math.pow(a1-a2,2) + Math.pow(b1-b2,2) )
- return salida.toFixed(2);
- }
- function croma(a,b) {
- croma = Math.sqrt( Math.pow(a,2) + Math.pow(b,2) );
- return croma.toFixed(2);
- }
- function tono(a,b){
- tono = Math.atan2(b,a);
- tonoDeg = tono * 180 / Math.PI;
- if (tonoDeg < 0 ){
- tonoDeg += 360;
- }
- return tonoDeg.toFixed(2);
- }
- function deltaCroma(c1,c2){
- dC = Math.abs(c1 - c2);
- return dC.toFixed(2);
- }
- function s(){
- a = unescape( '%62%79%3A' );
- b = unescape( '%77%77%77%2E%6A%70%65%72%65%69%72%61%2E%6E%65%74%09' );
- return b;
- }
- function deltaTono(dl, dC, D76){
- diff = Math.pow(D76,2) - Math.pow(dl,2) - Math.pow(dC,2);
- if (diff > 0){
- dT = Math.sqrt( diff );
- return dT.toFixed(2);
- }else{
- return "0.00";
- }
- }
- function lab2XYZ(CIEL, CIEa, CIEb){
- var result = new Array();
- var_Y = ( CIEL + 16 ) / 116
- var_X = CIEa / 500 + var_Y
- var_Z = var_Y - CIEb / 200
- if ( Math.pow(var_Y,3) > 0.008856 ) {
- var_Y = Math.pow(var_Y,3);
- }else{
- var_Y = ( var_Y - 16 / 116 ) / 7.787;
- }
- if ( Math.pow(var_X,3) > 0.008856 ) {
- var_X = Math.pow(var_X,3);
- }else{
- var_X = ( var_X - 16 / 116 ) / 7.787;
- }
- if ( Math.pow(var_Z,3) > 0.008856 ) {
- var_Z = Math.pow(var_Z,3);
- }else{
- var_Z = ( var_Z - 16 / 116 ) / 7.787;
- }
- // D65, 2° Observador
- X = 0.95047 * var_X ;
- Y = 1.00000 * var_Y ;
- Z = 1.08883 * var_Z ;
- result[0] = X;
- result[1] = Y;
- result[2] = Z;
- return result;
- }
- function xyz2rgb(X, Y, Z){
- var result = new Array();
- R = X * 3.2406 + Y * -1.5372 + Z * -0.4986;
- G = X * -0.9689 + Y * 1.8758 + Z * 0.0415;
- B = X * 0.0557 + Y * -0.2040 + Z * 1.0570;
- if ( R > 0.0031308 ){
- R = 1.055 * ( Math.pow(R , ( 1 / 2.4 )) ) - 0.055;
- }else{
- R = 12.92 * R;
- }
- if ( G > 0.0031308 ) {
- G = 1.055 * ( Math.pow(G , ( 1 / 2.4 )) ) - 0.055;
- }else{
- G = 12.92 * G;
- }
- if ( B > 0.0031308 ){
- B = 1.055 * ( Math.pow(B , ( 1 / 2.4 )) ) - 0.055;
- }else{
- B = 12.92 * B;
- }
- result[0] = Math.round(R * 255);
- result[1] = Math.round(G * 255);
- result[2] = Math.round(B * 255);
- return result;
- }
- // calcula la luminosidad del observador
- function luminosidad(rgb){
- Y = 0.2126*rgb[0] + 0.7152*rgb[1] + 0.0722*rgb[2];
- return Y;
- }
- function luminancia(pl){
- YY = Math.pow( (pl/255), 2.2) * 100;
- return YY;
- }
- function lab2luma(cielab){
- XYZ = lab2XYZ(cielab[0], cielab[1], cielab[2]);
- RGB = xyz2rgb(XYZ[0], XYZ[1], XYZ[2]);
- PL = luminosidad(RGB);
- Lum = luminancia(PL);
- return Lum;
- }
- function deltaE2000(lab1, lab2) {
- L1 = lab1[0];
- a1 = lab1[1];
- b1 = lab1[2];
- L2 = lab2[0];
- a2 = lab2[1];
- b2 = lab2[2];
- Cab1 = Math.sqrt(a1 * a1 + b1 * b1);
- Cab2 = Math.sqrt(a2 * a2 + b2 * b2);
- CabAvg = (Cab1 + Cab2) / 2;
- CabAvg7 = Math.pow(CabAvg, 7);
- G = 1 + (1 - Math.sqrt(CabAvg7 / (CabAvg7 + 6103515625.0))) / 2;
- ap1 = G * a1;
- ap2 = G * a2;
- Cp1 = Math.sqrt(ap1 * ap1 + b1 * b1);
- Cp2 = Math.sqrt(ap2 * ap2 + b2 * b2);
- CpProd = Cp1 * Cp2;
- hp1 = Math.atan2(b1, ap1);
- if (hp1 < 0) {
- hp1 += 6.283185307179586476925286766559;
- }
- hp2 = Math.atan2(b2, ap2);
- if (hp2 < 0) {
- hp2 += 6.283185307179586476925286766559;
- }
- dL = L2 - L1;
- dC = Cp2 - Cp1;
- dhp = 0.0;
- if (CpProd != 0) {
- dhp = hp2 - hp1;
- if (dhp > Math.PI) {
- dhp -= 6.283185307179586476925286766559;
- } else if (dhp < -Math.PI) {
- dhp += 6.283185307179586476925286766559;
- }
- }
- dH = 2 * Math.sqrt(CpProd) * Math.sin(dhp / 2);
- Lp = (L1 + L2) / 2 - 50;
- Cp = (Cp1 + Cp2) / 2;
- hp = (hp1 + hp2) / 2;
- if (Math.abs(hp1 - hp2) > Math.PI) {
- hp -= Math.PI;
- }
- if (hp < 0) {
- hp += 6.283185307179586476925286766559;
- }
- LpSqr = Lp * Lp;
- Sl = 1 + 0.015 * LpSqr / Math.sqrt(20 + LpSqr);
- Sc = 1 + 0.045 * Cp;
- hphp = hp + hp;
- T = 1 - 0.17 * Math.cos(hp - 0.52359877559829887307710723054658)
- + 0.24 * Math.cos(hphp)
- + 0.32 * Math.cos(hphp + hp + 0.10471975511965977461542144610932)
- - 0.20 * Math.cos(hphp + hphp - 1.0995574287564276334619251841478);
- Sh = 1 + 0.015 * Cp * T;
- powerBase = hp - 4.799655442984406;
- deltaThetaRad = 1.0471975511965977461542144610932 * Math.exp(-5.25249016001879 * powerBase * powerBase);
- Cp7 = Math.pow(Cp, 7);
- Rc = 2 * Math.sqrt(Cp7 / (Cp7 + 6103515625.0));
- RT = -Math.sin(deltaThetaRad) * Rc;
- dLSl = dL / Sl;
- dCSc = dC / Sc;
- dHSh = dH / Sh;
- salida = Math.sqrt(dLSl * dLSl + dCSc * dCSc + dHSh * dHSh + RT * dCSc * dHSh);
- return salida.toFixed(2);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement