Histogram mean value does not change in loop - javascript

I wrote a script to compare my top layer set to difference blend mode against 3 other layers. The bottom layer is an exact copy of the top layer. I look at the documents histogram, check to see if the mean < 1 (later I'm going to account for a little variance, hence 1), color the layer in the layer palette red and turn the layer off....repeat. The problem I am having is that my mean values for each iteration remain the same. I have written the files to a csv so I could debug the issue and I can't figure out why this is occurring.
#target photoshop
// call the source document
var srcDoc = app.activeDocument;
var check = srcDoc.artLayers.getByName("check");
var layers = srcDoc.layers;
var docHisto = srcDoc.histogram;
//var Name = app.activeDocument.name.replace(/\.[^\.]+$/,'');
//var Ext = decodeURI(app.activeDocument.name).replace(/^.*\./,'');
//var Path=app.activeDocument.path;
startRulerUnits = app.preferences.rulerUnits;
startTypeUnits = app.preferences.typeUnits;
var original_units = app.preferences.rulerUnits;
//app.preferences.rulerUnits = Units.PERCENT;
//width and height of image
var imageWidth = srcDoc.width.as('px');
var imageWidth = srcDoc.width.value;
var imageHeight = srcDoc.height.as('px');
var imageHeight = srcDoc.height.value;
var numPixels = imageWidth*imageHeight;
var layNum = srcDoc.artLayers.length;
srcDoc.activeLayer = check;
check.blendMode = BlendMode.DIFFERENCE;
for (var i = 1; i < layNum; ++i) {
var meanval = EvalHisto(docHisto, i) ;
alert(meanval)
if (meanval < 1){
alert("same");
srcDoc.activeLayer = layers[i];
layercolor("red");
}
layers[i].visible = false;
}
function layercolor(colour) {
switch (colour.toLocaleLowerCase()){
case 'red': colour = 'Rd '; break;
case 'orange' : colour = 'Orng'; break;
case 'yellow' : colour = 'Ylw '; break;
case 'yellow' : colour = 'Ylw '; break;
case 'green' : colour = 'Grn '; break;
case 'blue' : colour = 'Bl '; break;
case 'violet' : colour = 'Vlt '; break;
case 'gray' : colour = 'Gry '; break;
case 'none' : colour = 'None'; break;
default : colour = 'None'; break;
}
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
desc.putReference( charIDToTypeID('null'), ref );
var desc2 = new ActionDescriptor();
desc2.putEnumerated( charIDToTypeID('Clr '), charIDToTypeID('Clr '), charIDToTypeID(colour) );
desc.putObject( charIDToTypeID('T '), charIDToTypeID('Lyr '), desc2 );
executeAction( charIDToTypeID('setd'), desc, DialogModes.NO );
};
function EvalHisto(histogram, i) {
var mean = 0;
var total = 0;
var luminosity = srcDoc.histogram;
var red = srcDoc.channels["Red"].histogram;
var green = srcDoc.channels["Green"].histogram;
var blue = srcDoc.channels["Blue"].histogram;
var datFile = new File("~/Desktop/Histogram" + i + ".csv");
datFile.open("e");
datFile.writeln("Level,Luminosity,Red,Green,Blue, Mean\r");
for (var n = 0; n < histogram.length; n++) {
total = total + histogram[n]; //calculate total histogram value over the 255 color space
}
for (var m = 0; m < histogram.length; m++){
mean = mean + (m*histogram[m]/total); //calculate running mean of intensity
datFile.writeln(m + "," + luminosity[m] + "," + red[m] + "," + green[m] + "," + blue[m] + "," + mean + "\r");
}
datFile.close();
return mean;
};

I found the mistake, I needed to move
var docHisto = srcDoc.histogram;
into my layer loop, otherwise I would only ever be finding the histogram resulting from the first layer and second layer blend.

Related

Paint by number Illustrator script

I am from supercoloring and we decided to convert our vector illustrations in color to color by number worksheets. Our input files are color and outline images in svg format.
Outline version (like a coloring page) + Color version
outline version and
color version
What we want to get is the following
result
We would like that a color palette is generated under the outline version of the image based on the color data from the color version of the image. Moreover, numbers corresponding to this palette are placed inside each color space of the outlined version.
I understand that no script in the world would do this properly, but at least I am striving to reduce the time spent by the editor (person) to put these numbers manually in the Illustrator. I understand that our color vector images may have too many colors and shades so we need somehow to limit the result colors of the palette ( to fuse them into large groups of basic colors).
I searched all over the stackoverflow solutions and found some ingenious like Paint with numbers with Adobe Illustrator Javascript and
I'm looking to create an automated numbering system for custom paint by number kits in photoshop (Kudos to Yuri Khristich). However, they are not exactly adapted to our needs.
Most of scripts on the web generate outlined images from color version, but the quality is compromised. We have already a proper outline version that we want to use as a base for color by number worksheet.
Here is the script to make a 'color palette' for selected artwork.
And here, as you know, is the script to add color names to all filled areas.
So I took the two script, made a couple of minimal tweaks and get almost the result you want. All you need after the scripts is to copy the layer with numbers and 'palette' from a colored artwork to a outline version.
Script #1
// Modified version
// https://stackoverflow.com/questions/75344674/paint-by-number-illustrator-script
// Original:
// https://productivista.com/make-a-list-of-colors-from-your-selection/
/*
Date: July, 2020
Author: Katja Bjerrum, email: katja#productivista.com, www.productivista.com
============================================================================
NOTICE:
This script is provided "as is" without warranty of any kind.
Free to use, not for sale.
============================================================================
Released under the MIT license.
http://opensource.org/licenses/mit-license.php
============================================================================
*/
//#target illustrator
var doc = app.activeDocument;
var myLayer = doc.activeLayer;
app.coordinateSystem = CoordinateSystem.ARTBOARDCOORDINATESYSTEM;
var swGrps = doc.swatchGroups;
var mainSwGr = doc.swatchGroups[0];
var sel = doc.selection;
var actionSet = 'CreateSwatchGroup';
var actionName = 'ColourGroup';
var actionPath = Folder.myDocuments + '/Adobe Scripts/';
if (!Folder(actionPath).exists) Folder(actionPath).create();
//app.doScript("Colorgroup", "ToSwatchScript"); // Action, that creates swatch group
var actionDoc =
[ '/version 3',
'/name [' + actionSet.length + ' ' + ascii2Hex(actionSet) + ']',
'/isOpen 1',
'/actionCount 1',
'/action-1 {',
'/name [' + actionName.length + ' ' + ascii2Hex(actionName) + ']',
' /keyIndex 0',
' /colorIndex 0',
' /isOpen 1',
' /eventCount 1',
' /event-1 {',
' /useRulersIn1stQuadrant 0',
' /internalName (ai_plugin_swatches)',
' /localizedName [ 8',
' 5377617463686573',
' ]',
' /isOpen 0',
' /isOn 1',
' /hasDialog 1',
' /showDialog 1',
' /parameterCount 1',
' /parameter-1 {',
' /key 1835363957',
' /showInPalette 4294967295',
' /type (enumerated)',
' /name [ 15',
' 4e657720436f6c6f722047726f7570',
' ]',
' /value 17',
' }',
' }',
'}'].join('');
createAction(actionDoc, actionName, actionPath);
app.redraw();
app.doScript (actionName, actionSet);
app.redraw();
app.unloadAction(actionSet, '');
var convMM = 2.8346456692; // initialization of the variable to convert points to mm
var colorgroup = doc.swatchGroups[doc.swatchGroups.length - 1]; // Choose the last swatch group
var stY = -200; //
var stX = 20;
var recW = 25;
var recH = 25;
var offX = recW / 5;
var offY = recH / 4;
var textoffY = recH / 4;
var rows = 4;
var cols = 4;
var black = new GrayColor();
black.gray = 80;
var white = new GrayColor() ;
white.gray = 0;
var noStroke = doc.swatches[0].color;
if (swGrps.length <=1){
alert ("Please create swatch group from your selection");
}
else if (sel <= 0){
//docRef.placedItems[0].selected == false;
alert ("Please make a selection");
delSwatchGr(colorgroup); //delete swatch group
}
else{
swatchGroupList(colorgroup, stY, stX);//create corlor list
// delSwatchGr(colorgroup);//delete swatch group
}
//Function, that creates color list
function swatchGroupList(swatchGroup, stY, stX) {
// Groups everything in the list
var mainGroup = myLayer.groupItems.add();
mainGroup.name = "Colors";
mainGroup.moveToBeginning(myLayer);
//Name of the color list
var nameText = myLayer.textFrames.add();
nameText.contents = swatchGroup.name; // the name of the swatch group
nameText.position = [stX, stY + recH];
var nameStyle = nameText.textRange.characterAttributes;
nameStyle.size = 12;//size in punkt
//nameStyle.textFont = textFonts.getByName("Avenir-Book");//the font
nameStyle.capitalization = FontCapsOption.ALLCAPS;//ALL CAPITALS
var swatches = swatchGroup.getAllSwatches();
var swatchArray = [];
for (i = swatches.length-1; i>=0; i--) {
var mySwatch = swatches[i];
mySwatch.name = i + 1;
var subGroup = createSwatchGroup(mySwatch, textoffY);
swatchArray.push(subGroup);
}
nameText.moveToEnd(mainGroup);
var myGroup = swatchArray;
var maxW = maxWidth(myGroup);
for (var j = 0; j < myGroup.length; j++) {
var mySubGroup = myGroup[j];
mySubGroup.moveToBeginning(mainGroup);
}
for (var i = 0; i < mainGroup.groupItems.length; i++) {
var mySubGroup = mainGroup.groupItems[i];
if (mainGroup.groupItems.length > 7) {
rows = 7;
var c = i%rows;
var r = Math.floor(i/rows);
mySubGroup.position = [stX + r * (maxW + 10), stY - c * (recH + offY)];
}
else {
rows = 7;
var c = i % rows;
var r = Math.floor(i / rows);
mySubGroup.position = [stX, stY - c * (recH + offY)];
}
}
// textSwatch.moveToBeginning(SubGroup);
// path_ref.moveToBeginning(SubGroup);
// SubGroup.position = [stX + c * 140, stY - r * (path_ref.height + offY)];
subGroup.moveToBeginning(mainGroup);
}
function lightColor(c){
if(c.typename)
{
switch(c.typename)
{
case "CMYKColor":
return (c.black>=10 || c.cyan>10 || c.magenta>10 || c.yellow > 10) ? true : false;
case "RGBColor":
return (c.red<230 || c.green<230 || c.blue<230) ? true : false;
case "GrayColor":
return c.gray >= 10 ? true : false;
case "SpotColor":
return lightColor(c.spot.color);
//return false;
}
}
}
function fitItem(item, itemW, itemH, diff) {
var oldWidth = item.width
var oldHeight = item.height
if (item.width > item.height) {
// landscape, scale height using ratio from width
item.width = itemW - diff.deltaX
var ratioW = item.width / oldWidth
item.height = oldHeight * ratioW
} else {
// portrait, scale width using ratio from height
item.height = itemH - diff.deltaY
var ratioH = item.height / oldHeight
item.width = oldWidth * ratioH
}
}
function itemBoundsDiff(item) {
var itemVB = item.visibleBounds
var itemVW = itemVB[2] - itemVB[0] // right - left
var itemVH = itemVB[1] - itemVB[3] // top - bottom
var itemGB = item.geometricBounds
var itemGW = itemGB[2] - itemGB[0] // right - left
var itemGH = itemGB[1] - itemGB[3] // top - bottom
var deltaX = itemVW - itemGW
var deltaY = itemVH - itemGH
var diff = { deltaX: deltaX, deltaY: deltaY }
return diff
}
function delSwatchGr(swGr){
var swGrSws = swGr.getAllSwatches();
for (var j = 0; j < swGrSws.length; j++){
var sw = swGrSws[j];
sw.color = new CMYKColor();
}
swGr.remove();
}
//Function finds the max group width
function maxWidth(myGroup) {
var maxFound = 0;
for (var j = 0; j < myGroup.length; j++) {
var GrWidth = myGroup[j].width;
//var Widthmax = GrWidth.width;
maxFound = Math.max(maxFound, GrWidth);
}
return maxFound;
}
function createSwatchGroup(sw, myOffset) {
//Is "MyForm" path exists?
try{
var path_ref_ori = app.activeDocument.pathItems.getByName("MyForm" || "myform" || "MYFORM");
}
catch(e) {
var path_ref_ori = false;
}
if (path_ref_ori) {
myPath = path_ref_ori.duplicate();
var boundsDiff = itemBoundsDiff(myPath);
fitItem(myPath, recW, recH, boundsDiff);
myPath.name = "NewForm";
myPath.position = [0, 0];
}
else {
var myPath = createMyPath()
}
myPath.fillColor = sw.color;
myPath.stroked = true;
myPath.strokeWidth = 0.3;
myPath.strokeColor = lightColor(myPath.fillColor) ? noStroke : black;
var textSwatch = myLayer.textFrames.add(); //swatch text
textSwatch.contents = sw.name;
textSwatch.position = [myPath.width + 1.3 * convMM, -myOffset];
var textSwStyle = textSwatch.textRange.characterAttributes;
textSwStyle.size = 10; //size in punkt
//textSwStyle.textFont = textFonts.getByName("MyriadPro-Semibold"); //the font
var SubGroup = myLayer.groupItems.add(); //groups path and text
SubGroup.name = sw.name;
SubGroup.position = [0, 0];
textSwatch.moveToBeginning(SubGroup);
myPath.moveToBeginning(SubGroup);
return SubGroup;
}
function createMyPath(){
//Is "MyForm" path exists?
try{
var path_ref_ori = app.activeDocument.pathItems.getByName("MyForm" || "myform" || "MYFORM");
}
catch(e) {
var path_ref_ori = false;
}
if (path_ref_ori) {
path_ref = path_ref_ori.duplicate();
var boundsDiff = itemBoundsDiff(path_ref);
fitItem(path_ref, recW, recH, boundsDiff);
path_ref.name = "NewForm";
path_ref.position = [0, 0];
}
else {
var path_ref = myLayer.pathItems.rectangle(0, 0, recW, recH); //swatch path item
}
return path_ref
};
function createAction(str, set, path) {
var f = new File('' + path + '/' + set + '.aia');
f.open('w');
f.write(str);
f.close();
app.loadAction(f);
f.remove();
};
function ascii2Hex(hex) {
return hex.replace(/./g, function (a) { return a.charCodeAt(0).toString(16) });
};
Input (after select the artwork and run the script):
Result (added the global swatches and the 'color palette' at the bottom):
Script #2
// Based on:
// https://stackoverflow.com/questions/73705368/paint-with-numbers-with-adobe-illustrator-javascript
var doc = app.activeDocument,
lays = doc.layers,
WORK_LAY = lays.add(),
NUM_LAY = lays.add(),
i = lays.length - 1,
lay;
// main working loop
for (; i > 1; i--) {
//process each layer
lay = lays[i];
lay.name = lay.name + " Num:" + (i - 1); // i-1 as 2 layers beed added.
process(lay.pathItems, false);
process(lay.compoundPathItems, true); // if any
}
//clean up
NUM_LAY.name = "Numbers";
WORK_LAY.remove();
function process(items, isCompound) {
var j = 0,
b, xy, s, p, op;
for (; j < items.length; j++) {
// process each pathItem
op = items[j];
try { color = op.fillColor.spot.name } catch(e) { continue } // <-- HERE
// add stroke
if (isCompound) {
// strokeComPath(op);
} else {
// !op.closed && op.closed = true;
// op.filled = false;
// op.stroked = true;
};
b = getCenterBounds(op);
xy = [b[0] + (b[2] - b[0]) / 2, b[1] + (b[3] - b[1]) / 2];
s = (
Math.min(op.height, op.width) < 20 ||
(op.area && Math.abs(op.area) < 150)
) ? 20 : 40; // adjust font size for small area paths.
add_nums(color, xy, s); // <--- HERE
}
}
function getMinVisibleSize(b) {
var s = Math.min(b[2] - b[0], b[1] - b[3]);
return Math.abs(s);
}
function getGeometricCenter(p) {
var b = p.geometricBounds;
return [(b[0] + b[2]) / 2, (b[1] + b[3]) / 2];
}
// returns square of distance between p1 and p2
function getDist2(p1, p2) {
return Math.pow(p1[0] + p2[0], 2) + Math.pow(p1[1] + p2[1], 2);
}
// returns visibleBounds of a path in a compoundPath p
// which is closest to center of the original path op
function findBestBounds(op, p) {
var opc = getGeometricCenter(op);
var idx = 0,
d;
var minD = getDist2(opc, getGeometricCenter(p.pathItems[0]));
for (var i = 0, iEnd = p.pathItems.length; i < iEnd; i++) {
d = getDist2(opc, getGeometricCenter(p.pathItems[i]));
if (d < minD) {
minD = d;
idx = i;
}
}
return p.pathItems[idx].visibleBounds;
}
function applyOffset(op, checkBounds) {
var p = op.duplicate(WORK_LAY, ElementPlacement.PLACEATBEGINNING),
// offset value the small the better, but meantime more slow.
offset = function() {
var minsize = Math.min(p.width, p.height);
if (minsize >= 50) {
return '-1'
} else if (20 < minsize && minsize < 50) {
return '-0.5'
} else {
return '-0.2' // 0.2 * 2 (both side ) * 50 (Times) = 20
}
},
xmlstring = '<LiveEffect name="Adobe Offset Path"><Dict data="I jntp 2 R mlim 4 R ofst #offset"/></LiveEffect>'
.replace('#offset', offset()),
TIMES = 100; // if shapes are too large, should increase the value.
if (checkBounds) {
// check its size only if it needs, because it's too slow
while (TIMES-- && getMinVisibleSize(p.visibleBounds) > 3) p.applyEffect(xmlstring);
} else {
while (TIMES--) p.applyEffect(xmlstring);
}
return p;
}
function getCenterBounds(op) {
var originalMinSize = getMinVisibleSize(op.visibleBounds);
var p = applyOffset(op, false);
if (getMinVisibleSize(p.visibleBounds) > originalMinSize) {
// in some cases, path p becomes larger for some unknown reason
p.remove();
p = applyOffset(op, true);
}
var b = p.visibleBounds;
if (getMinVisibleSize(b) > 10) {
activeDocument.selection = [p];
executeMenuCommand("expandStyle");
p = activeDocument.selection[0];
if (p.typename == "CompoundPathItem") {
b = findBestBounds(op, p);
}
}
p.remove();
return b;
}
function add_nums(n, xy, s) {
var txt = NUM_LAY.textFrames.add();
txt.contents = n;
txt.textRange.justification = Justification.CENTER;
txt.textRange.characterAttributes.size = s;
txt.position = [xy[0] - txt.width / 2, xy[1] + txt.height / 2];
}
function strokeComPath(compoundPath) {
var p = compoundPath.pathItems,
l = p.length,
i = 0;
for (; i < l; i++) {
// !p[i].closed && p[i].closed = true;
// p[i].stroked = true;
// p[i].filled = false;
}
};
Result (added the layer with numbers after run the script):
Final outlined version with numbers and the 'color palette'
Note: you have to ungroup and unmask the color artwork before you run the Script #2.
Here is the results for the rest examples:
As you can see the 'final' artwork still need a quite amount of additional manual work: to move or remove extra numbers.
And it makes sense to reduce the number of colors in original color artworks (perhaps it's possible to do with a script to some extent, as well).

JS / JSX Script to generate unique PNGs from all permutations across all Photoshop Layer Groups and their Photoshop Layers

I'm looking into getting into generative art. My idea is to have Photoshop (CS5) generate a unique PNG for all permutations that exist while the script iterates through every LAYER across each LAYER GROUP (layerSets).
As an example, it would be similar to a character generator where:
PARENT layerSets consist of parts or locations across the face/body (A,B)
CHILD layers consist of accessories/styles (1,2,3)
Such that all generated PNG permutations would be: A1B1,A2B1,A3B1;A2B1,A2B2,A2B3;A3B1,A3B2,A3B3 only. (A1A2, A2A3, A1A3; B1B2, B2B3, B1B3 are not necessary; Standalone A1,A2,A3,B1,B2,B3 are not necessary).
I've found some code from #Mr.Online that generates random, and potentially redundant combinations from user-inputted quantity. His script requires that all layers be hidden by the user prior to running.
Thanks so much. Hopefully this'll help:
function Visible() {
var Grps = app.activeDocument.layerSets; // loops through all groups
for(var i = 0; i < Grps.length; i++){
var tmp = app.activeDocument.layerSets[i].layers.length;
app.activeDocument.layerSets[i].visible=true;
var groupChildArr = app.activeDocument.layerSets[i].layers;
var randLays = Math.floor(Math.random() * tmp);
groupChildArr[randLays].visible = true;
Save();
}
Revert();
}
function Save() {
var outFolder = app.activeDocument; // psd name
var outPath = outFolder.path;
var fName = "PNG"; // define folder name
var f = new Folder(outPath + "/" + fName);
if ( ! f.exists ) {
f.create()
}
var saveFile = new File(outPath + "/" + fName +"/" + "Pattern_" + num + ".png");
pngSaveOptions = new PNGSaveOptions();
pngSaveOptions.interlaced = false;
app.activeDocument.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE);
}
// Original code - revert function does not work
// for some users
//function Revert(){
// var idslct = charIDToTypeID( "slct" );
// var desc300 = new ActionDescriptor();
// var idnull = charIDToTypeID( "null" );
// var ref163 = new ActionReference();
// var idSnpS = charIDToTypeID( "SnpS" );
// ref163.putName( idSnpS, "test.psd" );
// desc300.putReference( idnull, ref163 );
// executeAction( idslct, desc300, DialogModes.NO );
//}
function Revert(){
var idRvrt = charIDToTypeID( "Rvrt" );
executeAction( idRvrt, undefined, DialogModes.NO );
}
var count = prompt("How many patterns you want","");
for (var x=0 ; x<count;x++){
var num = x+1;
Visible();
}
As you say, you need to ignore the random layers. However, if you know the number of layers & groups it's quite straight forward:
show_layers("A", "1");
show_layers("B", "1");
function show_layers(g, n)
{
// g is the name of the group (layerset)
// n is the name of the layer (artlayer)
srcDoc.activeLayer = srcDoc.layerSets.getByName(g).artLayers.getByName(n);
srcDoc.activeLayer.visible = true;
}
So, assuming all layers are switched off, you can get the layers by name and then make them visible.
Switching off all the layers is a bit more involved. You have to loop over all groups and then loop over its sublayers. Working with groups is a bit of a learning curve.
function switch_off_all_layers(bool)
{
var numLayers = app.activeDocument.layers.length;
// want to hide the background as well?
// default: background = visible
if (bool == undefined) bool = false;
if (bool == false)
{
numLayers -=1; // -1 for background
}
for(var i = 0 ; i < numLayers; i++)
{
if (app.activeDocument.layers[i].typename == "LayerSet")
{
app.activeDocument.layers[i].visible = true;
var subDoc = app.activeDocument.layers[i];
var numOfSubLayers = subDoc.layers.length;
for (var j = numOfSubLayers -1; j >= 0; j--)
{
var tempSubLayer = subDoc.layers[j];
tempSubLayer.visible = false;
}
}
}
}
Further to my explanation, if you can't supply the group layers & names then you fill want to loop over all groups and all layers.
var groupLayers = [];
var artLayers = [];
var theLayers = collectAllLayers(app.activeDocument, 0);
alert("Group layers\n" + groupLayers);
alert("Art layers\n" + artLayers);
// function collect all layers
function collectAllLayers (theParent, level)
{
for (var m = theParent.layers.length - 1; m >= 0; m--)
{
var theLayer = theParent.layers[m];
// apply the function to layersets;
if (theLayer.typename == "ArtLayer")
{
if (theLayer.isBackgroundLayer == true)
{
// add background layer (if needed)
// artLayers.push(theLayer.name);
}
else
{
// find the art layers
artLayers.push(theLayer.name);
}
}
else
{
// find the group layers
groupLayers.push(theLayer.name);
collectAllLayers(theLayer, level + 1)
}
}
}

Trying to export canvas size as file name in Photoshop JSX script

I'm not a programmer, but trying to write a script for Photoshop. Below is something that I found, but it simply increments the files "1.png, 2.png, etc..." I'd like to name the exported files, "documentName_canvasWidth_canvasHeight_incrementedNumber.png"
function sfwPNG24(saveFile){
var pngOpts = new ExportOptionsSaveForWeb;
pngOpts.format = SaveDocumentType.PNG
pngOpts.PNG8 = false;
pngOpts.transparency = true;
pngOpts.interlaced = false;
pngOpts.quality = 100;
activeDocument.exportDocument(new File(saveFile),ExportType.SAVEFORWEB,pngOpts);
}
/*
Incrementing a number inside a text layer then Saving it in PNG
*/
var layer = activeDocument.layers[0];
if (layer.kind == 'LayerKind.TEXT') {
for (var i=1; i < 7; i++) {
layer.textItem.contents = i.toString();
sfwPNG24( 'filepathgoeshere'+ i +'.png');
};
};
Add these changes to the second part of the code:
var layer = activeDocument.layers[0];
// documentName_canvasWidth_canvasHeight_incrementedNumber.png
var srcDoc = app.activeDocument;
// get width and height
var W = srcDoc.width.value;
var H = srcDoc.height.value;
// get document name
var fn = srcDoc.name;
if (layer.kind == 'LayerKind.TEXT')
{
for (var i=1; i < 7; i++)
{
layer.textItem.contents = i.toString();
sfwPNG24( 'filepathgoeshere'+ W + "_" + H + "_" + i +'.png')
}
}

limit Indesign item export only to images

I'm using the following script to export all items / per page from an indesign document to jpg. This script also crops all items to their size given by the container in indesign.
I would like to limit this script to export only all "placed images", because I only need the images. At the moment I get also all rectangular objects like text boxes and so on.
#target InDesign
//set properties for export to your needs
with(app.jpegExportPreferences){
antiAlias = true;
embedColorProfile = false;
exportResolution = 300;
jpegColorSpace = JpegColorSpaceEnum.RGB; //JpegColorSpaceEnum.CMYK, JpegColorSpaceEnum.GRAY r/w One of RGB, CMYK or Gray
jpegQuality = JPEGOptionsQuality.HIGH; //JPEGOptionsQuality.LOW, JPEGOptionsQuality.MEDIUM, JPEGOptionsQuality.HIGH, JPEGOptionsQuality.MAXIMUM r/w The compression quality.
jpegRenderingStyle = JPEGOptionsFormat.BASELINE_ENCODING; // JPEGOptionsFormat.PROGRESSIVE_ENCODING r/w The rendering style.
simulateOverprint = true;
}
//doc has to be saved once
var theDoc = app.activeDocument;
var docName = theDoc.name;
var docShortName = docName.replace(/.indd/, '')
var docPath = '' + theDoc.fullName;
var docContainerPath = docPath.replace(docName, '')
var destPath = docContainerPath + '/' + docShortName + '_jpgExport/'
if(Folder(destPath).create() != true){alert('Could not create targetfolder.'); exit();}
var pageItems = theDoc.pageItems.everyItem().getElements();
l = pageItems.length;
counter = 0;
for(var i = 0; i < l; i++){
counter = counter + 1;
var singlePageItem = pageItems[i];
currParentPage = singlePageItem.parentPage;
if(currParentPage == null){parentPageNumber = 'pasteboard'}else{parentPageNumber = singlePageItem.parentPage.name; }
newFile =new File(destPath + 'page_' + parentPageNumber + '_' + 'item_' + counter + '.jpg');
if(singlePageItem.exportFile(ExportFormat.JPG, newFile) === false){alert(newFile + ' could not write jpg-File.')}
}
If I understand you correctly, in place of:
var pageItems = theDoc.pageItems.everyItem().getElements();
you could use:
var pageItems = theDoc.allGraphics;
which would grab all the graphic elements instead of every pageItem. Is this what you were thinking?
EDIT: You may need to grab the parent element of every graphic element in order to export them.

Ideas/Assistance with ActionScript Color Fading?

Here is a function I added to my Flash-based chat to rainbowify certain text within [rainbow] and [/rainbow] tags.
ChatUI.prototype.rainbowParse = function(txt) {
txt = txt;
if ((txt.indexOf("[rainbow]") > -1) && (txt.indexOf("[/rainbow]") > -1)) {
txt = txt.replace("&apos;", "#").replace("&apos;", "#");
var firstChar = txt.indexOf("[rainbow]") + 9;
var lastChar = txt.indexOf("[/rainbow]");
if (((lastChar - firstChar) > 100) || ((txt.split("[rainbow]").length - 1) > 3)) {
break;
}
while (lastChar <= txt.lastIndexOf("[/rainbow]")) {
var RAINBOWTEXT = '';
var i = firstChar;
while (i < lastChar) {
RAINBOWTEXT += txt.charAt(i);
i++
}
var text = RAINBOWTEXT;
var texty = '';
colors = new Array('ff00ff','ff00cc','ff0099','ff0066','ff0033','ff0000','ff3300','ff6600','ff9900','ffcc00','ffff00','ccff00','99ff00','66ff00','33ff00','00ff00','00ff33','00ff66','00ff99','00ffcc','00ffff','00ccff','0099ff','0066ff','0033ff','0000ff','3300ff','6600ff','9900ff','cc00ff');
i = 0;
while (i <= text.length) {
var t = text.charAt(i);
if (t != undefined) {
texty += "<font color=\"#" + colors[i % colors.length] + "\">" + t + "</font>";
i++;
}
}
texty = texty.replace("> <", "> <");
var REPLACEME = "[rainbow]" + RAINBOWTEXT + "[/rainbow]";
txt = txt.replace(REPLACEME, texty);
if (lastChar == txt.lastIndexOf("[/rainbow]")) {
break;
}
nextChar = lastChar + 10;
firstChar = txt.indexOf("[rainbow]", lastChar) + 9;
lastChar = txt.indexOf("[/rainbow]", lastChar);
}
txt = txt.replace("#", "&apos;");
}
return txt;
}
However, I don't like this way these rainbows look. The text's colors repeat themselves.
To see an example of what I mean, go to http://www.tektek.org/color/ and click "Rainbow" and preview with the repeat set to 1. Then preview with it set to 3 or higher.
I want my code to have a repeat of 1, but since the rainbow text length varies so much, I have no idea how to do this. I've Googled numerous rainbow text generators, trying to look at their code. It sucks. Please give me some ideas or assistance with this. :(
You need to divide the number of elements in your colors array by the number of characters in your rainbow string and apply each colour to that number of characters in your string. That way each color will be applied only once and in equal proportions regardless of the length of your string:
// Calculate the number of characters to apply each character to
var inc = Math.round(colors.length / txt.length);
// Empty string to store the modified rainbox text in
var str = "";
// Loop through each color and apply it to the correct number of characters
for (var i = 0; i < colors.length; i ++) {
str += "<font color='#'" + colors[i] + "'>"
+ txt.substr(i * inc, inc)
+ "</font>";
}
Edit:
Okay, I reread the question and looked again at the example you link to and I think a better solution would be to create a linear gradient in a Sprite using the drawing API and mask it using the text field containing the text which must have the rainbow effect applied to it:
import flash.text.TextField;
import flash.text.TextFormat;
import flash.display.Sprite;
import flash.display.GradientType;
import flash.text.TextFieldAutoSize;
import flash.geom.Matrix;
import flash.text.Font;
// You need to embed the font to use it as a mask
Font.registerFont(Arial);
var txt:String = "My Rainbow text";
// Removed some of your colors to save time formatting
var colors:Array = [0xff00ff, 0xff00cc, 0xff0099, 0xff0066, 0xff0033,
0xff0000, 0xff3300, 0xff6600, 0xff9900, 0xffcc00,
0xffff00, 0xccff00, 0x99ff00, 0x66ff00, 0x33ff00];
var alphas:Array = [];
var ratios:Array = [];
// Populate alphas and ratios arrays of the same length as colors array
for (var i:int = 0; i < colors.length; i ++)
{
alphas.push(1);
ratios.push(i * Math.round(255 / colors.length)); // Equal ratio for each color
}
// Create a text field
var field:TextField = new TextField();
field.text = txt;
field.autoSize = TextFieldAutoSize.LEFT;
field.setTextFormat(new TextFormat("Arial", 30, 0x0000000));
field.embedFonts = true;
// Create a gradient of the same dimensions as the text field
var matrix:Matrix = new Matrix();
matrix.createGradientBox(field.width, field.height);
var gradient:Sprite = new Sprite();
gradient.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix);
gradient.graphics.drawRect(0, 0, field.width, field.height);
gradient.graphics.endFill();
this.addChild(field);
this.addChild(gradient);
// Mask the gradient with the text field
gradient.mask = field;

Categories

Resources