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

Comparing layers for equality [2011]

New Here ,
Dec 15, 2011 Dec 15, 2011

Copy link to clipboard

Copied

Is it possible to compare two different layers to see if they are in fact the same image?

 

I'm actually working on a game at the moment. The game map was created by using game sprites created by other people. For example, I found 5 different pictures of trees, and copy pasted them into photoshop multiple times to create a forest. I have 100 trees in my photoshop document, but in reality, they are all made up of only 5 images. I want to save out each of these trees into a format usable by my game engine. I want to save each layer as an image, but avoid saving duplicates. Thus the need to compare layers for equality.

 

Is it possible to do this within a photoshop script? Thanks for any help you can provide.

TOPICS
Actions and scripting

Views

2.0K
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 ,
Feb 28, 2025 Feb 28, 2025

Copy link to clipboard

Copied

@c.pfaffenbichler  Kindly ignore the additional request, i was able to work on that part. 

 

Thank you again for the help on entire feature request. Saved lot of scripting efforts for R&D.

Votes

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 ,
Feb 28, 2025 Feb 28, 2025

Copy link to clipboard

Copied

@c.pfaffenbichler  Is it possible to color the difference pixels instead of adding stroke ?

Votes

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 Expert ,
Feb 28, 2025 Feb 28, 2025

Copy link to clipboard

Copied

It is possible but I probably won’t have time to look into that this week. 

Votes

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 Expert ,
Mar 02, 2025 Mar 02, 2025

Copy link to clipboard

Copied

Screenshot 2025-03-02 at 16.10.23.pngexpand image

// tries to create a file comparing all pages of two cmyk-pdfs;
// 2025, use it at your own risk;
/* dialog for pdf-selection */
if (ScriptUI.environment.keyboardState.shiftKey == true) {var theRes = 300}
else {var theRes = 150};
var theFile1 = File.openDialog("please select the first pdf", checkForPDF, false);
var theFile2 = File.openDialog("please select the second pdf", checkForPDF, false);
if (theFile1 && theFile2) {
/* the open options */
	var pdfOpenOpts = new PDFOpenOptions;
	pdfOpenOpts.antiAlias = true;
	pdfOpenOpts.bitsPerChannel = BitsPerChannelType.EIGHT;
	pdfOpenOpts.cropPage = CropToType.TRIMBOX;
	pdfOpenOpts.mode = OpenDocumentMode.CMYK;
	pdfOpenOpts.resolution = theRes;
	pdfOpenOpts.suppressWarnings = true;
	pdfOpenOpts.usePageNumber  = true;
	var thePdf = compareMultipagePDF(theFile1, theFile2, pdfOpenOpts);
	revealAll ();
	};
/* function to compare all pages of two pdfs */
function compareMultipagePDF(myPDFFile1, myPDFFile2) {
	var secondShorter = false;
/* suppress dialogs */
	var theDialogSettings = app.displayDialogs;
	app.displayDialogs = DialogModes.NO;
	var myCounter = 1;
	var myBreak = false;
	while(myBreak == false){
		pdfOpenOpts.page = myCounter;
		try {
			var thePdf = app.open(myPDFFile1, pdfOpenOpts);
			thePdf.flatten();
			thePdf.layers[0].isBackgroundLayer = false;
			thePdf.layers[0].name = myPDFFile1.name+"_"+myCounter;
			if (myCounter == 1) {
				var theFile = thePdf
				}
			else {
				thePdf.layers[0].duplicate(theFile, ElementPlacement.PLACEATBEGINNING);
				thePdf.close(SaveOptions.DONOTSAVECHANGES)
				};
			try {
				var theSecondPdf = app.open(myPDFFile2, pdfOpenOpts);
				theSecondPdf.flatten();
				theSecondPdf.layers[0].isBackgroundLayer = false;
				theSecondPdf.layers[0].name = myPDFFile2.name+"_"+myCounter;
				theSecondPdf.layers[0].duplicate(theFile, ElementPlacement.PLACEATBEGINNING);
				theSecondPdf.close(SaveOptions.DONOTSAVECHANGES);
				var theSecond = activeDocument.activeLayer;
                theSecond.blendMode = BlendMode.DIFFERENCE;
				var id556 = charIDToTypeID( "GrpL" );
				executeAction( id556, undefined, DialogModes.NO );
// mark differences;
				mergVisibleToNewLayer();
				var theBlendIfThisArray = [ [9,9,255,255], [0,0,255,255], [0,0,255,255], [0,0,255,255] ];
				var theBlendIfUnderlyingArray = [ [0,0,255,255], [0,0,255,255], [0,0,255,255], [0,0,255,255] ];
				blendIfThisAndUnderlying (theBlendIfThisArray, theBlendIfUnderlyingArray);
				activeDocument.activeLayer.applyMaximum(10);
				cmykChannelMixer();
				groupSelectedLayers (myCounter);
				activeDocument.activeLayer.merge();
				var theGroup = activeDocument.activeLayer;
				//applyLayerStyleStroke(5, 255, 0, 0);
				applyColorOverlay (255, 0, 0);
				theGroup.fillOpacity = 0;
				theSecond.blendMode = BlendMode.NORMAL;
				}
			catch (e) {secondShorter = true}
			}
		catch (e) {
			try {
				var theSecondPdf = app.open(myPDFFile2, pdfOpenOpts);
				theSecondPdf.close(SaveOptions.DONOTSAVECHANGES);
				alert (theFile2.name+" seems to have more pages than "+theFile1.name)
				}
			catch (e) {}
			myBreak = true
			};
		myCounter = myCounter + 1;
		};
	if (secondShorter == true) {alert (theFile1.name+" seems to have more pages than "+theFile2.name)};
/* reset dialogmodes */
	app.displayDialogs = DialogModes.ERROR;
	};
/* open pdf page */
function openPDFPage (myPDFFile, pdfOpenOpts, myCounter) {
var thePdf = app.open(myPDFFile, pdfOpenOpts);
thePdf.flatten();
thePdf.layers[0].isBackgroundLayer = false;
thePdf.layers[0].name = myPDFFile.name+"_"+myCounter;
return thePdf
};
/* filter-function for pdf-files */
function checkForPDF (theFile) {
if (theFile.name.slice(-4) == ".pdf" || theFile.constructor.name == "Folder") {return true}
else {return false}
};
////// reveal all //////
function revealAll () {
var idRvlA = charIDToTypeID( "RvlA" );
executeAction( idRvlA, undefined, DialogModes.NO );
};
////// layer via copy //////
function mergVisibleToNewLayer (){
var desc23 = new ActionDescriptor();
desc23.putBoolean( stringIDToTypeID( "duplicate" ), true );
executeAction( stringIDToTypeID( "mergeVisible" ), desc23, DialogModes.NO );
};
////// group //////
function groupSelectedLayers (theName) {
var desc159 = new ActionDescriptor(); 
var ref114 = new ActionReference(); 
var idlayer = stringIDToTypeID( "layer" );
var idordinal = stringIDToTypeID( "ordinal" );
var idtargetEnum = stringIDToTypeID( "targetEnum" );
var idnull = stringIDToTypeID( "null" );
var idname = stringIDToTypeID( "name" );
ref114.putEnumerated(idlayer, idordinal, idtargetEnum); 
desc159.putReference(idnull, ref114 );
desc159.putString(idname, "aaa" );
executeAction( stringIDToTypeID( "groupLayersEvent" ), desc159, DialogModes.NO );
var desc63 = new ActionDescriptor();
var ref37 = new ActionReference();
ref37.putEnumerated( idlayer, idordinal, idtargetEnum );
desc63.putReference( idnull, ref37 );
var desc64 = new ActionDescriptor();
desc64.putString(idname, theName);
desc63.putObject(stringIDToTypeID( "to" ), idlayer, desc64);
executeAction(stringIDToTypeID( "set" ), desc63, DialogModes.NO)
};
////// make stroke //////
function applyLayerStyleStroke (theWitdh, theR, theG, theB) {
// =======================================================
var idsetd = charIDToTypeID( "setd" );
var desc12 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref7 = new ActionReference();
var idPrpr = charIDToTypeID( "Prpr" );
var idLefx = charIDToTypeID( "Lefx" );
ref7.putProperty( idPrpr, idLefx );
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref7.putEnumerated( idLyr, idOrdn, idTrgt );
desc12.putReference( idnull, ref7 );
var idT = charIDToTypeID( "T   " );
var desc13 = new ActionDescriptor();
var idScl = charIDToTypeID( "Scl " );
var idPrc = charIDToTypeID( "#Prc" );
desc13.putUnitDouble( idScl, idPrc, 100.000000 );
var idFrFX = charIDToTypeID( "FrFX" );
var desc14 = new ActionDescriptor();
var idenab = charIDToTypeID( "enab" );
desc14.putBoolean( idenab, true );
var idStyl = charIDToTypeID( "Styl" );
var idFStl = charIDToTypeID( "FStl" );
desc14.putEnumerated( idStyl, idFStl, charIDToTypeID( "OutF" ) );
var idPntT = charIDToTypeID( "PntT" );
var idFrFl = charIDToTypeID( "FrFl" );
var idSClr = charIDToTypeID( "SClr" );
desc14.putEnumerated( idPntT, idFrFl, idSClr );
var idMd = charIDToTypeID( "Md  " );
var idBlnM = charIDToTypeID( "BlnM" );
var idNrml = charIDToTypeID( "Nrml" );
desc14.putEnumerated( idMd, idBlnM, idNrml );
var idOpct = charIDToTypeID( "Opct" );
var idPrc = charIDToTypeID( "#Prc" );
desc14.putUnitDouble( idOpct, idPrc, 100.000000 );
var idSz = charIDToTypeID( "Sz  " );
var idPxl = charIDToTypeID( "#Pxl" );
desc14.putUnitDouble( idSz, idPxl, theWitdh );
var idClr = charIDToTypeID( "Clr " );
var desc15 = new ActionDescriptor();
var idRd = charIDToTypeID( "Rd  " );
desc15.putDouble( idRd, theR );
var idGrn = charIDToTypeID( "Grn " );
desc15.putDouble( idGrn, theG );
var idBl = charIDToTypeID( "Bl  " );
desc15.putDouble( idBl, theB );
var idRGBC = charIDToTypeID( "RGBC" );
desc14.putObject( idClr, idRGBC, desc15 );
var idFrFX = charIDToTypeID( "FrFX" );
desc13.putObject( idFrFX, idFrFX, desc14 );
var idLefx = charIDToTypeID( "Lefx" );
desc12.putObject( idT, idLefx, desc13 );
executeAction( idsetd, desc12, DialogModes.NO );
};
////// set blend if settings for this and underlying //////
function blendIfThisAndUnderlying (thisNumbers, underlyingNumbers) {
// =======================================================
var idsetd = charIDToTypeID( "setd" );
var desc11 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref8 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref8.putEnumerated( idLyr, idOrdn, idTrgt );
desc11.putReference( idnull, ref8 );
var idT = charIDToTypeID( "T   " );
var desc12 = new ActionDescriptor();
var idBlnd = charIDToTypeID( "Blnd" );
var list3 = new ActionList();
var desc13 = new ActionDescriptor();
var idChnl = charIDToTypeID( "Chnl" );
var ref9 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idChnl = charIDToTypeID( "Chnl" );
var idGry = charIDToTypeID( "Gry " );
ref9.putEnumerated( idChnl, idChnl, idGry );
desc13.putReference( idChnl, ref9 );
var idSrcB = charIDToTypeID( "SrcB" );
desc13.putInteger( idSrcB, thisNumbers[0][0] );
var idSrcl = charIDToTypeID( "Srcl" );
desc13.putInteger( idSrcl, thisNumbers[0][1] );
var idSrcW = charIDToTypeID( "SrcW" );
desc13.putInteger( idSrcW, thisNumbers[0][2] );
var idSrcm = charIDToTypeID( "Srcm" );
desc13.putInteger( idSrcm, thisNumbers[0][3] );
var idDstB = charIDToTypeID( "DstB" );
desc13.putInteger( idDstB, underlyingNumbers[0][0] );
var idDstl = charIDToTypeID( "Dstl" );
desc13.putInteger( idDstl, underlyingNumbers[0][1] );
var idDstW = charIDToTypeID( "DstW" );
desc13.putInteger( idDstW, underlyingNumbers[0][2] );
var idDstt = charIDToTypeID( "Dstt" );
desc13.putInteger( idDstt, underlyingNumbers[0][3] );
var idBlnd = charIDToTypeID( "Blnd" );
list3.putObject( idBlnd, desc13 );
/*var desc14 = new ActionDescriptor();
var idChnl = charIDToTypeID( "Chnl" );
var ref10 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idChnl = charIDToTypeID( "Chnl" );
var idRd = charIDToTypeID( "Rd  " );
ref10.putEnumerated( idChnl, idChnl, idRd );
desc14.putReference( idChnl, ref10 );
var idSrcB = charIDToTypeID( "SrcB" );
desc14.putInteger( idSrcB, thisNumbers[1][0] );
var idSrcl = charIDToTypeID( "Srcl" );
desc14.putInteger( idSrcl, thisNumbers[1][1] );
var idSrcW = charIDToTypeID( "SrcW" );
desc14.putInteger( idSrcW, thisNumbers[1][2] );
var idSrcm = charIDToTypeID( "Srcm" );
desc14.putInteger( idSrcm, thisNumbers[1][3] );
var idDstB = charIDToTypeID( "DstB" );
desc14.putInteger( idDstB, underlyingNumbers[1][0] );
var idDstl = charIDToTypeID( "Dstl" );
desc14.putInteger( idDstl, underlyingNumbers[1][1] );
var idDstW = charIDToTypeID( "DstW" );
desc14.putInteger( idDstW, underlyingNumbers[1][2] );
var idDstt = charIDToTypeID( "Dstt" );
desc14.putInteger( idDstt, underlyingNumbers[1][3] );
var idBlnd = charIDToTypeID( "Blnd" );
list3.putObject( idBlnd, desc14 );
var desc15 = new ActionDescriptor();
var idChnl = charIDToTypeID( "Chnl" );
var ref11 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idChnl = charIDToTypeID( "Chnl" );
var idGrn = charIDToTypeID( "Grn " );
ref11.putEnumerated( idChnl, idChnl, idGrn );
desc15.putReference( idChnl, ref11 );
var idSrcB = charIDToTypeID( "SrcB" );
desc15.putInteger( idSrcB, thisNumbers[2][0] );
var idSrcl = charIDToTypeID( "Srcl" );
desc15.putInteger( idSrcl, thisNumbers[2][1] );
var idSrcW = charIDToTypeID( "SrcW" );
desc15.putInteger( idSrcW, thisNumbers[2][2] );
var idSrcm = charIDToTypeID( "Srcm" );
desc15.putInteger( idSrcm, thisNumbers[2][3] );
var idDstB = charIDToTypeID( "DstB" );
desc15.putInteger( idDstB, underlyingNumbers[2][0] );
var idDstl = charIDToTypeID( "Dstl" );
desc15.putInteger( idDstl, underlyingNumbers[2][1] );
var idDstW = charIDToTypeID( "DstW" );
desc15.putInteger( idDstW, underlyingNumbers[2][2] );
var idDstt = charIDToTypeID( "Dstt" );
desc15.putInteger( idDstt, underlyingNumbers[2][3] );
var idBlnd = charIDToTypeID( "Blnd" );
list3.putObject( idBlnd, desc15 );
var desc16 = new ActionDescriptor();
var idChnl = charIDToTypeID( "Chnl" );
var ref12 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idChnl = charIDToTypeID( "Chnl" );
var idBl = charIDToTypeID( "Bl  " );
ref12.putEnumerated( idChnl, idChnl, idBl );
desc16.putReference( idChnl, ref12 );
var idSrcB = charIDToTypeID( "SrcB" );
desc16.putInteger( idSrcB, thisNumbers[3][0] );
var idSrcl = charIDToTypeID( "Srcl" );
desc16.putInteger( idSrcl, thisNumbers[3][1] );
var idSrcW = charIDToTypeID( "SrcW" );
desc16.putInteger( idSrcW, thisNumbers[3][2] );
var idSrcm = charIDToTypeID( "Srcm" );
desc16.putInteger( idSrcm, thisNumbers[3][3] );
var idDstB = charIDToTypeID( "DstB" );
desc16.putInteger( idDstB, underlyingNumbers[3][0] );
var idDstl = charIDToTypeID( "Dstl" );
desc16.putInteger( idDstl, underlyingNumbers[3][1] );
var idDstW = charIDToTypeID( "DstW" );
desc16.putInteger( idDstW, underlyingNumbers[3][2] );
var idDstt = charIDToTypeID( "Dstt" );
desc16.putInteger( idDstt, underlyingNumbers[3][3] );
var idBlnd = charIDToTypeID( "Blnd" );
list3.putObject( idBlnd, desc16 );*/
desc12.putList( idBlnd, list3 );
var idLefx = charIDToTypeID( "Lefx" );
var desc17 = new ActionDescriptor();
var idScl = charIDToTypeID( "Scl " );
var idPrc = charIDToTypeID( "#Prc" );
desc17.putUnitDouble( idScl, idPrc, 423.333316 );
var idLefx = charIDToTypeID( "Lefx" );
desc12.putObject( idLefx, idLefx, desc17 );
var idLyr = charIDToTypeID( "Lyr " );
desc11.putObject( idT, idLyr, desc12 );
executeAction( idsetd, desc11, DialogModes.NO );
};
////// channel mixer //////
function cmykChannelMixer () {
var idpercentUnit = stringIDToTypeID( "percentUnit" );
var idchannelMixer = stringIDToTypeID( "channelMixer" );
var desc5 = new ActionDescriptor();
var idpresetKind = stringIDToTypeID( "presetKind" );
var idpresetKindType = stringIDToTypeID( "presetKindType" );
var idpresetKindCustom = stringIDToTypeID( "presetKindCustom" );
desc5.putEnumerated( idpresetKind, idpresetKindType, idpresetKindCustom );
var idmonochromatic = stringIDToTypeID( "monochromatic" );
desc5.putBoolean( idmonochromatic, true );
var idgray = stringIDToTypeID( "gray" );
var desc6 = new ActionDescriptor();
var idcyan = stringIDToTypeID( "cyan" );
desc6.putUnitDouble( idcyan, idpercentUnit, 25.000000 );
var idmagenta = stringIDToTypeID( "magenta" );
desc6.putUnitDouble( idmagenta, idpercentUnit, 25.000000 );
var idyellowColor = stringIDToTypeID( "yellowColor" );
desc6.putUnitDouble( idyellowColor, idpercentUnit, 25.000000 );
var idblack = stringIDToTypeID( "black" );
desc6.putUnitDouble( idblack, idpercentUnit, 25.000000 );
var idchannelMatrix = stringIDToTypeID( "channelMatrix" );
desc5.putObject( idgray, idchannelMatrix, desc6 );
executeAction( idchannelMixer, desc5, DialogModes.NO );
};
////// color overlay //////
function applyColorOverlay (theR, theG, theB) {
//selectLayerByID(myLayer, false);
// =======================================================
var desc5 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putProperty( stringIDToTypeID( "property" ), stringIDToTypeID( "layerEffects" ) );
var idlayer = stringIDToTypeID( "layer" );
var idordinal = stringIDToTypeID( "ordinal" );
var idtargetEnum = stringIDToTypeID( "targetEnum" );
ref1.putEnumerated( idlayer, idordinal, idtargetEnum );
//        ref1.putIdentifier( idlayer, myLayer );
desc5.putReference( stringIDToTypeID( "null" ), ref1 );
var desc6 = new ActionDescriptor();
var idscale = stringIDToTypeID( "scale" );
var idpercentUnit = stringIDToTypeID( "percentUnit" );
desc6.putUnitDouble( idscale, idpercentUnit, 416.666667 );
var desc7 = new ActionDescriptor();
var idenabled = stringIDToTypeID( "enabled" );
desc7.putBoolean( idenabled, true );
var idpresent = stringIDToTypeID( "present" );
desc7.putBoolean( idpresent, true );
var idshowInDialog = stringIDToTypeID( "showInDialog" );
desc7.putBoolean( idshowInDialog, true );
desc7.putEnumerated( stringIDToTypeID( "mode" ), stringIDToTypeID( "blendMode" ), stringIDToTypeID( "normal" ) );
var idcolor = stringIDToTypeID( "color" );
var desc8 = new ActionDescriptor();
var idred = stringIDToTypeID( "red" );
desc8.putDouble( idred, theR );
var idgrain = stringIDToTypeID( "grain" );
desc8.putDouble( idgrain, theG );
var idblue = stringIDToTypeID( "blue" );
desc8.putDouble( idblue, theB );
desc7.putObject( idcolor, stringIDToTypeID( "RGBColor" ), desc8 );
var idpercentUnit = stringIDToTypeID( "percentUnit" );
desc7.putUnitDouble( stringIDToTypeID( "opacity" ), idpercentUnit, 100.000000 );
desc6.putObject( stringIDToTypeID( "solidFill" ), stringIDToTypeID( "solidFill" ), desc7 );
desc5.putObject( stringIDToTypeID( "to" ), stringIDToTypeID( "layerEffects" ), desc6 );
executeAction( stringIDToTypeID( "set" ), desc5, DialogModes.NO );
};

Votes

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 ,
Mar 02, 2025 Mar 02, 2025

Copy link to clipboard

Copied

LATEST

Thanks, I am attaching a sample output . is it possible to get that output in Photoshop to identify difference ?

Votes

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