//============================================================================= // // Web Output Script // This script embodies the Marc Adamus/Thom Hogan approach to resizing // and sharpening images for the web // Marc Adamus http://pacificnw.naturephotographers.net/tips/photoshop.htm // Thom Hogan http://forums.dpreview.com/forums/readflat.asp?forum=1039&thread=32107577&page=1 // // Some code snips were borrowed from fragments posted here: // View Actual Pixels http://www.ps-scripts.com/bb/viewtopic.php?p=224&highlight=#224 // Long Side Resize http://www.adobe.com/cfusion/exchange/index.cfm?event=extensionDetail&extid=1044732 // // The procedures MergeAllVisible and applyBlendIf were taken from the // TLR Professional Sharpening Toolkit and are used with permission. // http://www.thelightsright.com/TLRProfessionalSharpeningToolkit // // I wish to acknowledge and thanks those good people for their contributions. // // The little remaining code was written by me, Malcolm Hoar // // Installation: // Place this file in your Photoshop presets\scripts folder and restart Photoshop // // Usage: // To resize and sharpen an image simple select File | Scripts | Websize // By default this resizes to 1280 pixels on the longest side. // You can change this by editing the value of "longSize" (below). // You can also create multiple copies of this script with different // values of "longSize": Websize800, Websize1024 etc. // // Operation: // 1. Merge all visible layers (Web Output Presharp) // 2. Apply USM (150, 0.8, 5) Blend mode is set to Luminosity and // a BlendIf is applied to protect highlights // 3. Merge all visible layers (Web Output Sharp) // 4. Resize image to 1.66666 * longSize // 5. Apply Filter | Sharpen // 6. Apply Filter | Sharpen (a second time) // 7. Apply Filter | Sharpen (a third time) // 8. Set Blend mode (Luminosity) BlendIf and Opacity (50%) // 9. Resize image to longSize // 10. Add a reveal-all layer mask // 11. View | Actual Pixels // // Note that the opacity of the topmost layer is set to 50%. // You may reduce the opacity further if the image appears too // crunchy. Alternatively, you can increase the opacity to increase // the sharpness. This may produce some objectional halos on strong, // high contrast edges. This is expected. Simply select the Brush // tool loaded with Black and paint away the halos via the layer // mask. Be sure to paint on the mask and not on the image itself. // //============================================================================= // Defines the size of the required output images (longest side in pixels) var longSide = 1280; // BlendIf params to avoid blown highlights // const singleBlendIf = [8, 16, 220, 250, 8, 16, 220, 250]; const singleBlendIf = [8, 16, 200, 250, 0, 0, 255, 255]; if (!app.documents.length > 0) { alert("No open document"); } else { // Save unit prefs -- restore on exit var originalUnit = app.preferences.rulerUnits; app.preferences.rulerUnits = Units.PIXELS; var docRef = app.activeDocument; // Merge Visible Layers mergeAllVisible(); docRef.activeLayer.name = 'Web Output Presharp'; // Unsharp mask docRef.activeLayer.applyUnSharpMask(150, 0.8, 5); docRef.activeLayer.blendMode = BlendMode.LUMINOSITY; applyBlendIf(singleBlendIf); // Merge Visible Layers mergeAllVisible(); docRef.activeLayer.name = 'Web Output Sharp'; // Resize imageResize (longSide * 1.66666); // Sharpen docRef.activeLayer.applySharpen(); docRef.activeLayer.applySharpen(); docRef.activeLayer.applySharpen(); docRef.activeLayer.blendMode = BlendMode.LUMINOSITY; applyBlendIf(singleBlendIf); docRef.activeLayer.opacity = 50; // Resize again imageResize (longSide); // Add Reveal All layer mask AddImageMask ("RvlA"); // Restore unit prefs app.preferences.rulerUnits = originalUnit; // View Actual Pixels imageView('FtOn'); imageView('ActP'); } //============================================================================= function AddImageMask (type) { // "RvlA" or "HdAl" var id189 = charIDToTypeID( "Mk " ); var desc56 = new ActionDescriptor(); var id190 = charIDToTypeID( "Nw " ); var id191 = charIDToTypeID( "Chnl" ); desc56.putClass( id190, id191 ); var id192 = charIDToTypeID( "At " ); var ref50 = new ActionReference(); var id193 = charIDToTypeID( "Chnl" ); var id194 = charIDToTypeID( "Chnl" ); var id195 = charIDToTypeID( "Msk " ); ref50.putEnumerated( id193, id194, id195 ); desc56.putReference( id192, ref50 ); var id196 = charIDToTypeID( "Usng" ); var id197 = charIDToTypeID( "UsrM" ); var id198 = charIDToTypeID( type ); desc56.putEnumerated( id196, id197, id198 ); executeAction( id189, desc56, DialogModes.NO ); } //============================================================================= function imageResize (lSide) { var docRef = app.activeDocument; var docWidth = docRef.width.as("px"); var docHeight = docRef.height.as("px"); if (docWidth > docHeight) { var multiplier = lSide/docWidth; docRef.resizeImage(lSide, docHeight*multiplier, 72, ResampleMethod.BICUBIC ); } else { var multiplier = lSide/docHeight; docRef.resizeImage(docWidth*multiplier, lSide, 72, ResampleMethod.BICUBIC ); } } //============================================================================= function imageView (view) { var id73 = charIDToTypeID( "slct" ); var desc17 = new ActionDescriptor(); var id74 = charIDToTypeID( "null" ); var ref13 = new ActionReference(); var id75 = charIDToTypeID( "Mn " ); var id76 = charIDToTypeID( "MnIt" ); if (view.length < 5) var id77 = charIDToTypeID( view ); else var id77 = stringIDToTypeID( view ); ref13.putEnumerated( id75, id76, id77 ); desc17.putReference( id74, ref13 ); executeAction( id73, desc17, DialogModes.NO ); } //============================================================================= function mergeAllVisible() { var moduleName = 'applyMergeAllVisible'; try { var id836 = charIDToTypeID( "Mk " ); var desc233 = new ActionDescriptor(); var id837 = charIDToTypeID( "null" ); var ref196 = new ActionReference(); var id838 = charIDToTypeID( "Lyr " ); ref196.putClass( id838 ); desc233.putReference( id837, ref196 ); executeAction( id836, desc233, DialogModes.NO ); var id839 = charIDToTypeID( "MrgV" ); var desc234 = new ActionDescriptor(); var id840 = charIDToTypeID( "Dplc" ); desc234.putBoolean( id840, true ); executeAction( id839, desc234, DialogModes.NO ); } catch(someError) { alert( "An unexpected JavaScript error occurred in " + moduleName + ". Message = " + someError.description); ui.close(0); } } //============================================================================= function applyBlendIf(blendIfSettings) { var moduleName = 'applyBlendIf'; ThisBlackLow = blendIfSettings[0]; ThisBlackHigh = blendIfSettings[1]; ThisWhiteLow = blendIfSettings[2]; ThisWhiteHigh = blendIfSettings[3]; UnderlyingBlackLow = blendIfSettings[4]; UnderlyingBlackHigh = blendIfSettings[5]; UnderlyingWhiteLow = blendIfSettings[6]; UnderlyingWhiteHigh = blendIfSettings[7]; try { // Code generated by ScriptListener // ======================================================= var id1457 = charIDToTypeID( "setd" ); var desc339 = new ActionDescriptor(); var id1458 = charIDToTypeID( "null" ); var ref262 = new ActionReference(); var id1459 = charIDToTypeID( "Lyr " ); var id1460 = charIDToTypeID( "Ordn" ); var id1461 = charIDToTypeID( "Trgt" ); ref262.putEnumerated( id1459, id1460, id1461 ); desc339.putReference( id1458, ref262 ); var id1462 = charIDToTypeID( "T " ); var desc340 = new ActionDescriptor(); var id1463 = charIDToTypeID( "Blnd" ); var list117 = new ActionList(); var desc341 = new ActionDescriptor(); var id1464 = charIDToTypeID( "Chnl" ); var ref263 = new ActionReference(); var id1465 = charIDToTypeID( "Chnl" ); var id1466 = charIDToTypeID( "Chnl" ); var id1467 = charIDToTypeID( "Gry " ); ref263.putEnumerated( id1465, id1466, id1467 ); desc341.putReference( id1464, ref263 ); var id1468 = charIDToTypeID( "SrcB" ); desc341.putInteger( id1468, ThisBlackLow ); var id1469 = charIDToTypeID( "Srcl" ); desc341.putInteger( id1469, ThisBlackHigh ); var id1470 = charIDToTypeID( "SrcW" ); desc341.putInteger( id1470, ThisWhiteLow ); var id1471 = charIDToTypeID( "Srcm" ); desc341.putInteger( id1471, ThisWhiteHigh ); var id1472 = charIDToTypeID( "DstB" ); desc341.putInteger( id1472, UnderlyingBlackLow ); var id1473 = charIDToTypeID( "Dstl" ); desc341.putInteger( id1473, UnderlyingBlackHigh ); var id1474 = charIDToTypeID( "DstW" ); desc341.putInteger( id1474, UnderlyingWhiteLow ); var id1475 = charIDToTypeID( "Dstt" ); desc341.putInteger( id1475, UnderlyingWhiteHigh ); var id1476 = charIDToTypeID( "Blnd" ); list117.putObject( id1476, desc341 ); desc340.putList( id1463, list117 ); var id1477 = charIDToTypeID( "Lefx" ); var desc342 = new ActionDescriptor(); var id1478 = charIDToTypeID( "Scl " ); var id1479 = charIDToTypeID( "#Prc" ); desc342.putUnitDouble( id1478, id1479, 333.333333 ); var id1480 = charIDToTypeID( "Lefx" ); desc340.putObject( id1477, id1480, desc342 ); var id1481 = charIDToTypeID( "Lyr " ); desc339.putObject( id1462, id1481, desc340 ); executeAction( id1457, desc339, DialogModes.NO ); // ======================================================= } catch(someError) { alert( "An unexpected JavaScript error occurred in " + moduleName + ". Message = " + someError.description); ui.close(0); } } //=============================================================================