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

JS/PS CS3: identify single pixels sticking out

Community Expert ,
Jan 28, 2010 Jan 28, 2010

Copy link to clipboard

Copied

In a bitmap, is it possible to identify single pixels sticking out from a shape? Let's say I have this black shape in a black-and-white bitmap:

   xxxxxxxx

   xxxxxxxx

   xxxxxxxx

   xxxxxxxx

        x

an 8 by 4 rectangle with one pixel sticking out from the bottom. Question is, can I find such pixels using a script (JS) and make it white?

Thanks,

Peter

TOPICS
Actions and scripting

Views

4.2K

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
Adobe
Guru ,
Jan 28, 2010 Jan 28, 2010

Copy link to clipboard

Copied

Peter, I don't know a method for working with a bitmap image. (there is NO histogram in bitmap mode) Would you be able to switch modes to grayscale and back? If so then this may work although Im NOT sure if I've overlooked something here. I only tested with a small file. I would not expect this kind of thing to be fast.

$.sleep(500); & WaitForRedraw(); can come out there just so I can see whats happening in the GUI.

#target photoshop

app.bringToFront();

function main() {

if (app.documents.length == 0) {

alert('You have NO document open?');

return;

}

var whiteRef = new SolidColor();

whiteRef.rgb.red = 255;

whiteRef.rgb.green = 255;

whiteRef.rgb.blue = 255;

var docRef = app.activeDocument;

with (docRef) {

// Horizontal selection

selection.select([[0, 0], [width , 0], [width, 1], [0, 1]]);

if (channels[0].histogram[0] == 1) {

alert('Single Pixel');

selection.fill(whiteRef);

}

for (var i = 0; i < height-1; i++) {

selection.translateBoundary(0, 1);

$.sleep(500);

WaitForRedraw();

if (channels[0].histogram[0] == 1) {

alert('Single Pixel');

selection.fill(whiteRef);

}

}

// Vertical selection

selection.select([[0, 0], [1 , 0], [1, height], [0, height]]);

if (channels[0].histogram[0] == 1) {

alert('Single Pixel');

selection.fill(whiteRef);

}

for (var i = 0; i < width-1; i++) {

selection.translateBoundary(1, 0);

$.sleep(500);

WaitForRedraw();

if (channels[0].histogram[0] == 1) {

alert('Single Pixel');

selection.fill(whiteRef);

}

}

selection.deselect();

}

};

main();

// Redraw the Screen

function WaitForRedraw() {

  var eventWait = charIDToTypeID('Wait');

  var enumRedrawComplete = charIDToTypeID('RdCm');

  var typeState = charIDToTypeID('Stte');

  var keyState = charIDToTypeID('Stte');

  var desc = new ActionDescriptor();

  desc.putEnumerated(keyState, typeState, enumRedrawComplete);

  executeAction(eventWait, desc, DialogModes.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 Expert ,
Jan 28, 2010 Jan 28, 2010

Copy link to clipboard

Copied

Muppet,

Thanks for this. Temporarily converting to greyscale is not a problem. But unfortunately, your script breaks on this line:

selection.translateBoundary (0, 1);

with the error message "The document does not contain a selection". When I step through the script, I can see that it selects the first row of pixels, takes the first iteration in the for-loop fine, then in the second iteration the script breaks with the above-mentioned error message. So it looks as if the selection gets undone.

Scanning for lines with one pixel which are otherwise empty is not the right approach, though. I realise that my example may have led you to believe that it was, so let me give you a real example (see the screenshot). The line that the single pixel sits on has some other pixels set as well. So ideally, I would want to be able to look for a pixel that has one side adjacent to its own colour, the others to the opposite colour. In other words, if you're a black pixel and are surrounded by three white pixels and one black pixel, then you're single and you should change colour.

Sorry I didn't state this better earlier.

Thanks,

Peter

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
Valorous Hero ,
Jan 28, 2010 Jan 28, 2010

Copy link to clipboard

Copied

Just a theory..

If it is a rectangle shape you might be able to :-

Select the area

Get the selection bounds

Make a work path set to 1 (One of the bounds should be one less than the selection bounds) also check that there is only 4 pathpoints.

Then compare each bound, then you could make a new selection and fill.

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 Expert ,
Jan 28, 2010 Jan 28, 2010

Copy link to clipboard

Copied

Paul,

Thanks for the suggestion. But I'd prefer not to make a selection -- I've got hundreds of these things...

Peter

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
Valorous Hero ,
Jan 28, 2010 Jan 28, 2010

Copy link to clipboard

Copied

Ah now I see, another idea.

Select all the black ..

function selectBlack() {
    var desc63 = new ActionDescriptor();
    desc63.putInteger( charIDToTypeID('Fzns'), 13 );
        var desc64 = new ActionDescriptor();
        desc64.putDouble( charIDToTypeID('Lmnc'), 0.000000 );
        desc64.putDouble( charIDToTypeID('A   '), 0.000000 );
        desc64.putDouble( charIDToTypeID('B   '), 0.000000 );
    desc63.putObject( charIDToTypeID('Mnm '), charIDToTypeID('LbCl'), desc64 );
        var desc65 = new ActionDescriptor();
        desc65.putDouble( charIDToTypeID('Lmnc'), 0.000000 );
        desc65.putDouble( charIDToTypeID('A   '), 0.000000 );
        desc65.putDouble( charIDToTypeID('B   '), 0.000000 );
    desc63.putObject( charIDToTypeID('Mxm '), charIDToTypeID('LbCl'), desc65 );
    desc63.putInteger( stringIDToTypeID('colorModel'), 0 );
    executeAction( charIDToTypeID('ClrR'), desc63, DialogModes.NO );
};


Make a work path tolerance of 1, make selection from work path, invert and fill with 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
Guru ,
Jan 28, 2010 Jan 28, 2010

Copy link to clipboard

Copied

Paul,

Do you get a stairstep( corner points only ) path that way. When I try the path has smooth points and doesn't follow the shape. Do you know if there is a preference?

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
Valorous Hero ,
Jan 29, 2010 Jan 29, 2010

Copy link to clipboard

Copied

Yes I'm getting a staircase, but not selecting single pixels. Using workpaths can produce some strange results, I did a test with a rectangle with one pixel sticking out on one side at a time, this code worked for the Left, Right and Bottom but the Top was totally screwed up?

#target photoshop
main();

function main(){
DEBUG=true;
selectBlack();
var savedState = activeDocument.activeHistoryState;
var startRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var savedState = activeDocument.activeHistoryState;
try{
var SB = activeDocument.selection.bounds;
}catch(e){alert(e+" \r"+e.line);
     activeDocument.activeHistoryState = savedState;
    return;
}
activeDocument.selection.makeWorkPath(1.0);
var workPath = activeDocument.pathItems.getByName("Work Path");
return;
if(workPath.subPathItems[0].pathPoints.length != 4){
    activeDocument.activeHistoryState = savedState;
    return;
}

var PB=[];
if(DEBUG){
$.writeln( workPath.subPathItems[0].pathPoints[0].anchor);
$.writeln( workPath.subPathItems[0].pathPoints[1].anchor);
$.writeln( workPath.subPathItems[0].pathPoints[2].anchor);
$.writeln( workPath.subPathItems[0].pathPoints[3].anchor);
}
PB[0] = workPath.subPathItems[0].pathPoints[0].anchor[0]; //Left
PB[1] = workPath.subPathItems[0].pathPoints[0].anchor[1]; //Top
PB[2] = workPath.subPathItems[0].pathPoints[1].anchor[0]; //Right
PB[3] = workPath.subPathItems[0].pathPoints[2].anchor[1]; //Bottom
var side = 9;
if(Number(SB[0]) != Number(PB[0]) ) side = 0;
if(Number(SB[1]) != Number(PB[1]) ) side = 1;
if(Number(SB[2]) != Number(PB[2]) ) side = 2;
if(Number(SB[3]) != Number(PB[3]) ) side = 3;
activeDocument.activeHistoryState = savedState;
activeDocument.selection.deselect();
if(DEBUG){
$.writeln(SB.toString());
$.writeln(PB.toString());
}
switch(side){
    case 0: selSide(PB[0]-1,PB[1],PB[0],PB[3]); break;
    case 1: selSide(PB[0],PB[1]-1,PB[2],PB[1]); break;
    case 2: selSide(PB[2],PB[1],PB[2]+1,PB[3]); break;
    case 3: selSide(PB[0],PB[3],PB[2],PB[3]+1); break;
    default : break;
    }
app.preferences.rulerUnits = startRulerUnits;
}

function selSide(Left,Top,Right,Bottom){
activeDocument.selection.select([[Left,Top],[Right,Top],[Right,Bottom],[Left,Bottom]], SelectionType.REPLACE, 0, false);
var White = new SolidColor;
White.rgb.hexValue = 'ffffff';
activeDocument.selection.fill(White);
activeDocument.selection.deselect();
}
function selectBlack() {
    var desc63 = new ActionDescriptor();
    desc63.putInteger( charIDToTypeID('Fzns'), 13 );
        var desc64 = new ActionDescriptor();
        desc64.putDouble( charIDToTypeID('Lmnc'), 0.000000 );
        desc64.putDouble( charIDToTypeID('A   '), 0.000000 );
        desc64.putDouble( charIDToTypeID('B   '), 0.000000 );
    desc63.putObject( charIDToTypeID('Mnm '), charIDToTypeID('LbCl'), desc64 );
        var desc65 = new ActionDescriptor();
        desc65.putDouble( charIDToTypeID('Lmnc'), 0.000000 );
        desc65.putDouble( charIDToTypeID('A   '), 0.000000 );
        desc65.putDouble( charIDToTypeID('B   '), 0.000000 );
    desc63.putObject( charIDToTypeID('Mxm '), charIDToTypeID('LbCl'), desc65 );
    desc63.putInteger( stringIDToTypeID('colorModel'), 0 );
    executeAction( charIDToTypeID('ClrR'), desc63, DialogModes.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 Expert ,
Jan 29, 2010 Jan 29, 2010

Copy link to clipboard

Copied

Paul,

Thanks for the great effort. I get the same results as you, unfortunately. It excludes the single pixels, but some other things as well. But anyway, it's been educational. I'll dig into the path and pathPoints and see if there's anything there. In the meantime, if you find anything I'd be grateful if you'd let me know.

Thanks again,

Peter

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
Guru ,
Jan 29, 2010 Jan 29, 2010

Copy link to clipboard

Copied

artLayers[0].applyMaximum(1);

artLayers[0].applyMinimum(1);

May proved you a get out of jail card if odd pixels are stranded along edges… At least this one would be fast…

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
Guru ,
Jan 29, 2010 Jan 29, 2010

Copy link to clipboard

Copied

When I make a path from a selection I don't get stairstep paths. And I can't find a way to make Photoshop create one. I deleted my preferences - no joy.

Anyone have any ideas?

attached is an example path made from a selection. The image was similar to the one posted but sized so that each stray block was 1 px

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
Guru ,
Jan 29, 2010 Jan 29, 2010

Copy link to clipboard

Copied

Mike, I get the same as you no matter what.

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
Guru ,
Jan 29, 2010 Jan 29, 2010

Copy link to clipboard

Copied

That is good to know. I was beginning to think there was something wrong with my install of Photoshop.

I wonder why it creates a stairstep path for some.

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
Guru ,
Jan 30, 2010 Jan 30, 2010

Copy link to clipboard

Copied

Mike, I have changed all sorts of settings whilst trying to do this and never been able to work it out. If you don't mind using another CS app then you should be able to get pixel perfect vectors (well as close as I can work out and its reliable) that you could paste back to Photoshop. Illustrator has a great tracing function that is fully scriptable. Here is an example for a black & white trace… In my tests I used a bitmap converted to grayscale to place n trace… Takes a few seconds but very neat…

#target illustrator

var docRef = app.activeDocument;

with (docRef) {

var thisImage = placedItems[0].trace();

redraw();

// Get tracing options object

var thisTrace = thisImage.tracing.tracingOptions;

// Adjust the properties

with (thisTrace) {

cornerAngle = 90;

fills = true;

livePaintOutput = false;

minArea = 1;

pathFitting = 0.0;

preprocessBlur = 0.0;

resample = false;

strokes = false;

threshold = 128;

tracingMode = TracingModeType.TRACINGMODEBLACKANDWHITE;

viewRaster = ViewRasterType.TRACINGVIEWRASTERTRANSPARENTIMAGE;

viewVector = ViewVectorType.TRACINGVIEWVECTOROUTLINESWITHTRACING;

}

var thisGroup = thisImage.tracing.expandTracing();

redraw();

with (thisGroup) {

// Remove the white path items

for (var i = pathItems.length-1; i >= 0; i--) {

if (pathItems.fillColor.gray == 0) {

pathItems.remove();

}

}

// Remove the white compound path items

for (var i = compoundPathItems.length-1; i >= 0; i--) {

if (compoundPathItems.pathItems[0].fillColor.gray == 0) {

compoundPathItems.remove();

}

}

// Ungroup the paths

for (var i = pageItems.length-1; i >= 0; i--) {

pageItems.move(thisGroup, ElementPlacement.PLACEBEFORE);

}

}

// Make all the points angled corners

for (var i = 0; i < pathItems.length; i++) {

for (var j = 0; j < pathItems.pathPoints.length; j++) {

pathItems.pathPoints.pointType = PointType.CORNER;

pathItems.pathPoints.leftDirection = pathItems.pathPoints.anchor;

pathItems.pathPoints.rightDirection = pathItems.pathPoints.anchor;

}

}

redraw();

}

I've still got some work to do on this yet as I would like to remove all the unnecessary path points. I think Im going to need some trigonometry to work out if the path changes direction but I haven't used trig since school n that was some time ago…

Might also be of use to Peter depending on what his bitmaps were being used for could use illustrator .ai files instead.

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
Guru ,
Jan 30, 2010 Jan 30, 2010

Copy link to clipboard

Copied

Thanks Mark. I was more troubled by my paths being wrong than the script not working. But it's good to know how to get a path that exactly matches the selection when I need one.

BTW, I don't think you need trig to determine if the path changes direction if all the points are corner points. You just need to compare three points at a point. The prev, current, and next. If the x is the same in all three it's a horz line. If the y is the same, it's vert. But working out the logic of the condition check may be as hard as forgotten trig. This is not tested.

var isHorz = ( Math.max(pathPoint[c-1].anchor[0],pathPoint.anchor[0],pathPoint[c+1].anchor[0])==pathPoint.anchor[0] );

var isVert = ( Math.max(pathPoint[c-1].anchor[1],pathPoint.anchor[1],pathPoint[c+1].anchor[1])==pathPoint.anchor[1] );

if( !isHorz || !isVert ) alert('direction change');

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
Guru ,
Jan 30, 2010 Jan 30, 2010

Copy link to clipboard

Copied

Mike, Thanks I will look at that. I went with the trig as this will be part of some other things I may need for AI. I got close but NO cigar. I could not get my head around a clean way to check last-zero-first pathpoints as part of the the loop!!! So one or two points remain that are NOT really needed. Here is how I was trying…

#target illustrator

var docRef = app.activeDocument;

with (docRef) {

var thisImage = placedItems[0].trace();

redraw();

// Get tracing options object

var thisTrace = thisImage.tracing.tracingOptions;

// Adjust the properties

with (thisTrace) {

cornerAngle = 90;

fills = true;

livePaintOutput = false;

minArea = 1;

pathFitting = 0.0;

preprocessBlur = 0.0;

resample = false;

strokes = false;

threshold = 128;

tracingMode = TracingModeType.TRACINGMODEBLACKANDWHITE;

viewRaster = ViewRasterType.TRACINGVIEWRASTERTRANSPARENTIMAGE;

viewVector = ViewVectorType.TRACINGVIEWVECTOROUTLINESWITHTRACING;

}

var thisGroup = thisImage.tracing.expandTracing();

redraw();

with (thisGroup) {

// Remove the white path items

for (var i = pathItems.length-1; i >= 0; i--) {

if (pathItems.fillColor.gray == 0) {

pathItems.remove();

}

}

// Remove the white compound path items

for (var i = compoundPathItems.length-1; i >= 0; i--) {

if (compoundPathItems.pathItems[0].fillColor.gray == 0) {

compoundPathItems.remove();

}

}

// Ungroup the paths

for (var i = pageItems.length-1; i >= 0; i--) {

pageItems.move(thisGroup, ElementPlacement.PLACEBEFORE);

}

}

// Make all the points angled corners

for (var i = 0; i < pathItems.length; i++) {

for (var j = 0; j < pathItems.pathPoints.length; j++) {

pathItems.pathPoints.pointType = PointType.CORNER;

pathItems.pathPoints.leftDirection = pathItems.pathPoints.anchor;

pathItems.pathPoints.rightDirection = pathItems.pathPoints.anchor;

}

}

// Remove unwanted points (NOT quite right!!! but close)

for (var i = 0; i < pathItems.length; i++) {

for (var j = pathItems.pathPoints.length-2; j >= 1; j--) {

var pointAfter = pathItems.pathPoints[j + 1].anchor;

var pointBefore = pathItems.pathPoints[j - 1].anchor;

var myAngle = inverseArcTan(pointAfter, pointBefore);

if (myAngle == 0 || myAngle == 90 || myAngle == -90) {

pathItems.pathPoints.remove();

}

}

}

redraw();

}

function inverseArcTan(xy1, xy2) {

// Opposite & Adjacent Sides

var oppSide = (xy2[1] - xy1[1]);

var adjSide = (xy2[0] - xy1[0]);

// Radians to Degrees

var myAngle = (Math.atan(oppSide / adjSide)) * (180 / Math.PI);

return myAngle;

}

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
Guru ,
Jan 30, 2010 Jan 30, 2010

Copy link to clipboard

Copied

For me, it's too much math and too much to keep track of to do something like this in a script.

For the first point test, couldn't you use the lenght offset as the pointBefore and for the last use the start offset for pointAfter.

But  I question when you delete the point doesn't that change the pathPoints length and thereby effect pointAfter and pointBefore? Also doesn't deleting a point chage angle of the prev and next point?

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 Expert ,
Jan 31, 2010 Jan 31, 2010

Copy link to clipboard

Copied

Mark,

> Might also be of use to Peter depending on what his bitmaps were being used for could use illustrator .ai files instead.

ai files wouldn't be a problem. This is for a book I'm working on about a man who contributed a lot to the development of stenography in the 17th century). Each symbol he devised was scanned for the authors, but not particularly well and at too low a resolution. Rescanning is not an option, apparently, and I've been polishing up the files manually. I've scripted some things (trimming, bitmapping), and the single-pixel removal would be nice too. As there are 550 of these, I want to batch-process as much as possible.

As I said, this thread has been very educational for me so far -- thanks for that (and to Michael).

Peter

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
Valorous Hero ,
Jan 31, 2010 Jan 31, 2010

Copy link to clipboard

Copied

Have you tried Marks method yet?

activeDocument.activeLayer.applyMaximum(4);
activeDocument.activeLayer.applyMinimum(4);

It seems to work fine, just experiment with the values.

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
Guru ,
Jan 31, 2010 Jan 31, 2010

Copy link to clipboard

Copied

Paul this worked for me as a batch process on the mac. Inverse filter again inverse back should clean out what would have been stray white pixels.

#target photoshop

app.bringToFront();

while (app.documents.length) {

  app.activeDocument.close(SaveOptions.PROMPTTOSAVECHANGES);

}

var defaultFolder = new Folder ('~/Desktop');

var inputFolder = defaultFolder.selectDlg('Please select your Folder of Bitmap files…');

var outputFolder = defaultFolder.selectDlg('Please Make/Select a Folder to save Cleaned up files to…');

if (inputFolder != null && outputFolder != null) {

var fileList = inputFolder.getFiles(fileFiltering);

if (fileList.length > 0) {

main(fileList);

} else {

alert('This Folder contained NO Photoshop Tiff files!');

}

} else {

alert('A Required folder was NOT chosen!!!');

}

// Main Photoshop file processing

function main(fileObjs) {

with (app) {

displayDialogs = DialogModes.NO;

for (var i = 0; i < fileObjs.length; i++) {

if (fileList instanceof File) {

open(fileObjs);

var docRef = activeDocument;

with (docRef) {

var baseName = app.activeDocument.name.slice(0,-4);

if (mode != DocumentMode.GRAYSCALE) changeMode(ChangeMode.GRAYSCALE);

docRes = resolution;

$.write(docRes + '\n');

// Cleans single pixels

artLayers[0].applyMaximum(1); // Adjust as required

artLayers[0].applyMinimum(1); // Ditto

artLayers[0].invert();

artLayers[0].applyMaximum(1); // Ditto

artLayers[0].applyMinimum(1); // Ditto

artLayers[0].invert();

var thisBitmap = bitmapOptions(docRes)

changeMode(ChangeMode.BITMAP, thisBitmap);

var newFilePath = new File(outputFolder + '/' + baseName + '.tif');

        SaveFileasTIFF(newFilePath, false, TIFFEncoding.TIFFLZW, false, false, false);

        close(SaveOptions.DONOTSAVECHANGES);

}

}

}

}

}

function bitmapOptions(res) {

  bitOptions = new BitmapConversionOptions();

//bitOptions.angle = 0;

//bitOptions.frequency = 150;

bitOptions.method = BitmapConversionType.HALFTHRESHOLD;

//bitOptions.pattenName = '';

bitOptions.resolution = res;

bitOptions.shape = BitmapHalfToneType.SQUARE;

return bitOptions;

}

function SaveFileasTIFF(saveFile, aC, iC, la, sC, tr) {

  tiffSaveOptions = new TiffSaveOptions();

  tiffSaveOptions.alphaChannels = aC;

  tiffSaveOptions.byteOrder = ByteOrder.MACOS;

  tiffSaveOptions.embedColorProfile = true;

  tiffSaveOptions.imageCompression = iC;

  tiffSaveOptions.layers = la;

  tiffSaveOptions.spotColors = sC;

  tiffSaveOptions.transparency = tr;

  activeDocument.saveAs(saveFile, tiffSaveOptions, true, Extension.LOWERCASE);

}

// Mac ONLY filtering (Photoshop Tiff's)

function fileFiltering(fileObj) {

if (fileObj.creator == '8BIM' && fileObj.type == 'TIFF') {

return true;

} else {

return false;

}

}

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
Guru ,
Jan 31, 2010 Jan 31, 2010

Copy link to clipboard

Copied

Oh, I had a question to ask too… Im CS2 and for reasons I can't work out I can't…

$.writeIn('Foo'); // Returns '$.writeIn is not a function'

But I can…

$.write('Foo' + '\n');

Am I just being thick here!!!?

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
Valorous Hero ,
Jan 31, 2010 Jan 31, 2010

Copy link to clipboard

Copied

Nice Mark, I have just copied your $.writeIn('Foo'); and pasted into ESTK and it pastes in as a capitol "I"

it should be all lowercase $.writeln('Foo');

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
Guru ,
Feb 01, 2010 Feb 01, 2010

Copy link to clipboard

Copied

Time to go to specsavers I think… Im spending too much time looking at my screen… TVM Paul.

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 Expert ,
Feb 01, 2010 Feb 01, 2010

Copy link to clipboard

Copied

Mark,

That's absolutely fabulous! This works very well. I noticed though that when single pixels are at the edge, the whole line is made black. Suppose you have something like the top picture in the screenshot. Your script changes that to what you see in the second part of the screenshot. I don't know how difficult it is to cope with that in your script, but a workaround I found is to add a two-pixel border, run the script, then remove the border. That does the trick.

I also noticed that if you comment out the second pair of applyMin/Max, so that you get this:

artLayers[0].applyMaximum (1); // Adjust as required
artLayers[0].applyMinimum (1); // Ditto
artLayers[0].invert ();
artLayers[0].invert ();

Any white single-pixel "inlets" are left alone. This makes for a very flexible script.

Thanks very much for this script!

Regards,

Peter

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
Guru ,
Feb 01, 2010 Feb 01, 2010

Copy link to clipboard

Copied

Peter, before I recalled this old filter method. I tried another pixel selection where I would use test histogram expand retest histogram contract.

It was painfully slow so I did not bother to post. But to get that to work I also had to increase canvas +4 pixels to get the edges right then resize back. Happy its been of use…

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