ar-cutpaste icon indicating copy to clipboard operation
ar-cutpaste copied to clipboard

Better and faster PS scripts

Open jardicc opened this issue 4 years ago • 14 comments

I can help you with these:

  1. get document matrix (position, zoom, rotation)
  2. better and faster way to place layer. No need to open new document tab or select something, ...
  3. get active view bounds properly and fast (your code is not working because reference points nothing)
  4. Photoshop background panel automatically started with PS instead of connection SDK. I am not perfectly sure about this but perhaps it could eliminate the need to match password in PS and mobile app in local network. Or it could have UI to indicate whether phone is connected and maybe allow the connection with one button click.

Are you interested?

jardicc avatar May 03 '20 21:05 jardicc

Hi thanks a lot for these proposals. These would be great addons to this repo!

I couldn't crack the document positioning on the screen, so it's great to hear that I'm just missing something. Also, anything that can speed up the process would be more that welcome.

cyrildiagne avatar May 04 '20 05:05 cyrildiagne

Ok, once I will have time I will write some details.

jardicc avatar May 04 '20 07:05 jardicc

var desc = new ActionDescriptor();	
desc.putPath(stringIDToTypeID("null"), new File( "C:/path/to/file.png"));
desc.putBoolean(stringIDToTypeID("unwrapLayers"), true);
executeAction(stringIDToTypeID("placeEvent"), desc, DialogModes.ERROR);

This is the most efficient way to place layer into document I know so far. It won't be as a smart object, and it won't be deformed. It also doesn't open new document so you could save like 700ms maybe even more.

jardicc avatar May 04 '20 19:05 jardicc

moveTo(100, 100);

function moveTo(x, y) {
	var desc2 = new ActionDescriptor();
	desc2.putUnitDouble(stringIDToTypeID("horizontal"), stringIDToTypeID("pixelsUnit"), x);
	desc2.putUnitDouble(stringIDToTypeID("vertical"), stringIDToTypeID("pixelsUnit"), y);
		
	var desc = new ActionDescriptor();
	desc.putObject(stringIDToTypeID("position"), stringIDToTypeID("point"), desc2);
	desc.putBoolean(stringIDToTypeID("relative"), false);
	executeAction(stringIDToTypeID("transform"), desc, DialogModes.ERROR);
}

And this is the most efficient way how to move layers at the exact location in pixels. It ignores ruler units and document DPI so 1px is always 1px. It also ignores ruler origin. Point coordinate is left top pixel of rectangular boundary for sum of all selected layers. I am not sure whether the layer mask can affect that boundary.

jardicc avatar May 04 '20 20:05 jardicc

var ref = new ActionReference();
ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("viewTransform"));
ref.putEnumerated(stringIDToTypeID("document"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
var list = executeActionGet(ref).getList(stringIDToTypeID('viewTransform'));
var matrix = [list.getDouble(0), list.getDouble(1), list.getDouble(2), list.getDouble(3), list.getDouble(4), list.getDouble(5)];

This is how you get canvas 2D transformation matrix. It includes panning, zoom, rotation and horizontal flip. It should be in pixels. Reference is active document. One document can have multiple windows and this is only for active window. http://angrytools.com/css-generator/transform/

jardicc avatar May 04 '20 20:05 jardicc

var ref = new ActionReference();
ref.putProperty(stringIDToTypeID("property"),stringIDToTypeID("viewInfo"));
ref.putEnumerated(stringIDToTypeID("document"),stringIDToTypeID("ordinal"),stringIDToTypeID("targetEnum"));
var desc = executeActionGet(ref);

var bounds = desc.getObjectValue(stringIDToTypeID('viewInfo')).getObjectValue(stringIDToTypeID('activeView')).getObjectValue(stringIDToTypeID('globalBounds'));

var left = bounds.getDouble(stringIDToTypeID('left'));
var right = bounds.getDouble(stringIDToTypeID('right'))
var top = bounds.getDouble(stringIDToTypeID('top'))
var bottom = bounds.getDouble(stringIDToTypeID('bottom'))

This is how you get inner window position within your monitors. Again one document can have multiple windows and this is for active one. Works only in PS CC 2018+. You can have a bit problem with scrollbars and rulers and you might need some small constant magic numbers.

jardicc avatar May 04 '20 20:05 jardicc

And this is for an array of screens $.screens but I don't know how to get screen DPI. It is possible in CEP extension but with Connection SDK you have only ExtendScript. But maybe that is not needed at all.

jardicc avatar May 04 '20 21:05 jardicc

Wow thanks @jardicc this is amazing!

Would you like to / have time to try putting them in a pull request?

cyrildiagne avatar May 05 '20 09:05 cyrildiagne

No. I would need to build and set up everything in order to test it properly and this would take me probably a few hours because I am not familiar with mobile apps and python.

jardicc avatar May 05 '20 09:05 jardicc

Ok makes sense. Thanks a lot anyway for the snippets!

cyrildiagne avatar May 06 '20 19:05 cyrildiagne

I tried to setup all of these but as I expected it took about 3 hours and it is still not working. I have problem to make this work: basnet-http.default.example.com I tried docker as someone suggested but apparently I need Windows Pro instead of Windows Home or waste another few hours with complicated VirtualBox workaround. It would be great if you could provide an image for VirtualBox with whole OS tools and everything :-D So I could just test my PS script.

jardicc avatar May 10 '20 17:05 jardicc

So with help of https://github.com/cyrildiagne/ar-cutpaste/issues/44#issue-616253699 I am able to make it work and I should be able to improve that.

But I don't understand why the pasted layer has to be at the bottom of the layer stack?

jardicc avatar May 12 '20 20:05 jardicc

Sorry that was probably a setting for the video to have the photos appear with a brightness correction layer otherwise they were looking a bit dark in the video.

cyrildiagne avatar May 12 '20 20:05 cyrildiagne

I have this in script.js

function pasteImage(filename, layerName, x, y) {

	function place(filename) {
		var desc = new ActionDescriptor();	
		desc.putPath(stringIDToTypeID("null"), new File( filename));
		desc.putBoolean(stringIDToTypeID("unwrapLayers"), true);
		executeAction(stringIDToTypeID("placeEvent"), desc, DialogModes.ERROR);
	}

	function moveTo(x, y) {
		var desc2 = new ActionDescriptor();
		desc2.putUnitDouble(stringIDToTypeID("horizontal"), stringIDToTypeID("pixelsUnit"), x);
		desc2.putUnitDouble(stringIDToTypeID("vertical"), stringIDToTypeID("pixelsUnit"), y);
			
		var desc = new ActionDescriptor();
		desc.putObject(stringIDToTypeID("position"), stringIDToTypeID("point"), desc2);
		desc.putBoolean(stringIDToTypeID("relative"), false);
		executeAction(stringIDToTypeID("transform"), desc, DialogModes.ERROR);
	}

	try {		
		place(filename);
		moveTo(x, y);		
		activeDocument.activeLayer.name = layerName; 
		
	} catch (e) {
		alert(e);
	}
}

moveTo(x,y) is absolute within the canvas in pixels. But I don't understand how exactly screenpoint works. What is exactly "projected point" ?

jardicc avatar May 12 '20 21:05 jardicc