Photoshop Javascript 根据文件大小调整大小

发布于 2024-12-22 01:16:06 字数 5684 浏览 0 评论 0原文

我有一个包含很多子文件夹的文件夹,每个子文件夹中都包含一堆 TIF 和 PSD 文件。其中一些具有透明度,而另一些则没有。这些文件的大小差异很大。

我需要将所有文件转换为 JPG,或者如果它们包含透明度,则转换为 PNG。我要求文件大小不超过 200kb,并且只要不按比例放大,我并不介意它们有多大。

论坛上的某人(我非常感谢他)为此编写了相当多的代码,我的朋友对其进行了修改以完全满足我的要求,现在我们已经快完成了。

它工作得很好,唯一的问题是很多图像都是 1x1 像素和纯色块。

我们发现由于某种原因,相同的图像始终会发生这种情况,但无法弄清楚这些图像中到底是什么。

现在论坛先生 ( http://www.photoshopgurus.com/forum/members/ paul-mr.html )修改了脚本,现在似乎可以与 PSD 配合使用。

它可以处理具有透明度的 TIF,但它无法处理某些具有 100% 不透明度的 TIF。除了蓝色之外,我找不到与这些文件一致的内容,尽管这可能是一个巨大的巧合,而且可能确实如此(我一直在处理的图像中有很多蓝色)。

以下是首次编写代码的线程的链接。 Paul MR 似乎认为颜色采样器位有点可疑,所以也许这就是导致问题的原因(蓝色?)。

http://www.photoshopgurus.com/forum/photoshop-actions-automation/34745-batching-tiffs-jpg-png-w-automatic-resize-based-filesize.html

我希望我能做更多的事情来尝试自己解决这个问题,但我对这些东西几乎一无所知,我只知道在什么情况下一些脚本可以提供帮助。

以下是当前的脚本:

#target PhotoshopString.prototype.endsWith  = function(str) {
 return (this.match(str  + "$")  == str)
} String.prototype.startsWith  = function(str) {
    return this.indexOf(str)  == 0;
};
var desiredFileSize  = 200000;
app.bringToFront();
app.displayDialogs  = DialogModes.NO;
main();
//app.displayDialogs = DialogModes.YES;
function main() {
    var topLevelFolder  = Folder.selectDialog("Please select top level folder.");
    if (topLevelFolder  == null)return;
    var FileList  = [];
    getFileList(topLevelFolder);
    var startRulerUnits  = app.preferences.rulerUnits;
    app.preferences.rulerUnits  = Units.PIXELS;
    for (var f in FileList)  {
        app.open(FileList[f]);
        activeDocument.changeMode(ChangeMode.RGB);
        try  {
            activeDocument.mergeVisibleLayers();
        } catch(e)  {} var Name  = decodeURI(app.activeDocument.name).replace(/.[^.] + $ /, '');
        if (hasTransparency(FileList[f]))  {
            var saveFile  = File(FileList[f].path  + "/"  + Name  + ".png");
            SavePNG(saveFile);
            app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
        } else  {
            var saveFile  = File(FileList[f].path  + "/"  + Name  + ".jpg");
            SaveForWeb(saveFile, 80);
            app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
        } app.preferences.rulerUnits  = startRulerUnits;
    } function getFileList(folder)  {
        var fileList  = folder.getFiles();
        for (var i = 0; i < fileList.length; i++)  {
            var file  = fileList[i];
            if (file instanceof Folder)  {
                getFileList(file);
            } else  {
                if ((file.name.endsWith("tiff")  || file.name.endsWith("tif")  || file.name.endsWith("psd"))  &&  ! file.name.startsWith("._"))FileList.push(file);
            }
        }
    } alert(FileList.length  + " files have been modified.");
} function hasTransparency(file) {
    if (file.name.endsWith("tiff")  || file.name.endsWith("tif"))  {
        var sample  = app.activeDocument.colorSamplers.add([new UnitValue(1.5, 'px'), new UnitValue(1.5, 'px')]);
        try  {
            sample.color.rgb.hexValue;
            sample.remove();
            return false;
        } catch(e)  {
            sample.remove();
            return true;
        }
    } var doc  = activeDocument;
    if (doc.activeLayer.isBackgroundLayer)return false;
    var desc  = new ActionDescriptor();
    var ref  = new ActionReference();
    ref.putProperty(charIDToTypeID("Chnl"), charIDToTypeID("fsel"));
    desc.putReference(charIDToTypeID("null"), ref);
    var ref1  = new ActionReference();
    ref1.putEnumerated(charIDToTypeID("Chnl"), charIDToTypeID("Chnl"), charIDToTypeID("Trsp"));
    desc.putReference(charIDToTypeID("T "), ref1);
    executeAction(charIDToTypeID("setd"), desc, DialogModes.NO);
    var w  = doc.width.as('px');
    var h  = doc.height.as('px');
    var transChannel  = doc.channels.add();
    doc.selection.store(transChannel);
    if (transChannel.histogram[255]  != (h  * w))  {
        transChannel.remove();
        return true;
    } else  {
        transChannel.remove();
        return false;
    }
};
function SavePNG(saveFile) {
    pngSaveOptions  = new PNGSaveOptions();
    activeDocument.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE);
    var actualFilesize  = saveFile.length;
    var ratio  = desiredFileSize / actualFilesize;
    if (ratio  < 1)  {
        var imageScale  = Math.sqrt(ratio);
        activeDocument.resizeImage(activeDocument.width  * imageScale, activeDocument.height  * imageScale, activeDocument.resolution, ResampleMethod.BICUBICSMOOTHER);
        activeDocument.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE);
    }
}
function SaveForWeb(saveFile, jpegQuality) {
    var sfwOptions  = new ExportOptionsSaveForWeb();
    sfwOptions.format  = SaveDocumentType.JPEG;
    sfwOptions.includeProfile  = false;
    sfwOptions.interlaced  = 0;
    sfwOptions.optimized  = true;
    sfwOptions.quality  = jpegQuality;
    activeDocument.exportDocument(saveFile, ExportType.SAVEFORWEB, sfwOptions);
    var actualFilesize  = saveFile.length;
    var ratio  = desiredFileSize / actualFilesize;
    if (ratio  < 1)  {
        var imageScale  = Math.sqrt(ratio);
        activeDocument.resizeImage(activeDocument.width  * imageScale, activeDocument.height  * imageScale, activeDocument.resolution, ResampleMethod.BICUBICSMOOTHER);
        activeDocument.exportDocument(saveFile, ExportType.SAVEFORWEB, sfwOptions);
    }
}

I have a folder with a lot of subfolders, each with a bunch of TIFs and PSD files inside. Some of these have transparency in them while some don't. These files vary massively in size.

I need all the files to be turned into JPGs, or if they contain transparency, PNGs. I require the files to be 200kb or less and don't really mind how large they are as long as they aren't scaled up.

Someone on a forum (who I'm insanely thankful for) wrote a fair bit of code for it, which my friend modified to suit exactly what I was asking and we're nearly there now.

It worked fine, the only problem being that a lot of images came out 1x1 pixel and a solid block of colour.

We've found this was consistently happening with the same images for some reason, but couldn't work out what exactly it was in these images.

Now Mr forum blokey ( http://www.photoshopgurus.com/forum/members/paul-mr.html ) modified the script and it now seems to work fine with PSDs.

It's working with TIFs with transparency but some of the TIFs with 100% opacity it just won't work on. I can't find much that's consistent with these files other than the colour blue, though this just could be a massive coincidence and probably is (there's a lot of blue in the images I've been dealing with).

Below is a link to the thread in which the code was first written. Paul MR seems to think the colorsampler bit is a little suspect so perhaps that's what's causing the problems (blueness?).

http://www.photoshopgurus.com/forum/photoshop-actions-automation/34745-batching-tiffs-jpg-png-w-automatic-resize-based-filesize.html

I wish I could do a little more to try and work this out myself but I've barely a speck of understanding on this stuff, I just know when there's a situation where a bit of scripting could help out.

Below is the script as it currently stands:

#target PhotoshopString.prototype.endsWith  = function(str) {
 return (this.match(str  + "$")  == str)
} String.prototype.startsWith  = function(str) {
    return this.indexOf(str)  == 0;
};
var desiredFileSize  = 200000;
app.bringToFront();
app.displayDialogs  = DialogModes.NO;
main();
//app.displayDialogs = DialogModes.YES;
function main() {
    var topLevelFolder  = Folder.selectDialog("Please select top level folder.");
    if (topLevelFolder  == null)return;
    var FileList  = [];
    getFileList(topLevelFolder);
    var startRulerUnits  = app.preferences.rulerUnits;
    app.preferences.rulerUnits  = Units.PIXELS;
    for (var f in FileList)  {
        app.open(FileList[f]);
        activeDocument.changeMode(ChangeMode.RGB);
        try  {
            activeDocument.mergeVisibleLayers();
        } catch(e)  {} var Name  = decodeURI(app.activeDocument.name).replace(/.[^.] + $ /, '');
        if (hasTransparency(FileList[f]))  {
            var saveFile  = File(FileList[f].path  + "/"  + Name  + ".png");
            SavePNG(saveFile);
            app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
        } else  {
            var saveFile  = File(FileList[f].path  + "/"  + Name  + ".jpg");
            SaveForWeb(saveFile, 80);
            app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
        } app.preferences.rulerUnits  = startRulerUnits;
    } function getFileList(folder)  {
        var fileList  = folder.getFiles();
        for (var i = 0; i < fileList.length; i++)  {
            var file  = fileList[i];
            if (file instanceof Folder)  {
                getFileList(file);
            } else  {
                if ((file.name.endsWith("tiff")  || file.name.endsWith("tif")  || file.name.endsWith("psd"))  &&  ! file.name.startsWith("._"))FileList.push(file);
            }
        }
    } alert(FileList.length  + " files have been modified.");
} function hasTransparency(file) {
    if (file.name.endsWith("tiff")  || file.name.endsWith("tif"))  {
        var sample  = app.activeDocument.colorSamplers.add([new UnitValue(1.5, 'px'), new UnitValue(1.5, 'px')]);
        try  {
            sample.color.rgb.hexValue;
            sample.remove();
            return false;
        } catch(e)  {
            sample.remove();
            return true;
        }
    } var doc  = activeDocument;
    if (doc.activeLayer.isBackgroundLayer)return false;
    var desc  = new ActionDescriptor();
    var ref  = new ActionReference();
    ref.putProperty(charIDToTypeID("Chnl"), charIDToTypeID("fsel"));
    desc.putReference(charIDToTypeID("null"), ref);
    var ref1  = new ActionReference();
    ref1.putEnumerated(charIDToTypeID("Chnl"), charIDToTypeID("Chnl"), charIDToTypeID("Trsp"));
    desc.putReference(charIDToTypeID("T "), ref1);
    executeAction(charIDToTypeID("setd"), desc, DialogModes.NO);
    var w  = doc.width.as('px');
    var h  = doc.height.as('px');
    var transChannel  = doc.channels.add();
    doc.selection.store(transChannel);
    if (transChannel.histogram[255]  != (h  * w))  {
        transChannel.remove();
        return true;
    } else  {
        transChannel.remove();
        return false;
    }
};
function SavePNG(saveFile) {
    pngSaveOptions  = new PNGSaveOptions();
    activeDocument.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE);
    var actualFilesize  = saveFile.length;
    var ratio  = desiredFileSize / actualFilesize;
    if (ratio  < 1)  {
        var imageScale  = Math.sqrt(ratio);
        activeDocument.resizeImage(activeDocument.width  * imageScale, activeDocument.height  * imageScale, activeDocument.resolution, ResampleMethod.BICUBICSMOOTHER);
        activeDocument.saveAs(saveFile, pngSaveOptions, true, Extension.LOWERCASE);
    }
}
function SaveForWeb(saveFile, jpegQuality) {
    var sfwOptions  = new ExportOptionsSaveForWeb();
    sfwOptions.format  = SaveDocumentType.JPEG;
    sfwOptions.includeProfile  = false;
    sfwOptions.interlaced  = 0;
    sfwOptions.optimized  = true;
    sfwOptions.quality  = jpegQuality;
    activeDocument.exportDocument(saveFile, ExportType.SAVEFORWEB, sfwOptions);
    var actualFilesize  = saveFile.length;
    var ratio  = desiredFileSize / actualFilesize;
    if (ratio  < 1)  {
        var imageScale  = Math.sqrt(ratio);
        activeDocument.resizeImage(activeDocument.width  * imageScale, activeDocument.height  * imageScale, activeDocument.resolution, ResampleMethod.BICUBICSMOOTHER);
        activeDocument.exportDocument(saveFile, ExportType.SAVEFORWEB, sfwOptions);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文