Copy link to clipboard
Copied
I've been googling, and reading, but I have not been able to find an action, or method to select a layer, and have it scale to the canvas size? This seems to be something that should be built in?
Anyone know of a script or action I can use?
Sometimes it needs to scale up or down.
And I don't need to keep the proportions. Just scale to fill.
Thanks for your help
Maxi
PS: I know in Russell Brown's Paper Texture extension, the loaded layers are scaled to fit the canvas.
What is your ruler units? I only get that error in CS6 if the ruler is set to percent. If your ruler is set to percent I can add some code to the script that will fix the error.
Copy link to clipboard
Copied
Something like this?
var doc = app.activeDocument;
var layer = doc.activeLayer;
layer.translate(new UnitValue(0-layer.bounds[0].as('px'),'px'), new UnitValue(0-layer.bounds[1].as('px'),'px'));
layer.resize((doc.width.value/(layer.bounds[2]-layer.bounds[0]))*100,(doc.height.value/(layer.bounds[3]-layer.bounds[1]))*100,AnchorPosition.TOPLEFT);
Copy link to clipboard
Copied
Thank you Michael,
How would I go about putting this into an action or script to use? Sorry, I don't have scripting experience just working with actions.
Should I save that as a text file, then load it as a script?
Thanks for your help.
Maxi
Copy link to clipboard
Copied
Copy and paste the code in a plain text editor or use the ExtendScript ToolKit editor at installs with Photoshop. Save the file with .jsx as the extension in the Photoshop/presets/scripts folder. Then you can either run the script from the menu or create an action using insert menu item to run the script from an action.
The key is making sure the text editor can save as plain text. Also you may need admin rights to save to the scripts folder. Or you could try saving to the desktop and using the os file browser to move to the correct folder. You can run the script from any folder using the menu but the script needs to be in the scripts folder if you want an action.
Copy link to clipboard
Copied
Thank you, I actually got that far, first via the notepad then using Extend Script Toolkit.
Tell me if I am doing this wrong.
Test image: black background. I copy a layer from another doc (much smaller size.)
I have the small layer selected, go to scripts, select my resize script, and I get this error: (I'm using CS6)
Copy link to clipboard
Copied
What type of layer is the selected layer?
Copy link to clipboard
Copied
I tried both a regular image layer, and as a smart object.
I am not trying to keep the targeted layer's aspect ration intact.
example
100x100 pixel layer scaled to Canvas size 500x900 px.
Like wise if the target layer is bigger, 5000x4000px scaled down to canvas size 500x500px, as an example.
Thanks.
Copy link to clipboard
Copied
Yes I know you want to fill the canvas. so if you have a 1:1 aspect ratio layer and a 5:9 aspect ratio canvas. If you were to scale you layer 500% it would be 500x500 and fill the canvas width but not the height you would need to scale it 900% the layer would be 900x900 fill the height and 400x900 pixels would fall outside the canvas and be masked off by the canvas size. the result you would see would be canvas size 500x900 pixels sane for scaling down. When the aspect ratios do not match there will be spill over and you must resize to the width or height the same percentage to have no distortion
Copy link to clipboard
Copied
JJMack, I think Picturequest understands that if the aspect ratio is not maintained there will be distortion in the resized image. There are times when image distortion doesn't matter.
Picturequest, I works for me in Photoshop CC. I can test in with CS6 and CS5 in a few hours. I don't understand why it is not working for you unless it's that resample preference bug JJMack suggested may be the problem.
But when it does work it scales the activeLayer up or down to match the canvas size.
Copy link to clipboard
Copied
What is your ruler units? I only get that error in CS6 if the ruler is set to percent. If your ruler is set to percent I can add some code to the script that will fix the error.
Copy link to clipboard
Copied
Hi Michael!
You are GREAT! My ruler was set to percentage. I changed it to inches and the script worked!!!
I just checked and it works both ways. Scaling up or down!
I work with texture layers a lot. And if I bring in a set of textures from another Doc, they are usually not the same size. So I have to manually scale each. This will definitely speed up my workflow.
Thanks!
Maxi!
5 Stars for you!!!
Copy link to clipboard
Copied
It is a good practice when writing scripts to save the current Photoshop ruler units and set the ruler units to units you want to work with something like pixels so you know what your dealing with. When ruler units are set to percent width = 100% and height = 100%. If you then compare width to height they will always be equal. 100% = 100% Before ending the script you set the ruler unit back to the saved ruler units so thing don't change on the user...
Distortion may be ok for textures like paper. However for regular patten texture like bricks changing their aspect ratio may turn brick into blocks or slabs of slate. A lot depends on how extreme the aspect ratio change is.
Copy link to clipboard
Copied
Here is a version with the ruler fix as well as other improvements. I add suspendHistory so it will only use one historyState, added a few checks, and an optional argument to keep aspect ratio for JJMack.
var maintainAspectRatio;// set to true to keep aspect ratio
if(app.documents.length>0){
app.activeDocument.suspendHistory ('Fit Layer to Canvas', 'FitLayerToCanvas('+maintainAspectRatio+')');
}
function FitLayerToCanvas( keepAspect ){// keepAspect:Boolean - optional. Default to false
var doc = app.activeDocument;
var layer = doc.activeLayer;
// do nothing if layer is background or locked
if(layer.isBackgroundLayer || layer.allLocked || layer.pixelsLocked
|| layer.positionLocked || layer.transparentPixelsLocked ) return;
// do nothing if layer is not normal artLayer or Smart Object
if( layer.kind != LayerKind.NORMAL && layer.kind != LayerKind.SMARTOBJECT) return;
// store the ruler
var defaultRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var width = doc.width.as('px');
var height =doc.height.as('px');
var bounds = app.activeDocument.activeLayer.bounds;
var layerWidth = bounds[2].as('px')-bounds[0].as('px');
var layerHeight = bounds[3].as('px')-bounds[1].as('px');
// move the layer so top left corner matches canvas top left corner
layer.translate(new UnitValue(0-layer.bounds[0].as('px'),'px'), new UnitValue(0-layer.bounds[1].as('px'),'px'));
if( !keepAspect ){
// scale the layer to match canvas
layer.resize( (width/layerWidth)*100,(height/layerHeight)*100,AnchorPosition.TOPLEFT);
}else{
var layerRatio = layerWidth / layerHeight;
var newWidth = width;
var newHeight = ((1.0 * width) / layerRatio);
if (newHeight >= height) {
newWidth = layerRatio * height;
newHeight = height;
}
var resizePercent = newWidth/layerWidth*100;
app.activeDocument.activeLayer.resize(resizePercent,resizePercent,AnchorPosition.TOPLEFT);
}
// restore the ruler
app.preferences.rulerUnits = defaultRulerUnits;
}
Copy link to clipboard
Copied
Mike you did it again you made me go read the guide for that suspendHistory. Some day I might actually know something about scripting Photoshop.
Copy link to clipboard
Copied
Back again in our last but one discussion (and the last, too).
Please can you help me to understand you better.
Why:
// …
// store the ruler
var defaultRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
//var width = doc.width.as('px');
//the rulers have already the unit.PIXELS ? - you defined it before -
why you don't use it ?
var width = doc.width.value;
//var height =doc.height.as('px');
var height = doc.height.value;
//var bounds = app.activeDocument.activeLayer.bounds;
// ------------- 'layer' is already defined before - why you don't use it ?
// (but I think is it better to use a different and not a confusingly similar variablename like --> 'aLayer' or 'theBounds' instead of 'layer' and 'bounds')
var bounds = layer.bounds;
//var layerWidth = bounds[2].as('px')-bounds[0].as('px');
var layerWidth = bounds[2].value-bounds[0].value;
//var layerHeight = bounds[3].as('px')-bounds[1].as('px');
var layerHeight = bounds[3].value-bounds[1].value;
// why you don't use your own variable 'bounds' ?
// I think it is safer and much easier to read - or what do you think?
//layer.translate(new UnitValue(0-layer.bounds[0].as('px'),'px'), new UnitValue(0-layer.bounds[1].as('px'),'px'));
layer.translate((0-bounds[0].value), (0-bounds[1].value));
// …
One could go a step further:
// …
// store the ruler
var defaultRulerUnits = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS;
var width = doc.width.value;
var height = doc.height.value;
var Bds = layer.bounds;
var Bds_0 = Bds[0].value;
var Bds_1 = Bds[1].value;
var Bds_2 = Bds[2].value;
var Bds_3 = Bds[3].value;
var layerWidth = Bds_2 - Bds_0;
var layerHeight = Bds_3 - Bds_1;
layer.translate((0 - Bds_0), (0 - Bds_1));
// …
What do you think about this?
In advance thanx for answering
pixxxelschubser
Copy link to clipboard
Copied
You some made good points. If I were writting this from the start I hope that the code would have been clearer and variable useage more consistant. But the first bit of code was something I put together to see if it answered the op needs. Adding setting the rulerUnit and checks were added because of the error with percent. The code for keeping the aspect ratio was from a different function that I modified to add that option.
I think that using .as('px') instead of .value is a matter of style. They both set height to a number object. Using .as('px') has an advantage of returning pixels with every ruler unit except percent( not that it matters here ). Using .value returns in whatever the current ruler is set to. But the main reason is I didn't bother to edit those lines after I set the ruler unit to pixels. I really think that the percent exception is a problem with the Object Model. It should work like other UnitValues.
I also think variable names and defining variables for each element in the bounds array is a matter of style. To me bounds[0].value is eaiser to read than Bds_0. And I don't see much difference between layer and aLayer. It is clear to me that layer is a variable and Layer is a Object Model class. Similary I don't see much difference between bounds and theBounds. However I do think either is better than Bds.
It is not that I think you are wrong. I just think you have a different style than I do.
Copy link to clipboard
Copied
Thank you for your response.
Michael L Hale wrote:
… But the main reason is I didn't bother to edit those lines after I set the ruler unit to pixels. I really think that the percent exception is a problem with the Object Model. It should work like other UnitValues …
It does.
But in post #1 you try the following:
var doc = app.activeDocument;
var layer = doc.activeLayer;
layer.translate(new UnitValue(0-layer.bounds[0].as('px'),'px'), new UnitValue(0-layer.bounds[1].as('px'),'px'))layer.resize((doc.width.value/(layer.bounds[2]-layer.bounds[0]))*100,(doc.height.value/(layer.bounds[3]-layer.bounds[1]))*100,AnchorPosition.TOPLEFT);
or shorter (in my style )
// …
layer.translate((0-Bds_0), (0-Bds_1));
// …
The result is a number - but a relativ number in the unit PERCENT (number *100).
It seems to be (you said it before), that PS can't translate correct with relativ percent. Every relative value in percent in PS should be divided by one hundred. And that's the reason for the error above.
If you make this:
(no translation to the left top corner)
and than only:
layer.resize(width/layerWidth*100,height/layerHeight*100,AnchorPosition.MIDDLECENTER);
than it works (not so exactly how your method from the left top corner, because the 'middlecenter' calculate in two directions - but it works)
This variante also works:
layer.translate((0-Bds_0)/100, (0-Bds_1)/100);
layer.resize(width/layerWidth*100,height/layerHeight*100,AnchorPosition.TOPLEFT);
and this too:
layer.translate((width-Bds_2)/100, (height-Bds_3)/100);
layer.resize(width/layerWidth*100,height/layerHeight*100,AnchorPosition.BOTTOMRIGHT);
Michael L Hale wrote:
… It is not that I think you are wrong. I just think you have a different style than I do.
charming expression
I think that I can live very well with that.
Thank you for your patience.
greetings
Copy link to clipboard
Copied
This has all been very interesting from the point of a non programmer. There are ways I'd like to work in PS on projects that take too many steps. I see now how they can be scripted.
Many thanks to Michael and JJMack, for your expert help!!!
Maxi
Copy link to clipboard
Copied
Hi Michael!
Don't know if you are using the new CC. Regarding the resize script. Do you know if you can choose PRESERVE DETAIL as the scaling method? Its in the image resize, but I don't know if it could be accessed by the script?
I do notice a difference in the quality of the upscale.
Thanks
Max
Copy link to clipboard
Copied
I don't know if that new feature is supported by the object model. Adobe hasn't released the CC JavaScript Ref. But scriptlistener does record the menu item image size... with a new stringID, stringIDToTypeID( "preserveDetailsUpscale" ), so it is possible to resize the document with that option.
As I understand it layer resize uses the resample method from the Photoshop preferences. And I don't see any new options in that preference setting dropdownlist. So I would guess that if you wanted to resize a layer with that option you would first need to dupe the layer to a new doc, resize the new doc, then dupe the layer back to the original doc.
Copy link to clipboard
Copied
Just came across this thread about this type of script which will help with my photoshop workflow.
Though what I need is for the canvas size to remain the same, in my case it's 850px x 572px, and scale the layer size down to fit the canvas but lock aspect ratio of the layer I'm scaling. So it would be fit to width or height
I've noticed in JJMacks post he was talking about the spill over the canvas when keeping the aspect ratio of the layer. This is excatly what I need for my workflow.
I tried the script above, which Michael L Hale posted up, it's own right but I still noticed it scaled my image to fit the cavas which resulted in distortion. Do I have to change any parameters in the script to maintain aspect ratio of my layer?Thanks in advance,
Evan
Copy link to clipboard
Copied
Bump -
I need the same thing requested by Evanalmighty -
How do I modify the script from Michael L Hale so that the canvas size is maintained, but the layer selected aspect ratio is maintained but scaled to fit either the height or width of the canvas depending on which is greater, or in the event that both height and width are already 1:1 match of the canvas it would fill. In my workflow, I use NTSC standard size canvas, but have images I need to place on the canvas that are usually much larger or much wider (i.e, billboard artwork, print ads, banners, etc.) and it would be great to click one button and have the layer scale uniformly to fill one aspect while maintaining H+W proportions. Please help!
Matt
Copy link to clipboard
Copied
Hey...
Can someone help me out about what values should I change to keep the aspect ratio? I've seen some comments inside the code where there is supposed to change something, but I'm new to Scripts so I don't know exactly what to change.
Thanks in advance...
Copy link to clipboard
Copied
If you post the code we may be able to help. Your replaying the an append that is years old.
Copy link to clipboard
Copied
Hey JJMack...
The code I'm trying to use and customize was provided by Michael L. Hale in this thread.
I'm able to run the script but the aspect ratio is not kept. I would like to know what should I change in the following code in order to keep the aspect ratio of the selected layer. That means that either the width or the height must match canvas size.
Here's the code...
- var maintainAspectRatio;// set to true to keep aspect ratio
- if(app.documents.length>0){
- app.activeDocument.suspendHistory ('Fit Layer to Canvas', 'FitLayerToCanvas('+maintainAspectRatio+')');
- }
- function FitLayerToCanvas( keepAspect ){// keepAspect:Boolean - optional. Default to false
- var doc = app.activeDocument;
- var layer = doc.activeLayer;
- // do nothing if layer is background or locked
- if(layer.isBackgroundLayer || layer.allLocked || layer.pixelsLocked
- || layer.positionLocked || layer.transparentPixelsLocked ) return;
- // do nothing if layer is not normal artLayer or Smart Object
- if( layer.kind != LayerKind.NORMAL && layer.kind != LayerKind.SMARTOBJECT) return;
- // store the ruler
- var defaultRulerUnits = app.preferences.rulerUnits;
- app.preferences.rulerUnits = Units.PIXELS;
- var width = doc.width.as('px');
- var height =doc.height.as('px');
- var bounds = app.activeDocument.activeLayer.bounds;
- var layerWidth = bounds[2].as('px')-bounds[0].as('px');
- var layerHeight = bounds[3].as('px')-bounds[1].as('px');
- // move the layer so top left corner matches canvas top left corner
- layer.translate(new UnitValue(0-layer.bounds[0].as('px'),'px'), new UnitValue(0-layer.bounds[1].as('px'),'px'));
- if( !keepAspect ){
- // scale the layer to match canvas
- layer.resize( (width/layerWidth)*100,(height/layerHeight)*100,AnchorPosition.TOPLEFT);
- }else{
- var layerRatio = layerWidth / layerHeight;
- var newWidth = width;
- var newHeight = ((1.0 * width) / layerRatio);
- if (newHeight >= height) {
- newWidth = layerRatio * height;
- newHeight = height;
- }
- var resizePercent = newWidth/layerWidth*100;
- app.activeDocument.activeLayer.resize(resizePercent,resizePercent,AnchorPosition.TOPLEFT);
- }
- // restore the ruler
- app.preferences.rulerUnits = defaultRulerUnits;
- }