Copy link to clipboard
Copied
Could you show an example how to iterate image file lines pixel by pixel to detect is pixel line is completely "white" i.e. empty or not empty i.e. "not white".
So if line is full of white pixels then result is 0 if not then result is 1. Just for a sample.
The example is below. As you can observe, some lines are completely emty while othes is not. So how to iterate such an image in Photoshop script?
Try this version...
...#target photoshop;
app.bringToFront();
main();
function main(){
if(!documents.length) return;
try{
var doc = app.activeDocument;
app.displayDialogs = DialogModes.NO;
var strtRulerUnits = app.preferences.rulerUnits;
var strtTypeUnits = app.preferences.typeUnits;
app.preferences.rulerUnits = Units.PIXELS;
app.preferences.typeUnits = TypeUnits.PIXELS;
Left =0; Top = 0; Right = doc.width; Bottom =1;
var lineType=[];
for(var a = 0;a<doc.height; a++){
activeDocument.selection.select([[Left,Top],[R
Copy link to clipboard
Copied
You can try this:
#target photoshop
var doc = activeDocument
for(var i=0;i<doc.height;i++){
doc.selection.deselect();
getSelect (i, 0, i+1, doc.width)
if(doc.histogram[255]==parseInt (doc.width)){
checkSelet (i);
if(doc.selection.bounds[2]<doc.width){$.writeln(false)}
else{$.writeln(true)}
}
else{$.writeln(false)}
}
function getSelect(top,left,bottom,right){
var idsetd = charIDToTypeID( "setd" );
var desc6 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref1 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref1.putProperty( idChnl, idfsel );
desc6.putReference( idnull, ref1 );
var idT = charIDToTypeID( "T " );
var desc7 = new ActionDescriptor();
var idTop = charIDToTypeID( "Top " );
var idPxl = charIDToTypeID( "#Pxl" );
desc7.putUnitDouble( idTop, idPxl, top );
var idLeft = charIDToTypeID( "Left" );
var idPxl = charIDToTypeID( "#Pxl" );
desc7.putUnitDouble( idLeft, idPxl, left );
var idBtom = charIDToTypeID( "Btom" );
var idPxl = charIDToTypeID( "#Pxl" );
desc7.putUnitDouble( idBtom, idPxl, bottom );
var idRght = charIDToTypeID( "Rght" );
var idPxl = charIDToTypeID( "#Pxl" );
desc7.putUnitDouble( idRght, idPxl, right );
var idRctn = charIDToTypeID( "Rctn" );
desc6.putObject( idT, idRctn, desc7 );
executeAction( idsetd, desc6, DialogModes.NO );
}
function checkSelet(y){
var idIntW = charIDToTypeID( "IntW" );
var desc10 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref2 = new ActionReference();
var idChnl = charIDToTypeID( "Chnl" );
var idfsel = charIDToTypeID( "fsel" );
ref2.putProperty( idChnl, idfsel );
desc10.putReference( idnull, ref2 );
var idT = charIDToTypeID( "T " );
var desc11 = new ActionDescriptor();
var idHrzn = charIDToTypeID( "Hrzn" );
var idPxl = charIDToTypeID( "#Pxl" );
desc11.putUnitDouble( idHrzn, idPxl, 1 );
var idVrtc = charIDToTypeID( "Vrtc" );
var idPxl = charIDToTypeID( "#Pxl" );
desc11.putUnitDouble( idVrtc, idPxl, y );
var idPnt = charIDToTypeID( "Pnt " );
desc10.putObject( idT, idPnt, desc11 );
var idTlrn = charIDToTypeID( "Tlrn" );
desc10.putInteger( idTlrn, 0 );
var idAntA = charIDToTypeID( "AntA" );
desc10.putBoolean( idAntA, true );
executeAction( idIntW, desc10, DialogModes.NO );
}
Copy link to clipboard
Copied
where did u get it...
Copy link to clipboard
Copied
I wrote it. Just a word of warning, It won't detect a full line that's transparent. Placing a colored layer under the layer you're checking would work better.
Copy link to clipboard
Copied
I tried it with ps cs6 on 1 by 1 pixel document.
It only outputs false while pixel is white but if pixel is not white then there is an error
Copy link to clipboard
Copied
I'll have to take a look later and see if my CS6 still works.
Copy link to clipboard
Copied
Just shortened your code Chuck and it does work now in CS6.
#target photoshop
var doc = activeDocument
for(var i=0;i<doc.height;i++){
getSelect (i, 0, i+1, doc.width);
if(doc.histogram[255]==Number (doc.width)) $.writeln(true);
else $.writeln(false);
}
doc.selection.deselect();
function getSelect(top,left,bottom,right){
var desc6 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putProperty( charIDToTypeID('Chnl'), charIDToTypeID('fsel') );
desc6.putReference( charIDToTypeID('null'), ref1 );
var desc7 = new ActionDescriptor();
desc7.putUnitDouble( charIDToTypeID('Top '), charIDToTypeID('#Pxl'), top );
desc7.putUnitDouble( charIDToTypeID('Left'), charIDToTypeID('#Pxl'), left );
desc7.putUnitDouble( charIDToTypeID('Btom'), charIDToTypeID('#Pxl'), bottom );
desc7.putUnitDouble( charIDToTypeID('Rght'), charIDToTypeID('#Pxl'), right );
desc6.putObject( charIDToTypeID('T '), charIDToTypeID('Rctn'), desc7 );
executeAction( charIDToTypeID('setd'), desc6, DialogModes.NO );
};
Copy link to clipboard
Copied
Thanks. With PS 2017, it was registering transparent as white with the histogram. A full lime of transparent might throw that error.
Copy link to clipboard
Copied
Yes transparency does show as white in the histogram, it would take a lot more code to work out those lines.
Copy link to clipboard
Copied
not sure is the code works properly...
for example, with the following sample picture (10 px height)
it outputs in javascript console
false
false
false
false
but for I understand it it should outputs next
false
false
true
false
true
false
false
true
false
false
because there are 10 lines in the picture and only three lines contains not white pixels
note that transparency does not matter here because source image will be flat
Am I describe the idea clear?
Copy link to clipboard
Copied
Try this version...
#target photoshop;
app.bringToFront();
main();
function main(){
if(!documents.length) return;
try{
var doc = app.activeDocument;
app.displayDialogs = DialogModes.NO;
var strtRulerUnits = app.preferences.rulerUnits;
var strtTypeUnits = app.preferences.typeUnits;
app.preferences.rulerUnits = Units.PIXELS;
app.preferences.typeUnits = TypeUnits.PIXELS;
Left =0; Top = 0; Right = doc.width; Bottom =1;
var lineType=[];
for(var a = 0;a<doc.height; a++){
activeDocument.selection.select([[Left,Top],[Right,Top],[Right,Bottom],[Left,Bottom]], SelectionType.REPLACE, 0, false);
Top++; Bottom++;
var area = activeDocument.histogram;
if(area[255] != doc.width.value){
lineType.push(1);
}else{
lineType.push(0);
}}
activeDocument.selection.deselect();
var w = new Window("dialog","Lines",undefined, {closeButton: false});
w.dl = w.add("dropdownlist");
for(var z in lineType){w.dl.add("item", "Line " +(Number(z)+1) + " = " + lineType
);} w.dl.selection=0;
w.b = w.add("button",undefined,"Okay");
w.b.onClick = function(){w.close(0);}
w.show();
}catch(e){}
finally{
app.preferences.rulerUnits = strtRulerUnits;
app.preferences.typeUnits = strtTypeUnits;
}
};
Copy link to clipboard
Copied
For some reason the code works too slow on real size A4 300 dpi documents... Maybe there is other fast logic to complete the same process?
Copy link to clipboard
Copied
Sorry no there isn't.
Matlab might be the way to go though as Photoshop is not good at this sort of thing.
Copy link to clipboard
Copied
Have you tried the RAW code?
Copy link to clipboard
Copied
Yes, I have tried the RAW code. It works allmost identical if not longer and there were some troubles with finishing the process.
Copy link to clipboard
Copied
Can you provide a file for testing?
Copy link to clipboard
Copied
In my test with an 8bit RGB image (210mm x 297mm at 300ppi) Supermerlin’s Script took only about half the time the Raw one did (roughly 27sec and 54sec).
So the advantage I had noticed in previous testing was apparently owed to some intermediate image size …
Copy link to clipboard
Copied
Using the data from a RAW duplicate might be faster especially for larger images.
// based on code by paul riggott;
// 2017, use it at your own risk;
#target photoshop
File.prototype.readByte = function() {
return this.read(1).charCodeAt(0);
};
function convertByteToSignedByte(num){
var dec = (num | (num % 256))-128
return dec;
};
function convertByteToLum( num){
var dec = Math.round((num/256)*100);
return dec;
};
function main(){
if(!documents.length) return;
if(activeDocument.mode != DocumentMode.LAB) {
var theCopy = activeDocument.duplicate("theCopy", true);
var desc3 = new ActionDescriptor();
desc3.putClass( charIDToTypeID( "T " ), charIDToTypeID( "LbCM" ) );
executeAction( charIDToTypeID( "CnvM" ), desc3, DialogModes.NO );
}
var Name = decodeURI(app.activeDocument.name).replace(/\.[^\.]+$/, '');
try{
var Path = activeDocument.path;
}catch(e){var Path = '~/Desktop';}
var rawFile = new File(Path +"/"+Name +".raw");
saveAsRaw(rawFile);
var len = 0;
var W = activeDocument.width.as('px');
CountW=0;
CountH=0;
rawFile.encoding = 'BINARY';
rawFile.open('r');
var theArray = new Array;
//////////////////
var theCheck = true;
while(!rawFile.eof){
var theL = convertByteToLum(rawFile.readByte());
convertByteToSignedByte(rawFile.readByte());
convertByteToSignedByte(rawFile.readByte());
if (theL != 100) {theCheck = false};
len++;
if(len % W == 0){
CountH++;
CountW=0;
theArray.push(theCheck);
var theCheck = true;
}
else{
CountW++;
}
};
rawFile.close();
rawFile.remove();
try {theCopy.close(SaveOptions.DONOTSAVECHANGES)}
catch (e) {};
alert ("line white\n"+theArray.join("\n"))
};
//var time1 = Number(timeString());
main();
//var time2 = Number(timeString());
//alert("time: "+((time2-time1)/1000)+" seconds\nstart "+time1+"\nend "+time2);
function saveAsRaw(file) {
var desc1 = new ActionDescriptor();
var desc2 = new ActionDescriptor();
desc2.putString( charIDToTypeID('FlCr'), "8BIM" );
desc2.putBoolean( charIDToTypeID('ChnI'), true );
desc1.putObject( charIDToTypeID('As '), charIDToTypeID('Rw '), desc2 );
desc1.putPath( charIDToTypeID('In '), new File( file ) );
desc1.putBoolean( charIDToTypeID('Cpy '), true );
executeAction( charIDToTypeID('save'), desc1, DialogModes.NO );
};
////// function to get the date //////
function timeString () {
var now = new Date();
return now.getTime()
};