Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Photoshop script for adding measurements to your mockups, based on Pixel Measure v0.04 by Nikolaj Selvik (https://code.google.com/p/pixelmeasure/)
/*
Photoshop script for adding measurements to your mockups,
based on Pixel Measure v0.04 by Nikolaj Selvik (https://code.google.com/p/pixelmeasure/)
To install: Place in /Applications/Adobe Photoshop CC/Presets/Scripts/ and restart Photoshop.
To use: Draw a rectangle marquee and invoke from File > Scripts > Pixel Measure.
Tips:
- Set your pencil to 1x1 and your foreground color to something visible (e.g., red).
- Set your Measurement Scale (Image > Analysis > Set Measurement Scale).
For iOS retina, you might use the unit "pt" and set the pixel length to 2 (2px = 1pt @2x).
- Set your DPI scale (Image > Image Size). In the retina example, if 72 is your normal dpi,
use 144 (72 x 2 = 144).
- Set your ruler to use points.
- Set a keyboard shortcut to invoke the script.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
var originalUnit = preferences.rulerUnits;
preferences.rulerUnits = Units.POINTS;
var ratio;
app.displayDialogs = DialogModes.NO;
if(validateState())
{
app.activeDocument.suspendHistory("Create measurement", "createMeasure();");
}
function validateState()
{
if (app.documents.length === 0)
{
alert("No document open");
return false;
} else {
docRef = app.activeDocument;
ratio = docRef.measurementScale.pixelLength;
docRes = docRef.resolution;
}
if(!hasSelection(app.activeDocument))
{
alert("Please make a selection to measure");
return false;
}
if (docRes / ratio !== 72) {
if (!confirm("Measurement Scale does not match document resolution\rContinue anyway?")) {
return false;
}
}
try {
var colorTest = app.foregroundColor;
} catch(e) {
alert("Invalid foreground color\r" + e);
return false;
}
return true;
}
function createMeasure()
{
var selRef = docRef.selection;
var mainLayerSet;
// set density-independent units (dp, pt)
var measureUnits = docRef.measurementScale.logicalUnits;
ratio = docRef.measurementScale.pixelLength;
if(measureUnits == "pixels")
{
measureUnits = "px";
}
else if(measureUnits == "points")
{
measureUnits = "pt";
}
// =======================================================
// Create "Pixel Measures" LayerSet if it doesn't already exist
// =======================================================
try
{
mainLayerSet = docRef.layerSets.getByName("Pixel Measures");
}
catch(error)
{
mainLayerSet = docRef.layerSets.add();
mainLayerSet.name = "Pixel Measures";
}
// =======================================================
// Create Measurement LayerSet
// =======================================================
var layerSetRef = mainLayerSet.layerSets.add();
var linesLayerRef = layerSetRef.artLayers.add();
// =======================================================
// Draw Lines
// =======================================================
// get average color
var x1 = selRef.bounds[0].value;
var y1 = selRef.bounds[1].value;
var x2 = selRef.bounds[2].value;
var y2 = selRef.bounds[3].value;
selRef.copy(true);
var chanRef = docRef.channels.add();
chanRef.name = "TMP";
chanRef.kind = ChannelType.SELECTEDAREA;
selRef.store(docRef.channels.getByName("TMP"), SelectionType.EXTEND);
docRef.paste();
var tmpLayer = docRef.activeLayer;
selRef.load(docRef.channels.getByName("TMP"));
tmpLayer.applyAverage();
chanRef.remove();
selRef.deselect();
var width = x2 - x1;
var height = y2 - y1;
var tmpSampler = docRef.colorSamplers.add(Array(x1 + width/2, y1 + height/2));
var bgColor = new SolidColor();
bgColor = tmpSampler.color;
tmpSampler.remove();
// figure out what color to use
var baseColorValue = (bgColor.rgb.red + bgColor.rgb.green + bgColor.rgb.blue) / 3;
var tmpFgColor = app.foregroundColor;
if(baseColorValue < 192)
{
app.foregroundColor.rgb.hexValue = "ffffff";
}
var horizontal = width > height;
if(horizontal)
{
drawLine(x1,y1,x1,y1+10/ratio);
drawLine(x2-1/ratio,y1,x2-1/ratio,y1+10/ratio);
drawLine(x1,y1+5/ratio,x2-1/ratio,y1+5/ratio);
}
else
{
drawLine(x1,y1,x1+10/ratio,y1);
drawLine(x1,y2-1/ratio,x1+10/ratio,y2-1/ratio);
drawLine(x1+5/ratio,y1,x1+5/ratio,y2-1/ratio);
}
// =======================================================
// Draw Text
// =======================================================
var textLayerRef = layerSetRef.artLayers.add();
textLayerRef.kind = LayerKind.TEXT;
var textItemRef = textLayerRef.textItem;
textItemRef.size = new UnitValue(5, "pt");
// temporary workaround for text size bug
if (textItemRef.size.as("pt") != 5) {
changeTextSize(5*ratio);
}
textItemRef.font = "Monaco";
textItemRef.antiAliasMethod = AntiAlias.NONE;
var textWidth, textHeight, textX, textY;
if (horizontal) {
if (width > 16) {
textItemRef.contents = width + " " + measureUnits;
} else {
textItemRef.contents = width + "\r" + measureUnits;
}
textItemRef.justification = Justification.CENTER;
// test position of text and find good offsets
textWidth = textLayerRef.bounds[2].value - textLayerRef.bounds[0].value;
textHeight = textLayerRef.bounds[3].value - textLayerRef.bounds[1].value;
textX = x1 + width/2;
if (textX - textWidth/2 < 0) {
textX = 1;
textItemRef.justification = Justification.LEFT;
} else if (textX + textWidth/2 > docRef.width.value) {
textX = docRef.width.value - 1;
textItemRef.justification = Justification.RIGHT;
}
textY = y1 + 21/ratio;
if (textY + 4 > docRef.height.value) {
textY = y1 - (width > 16 ? 6 : 16)/ratio;
}
textItemRef.position = Array(Math.floor(textX), Math.floor(textY));
} else {
textItemRef.contents = height + " " + measureUnits;
// test position of text and find good offsets
textWidth = textLayerRef.bounds[2].value - textLayerRef.bounds[0].value;
textHeight = textLayerRef.bounds[3].value - textLayerRef.bounds[1].value;
textX = x1 + 15/ratio;
if (textX + textWidth > docRef.width.value) {
textX = x1 - 4/ratio;
textItemRef.justification = Justification.RIGHT;
}
textY = y1 + 4/ratio + height/2;
textItemRef.position = Array(Math.floor(textX), Math.floor(textY));
}
layerSetRef.name = (horizontal ? width : height) + " " + measureUnits;
textItemRef.color = app.foregroundColor;
// =======================================================
// Reset
// =======================================================
app.preferences.rulerUnits = originalUnit;
app.foregroundColor = tmpFgColor;
}
function drawLine(x1,y1,x2,y2)
{
// Factor in ruler offset, from http://forums.adobe.com/message/2866222#2866222
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var desc = executeActionGet(ref);
var xOffSet = desc.getInteger(stringIDToTypeID('rulerOriginH')) / 65536;
var yOffSet = desc.getInteger(stringIDToTypeID('rulerOriginV')) / 65536;
x1 -= xOffSet/ratio;
x2 -= xOffSet/ratio;
y1 -= yOffSet/ratio;
y2 -= yOffSet/ratio;
var pointArray = [];
var pointA = new PathPointInfo();
pointA.kind = PointKind.CORNERPOINT;
pointA.anchor = Array(x1, y1);
pointA.leftDirection = pointA.anchor;
pointA.rightDirection = pointA.anchor;
pointArray.push(pointA);
var pointB = new PathPointInfo();
pointB.kind = PointKind.CORNERPOINT;
pointB.anchor = Array(x2, y2);
pointB.leftDirection = pointB.anchor;
pointB.rightDirection = pointB.anchor;
pointArray.push(pointB);
var line = new SubPathInfo();
line.operation = ShapeOperation.SHAPEXOR;
line.closed = false;
line.entireSubPath = pointArray;
var lineSubPathArray = [];
lineSubPathArray.push(line);
var linePath = app.activeDocument.pathItems.add("TempPath", lineSubPathArray);
linePath.strokePath(ToolType.PENCIL, false);
app.activeDocument.pathItems.removeAll();
}
function hasSelection(doc)
{
var res = false;
var as = doc.activeHistoryState;
doc.selection.deselect();
if (as != doc.activeHistoryState)
{
res = true;
doc.activeHistoryState = as;
}
return res;
}
// Temporary fix for the textItem.size bug: https://forums.adobe.com/message/6804450
// Adapted from https://forums.adobe.com/message/6814050#6814050
function changeTextSize(newSize) {
var idsetd = charIDToTypeID( "setd" );
var desc23 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref6 = new ActionReference();
var idPrpr = charIDToTypeID( "Prpr" );
var idTxtS = charIDToTypeID( "TxtS" );
ref6.putProperty( idPrpr, idTxtS );
var idTxLr = charIDToTypeID( "TxLr" );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref6.putEnumerated( idTxLr, idOrdn, idTrgt );
desc23.putReference( idnull, ref6 );
var idT = charIDToTypeID( "T " );
var desc24 = new ActionDescriptor();
var idtextOverrideFeatureName = stringIDToTypeID( "textOverrideFeatureName" );
desc24.putInteger( idtextOverrideFeatureName, 808465458 );
var idtypeStyleOperationType = stringIDToTypeID( "typeStyleOperationType" );
desc24.putInteger( idtypeStyleOperationType, 3 );
var idSz = charIDToTypeID( "Sz " );
var idPxl = charIDToTypeID( "#Pxl" );
desc24.putUnitDouble( idSz, idPxl, newSize );
var idTxtS = charIDToTypeID( "TxtS" );
desc23.putObject( idT, idTxtS, desc24 );
executeAction( idsetd, desc23, DialogModes.NO );
}
@ahsanpervaiz

Does it work with Photoshop CC2015 and 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment