SaveAs jpg quality not working

Hello,
The quality option doesn’t seem to work. I get:
File size: 824KB with quality:12
File size: 681KB with quality:1
Quality 1 should be a much smaller file size … I don’t understand what I am doing wrong…
Thx for your help,
fred

        const storage = require("uxp").storage;
        const lfs = storage.localFileSystem;
        
        await require('photoshop').core.executeAsModal(async () => {
            try {
                let f = await lfs.getFileForSaving("Logo_OK_FINAL_TODAY_LAST.jpg");
        
                await app.activeDocument.saveAs.jpg( f,  {
                    embedColorProfile: true, quality: 1
            }, true );

            } catch (error) {
                console.error("Error creating export file:", error.message);
            }
        })

It really depends on the file contents. For example, if the image is a solid white square, there isn’t much data for the JPEG compression algorithm to compress, so the file size difference between quantity 12 and 1 would be small.

To test, open your image in Photoshop and then open the save for web dialog via File > Export > Save for Web (Legacy).... Adjust the quantity and check the file size at different qualities and see if you get the same results as the script.

And, just so you know, when I test a color picture using your script, the difference between quality 1 and quality 12 is evident in the file size and also visually.

Hi Duncan,
Thank you for your response.
I tried different export types in the Photoshop interface and the only one exporting to a very small file in the lowest quality is, like you said: SaveForWeb (Legacy).

This works very well in Extendscript:

                var options = new ExportOptionsSaveForWeb();
                    options.format = SaveDocumentType.JPEG;
                    options.includeProfile = true;
                    options.quality = 3;
                    options.optimized = true;

                // export to JPG
                app.activeDocument.exportDocument(exportFile, ExportType.SAVEFORWEB, options);

Is there a UXP code available doing that (API ou BatchPlay) ?

Thx,
Fred

Your code should work as long as the image can be successfully compressed by the JPEG algorithm. Using your code with a JPEG picture I get the following result.

  • Quality 12 = 2.2 MB jpeg file
  • Quality 1 = 301 KB jpeg file

As you can see, a lower quality does result in a smaller file size using your code. Also note, if I use the legacy Export for Web dialog and set the quality to 10 (roughly 1 on a 1-12 scale) the file size is very similar as what was exported from your script.

Can you post an example image that is giving you trouble? Maybe that will help figure out why you are not getting the expected results.



Hello, I coded a quick .psjs file to check the saveas jpg of a 300x600.psd with a solid green background with 2 different quality settings and I really dont understand what’s wrong here.

with quality = 10 the file size is: 624 KB.
with quality = 1 the file size is: 622 KB.

If I use Export > Export As in photoshop, the file is 1.5 KB

const photoshop = require("photoshop");
const { constants } = photoshop;
const fs = require("uxp").storage.localFileSystem;
const app = photoshop.app;
const { showAlert } = photoshop.core;

    await require('photoshop').core.executeAsModal(async () => {
        
        try {
            let options = {
                embedColorProfile: false, // Disable color profiles
                quality: 1, // Adjust quality (1-12)
                formatOptions: constants.JPEGFormatOptions.OPTIMIZEDBASELINE
            };

            const myFolder =  await fs.getFolder();
            await showAlert("myFolder: "  + myFolder)
            const uniqueFileName = `JPG_quality_${options.quality}.jpg`;
            const exportFile = await fs.createEntryWithUrl(`${myFolder.nativePath}/${uniqueFileName}`, { overwrite: true });
            await app.activeDocument.saveAs.jpg(exportFile, options, true);
                    
        } catch (error) {
            await showAlert("error: "  + error)
            console.error("Error during export:", error.message);
        }
    });

Not sure now, but I think I saw some post saying that in some case quality value is 1-255. Can you try setting it 255 and see what happens? No guarantees though :slightly_smiling_face:

Hi, thanks for the tip. I just tried quality = 255 and the file size is: 624 KB :frowning:

I really don’t understand. SaveForWeb in Extendscript used to to do this really well but Adobe removed it from UXP if I understand correctly…

So, the first thing that jumps out at me is that your exported file sizes seem way too big for a 300x600 image. I mean, a real saved Photoshop psd file at 300x600 with a simple green background is only 40 KB on my system…

Using an identical 300x600 at 72 ppi file,

If I run your script, I get:

JPG_Quality_1.jpg   @ 13 KB
JPG_Quality_12.jpg  @ 14 KB

If I use Export As, I get:

JPG_Quality_1.jpg   @ 1 KB
JPG_Quality_7.jpg   @ 2 KB

If I use Save For Web (Legacy), I get:

JPG_Quality_12.jpg  @ 2 KB // 12 to match the 1 from above on a 1-12 scale 
JPG_Quality_100.jpg @ 3 KB

If I increase the ppi to 300, the exported sizes using your script are still only:

JPG_Quality_12.jpg  @ 13 KB
JPG_Quality_100.jpg @ 14 KB

As you can see, none of the methods export the same file sizes. I know from previous experience scripting with Illustrator that different parts of the program use different code and the quality and exported sizes from a script can differ quite a bit. This still doesn’t explain the really large files sizes you are getting so I fear I may be out of solutions…

This may be a long shot but are you using the latest version of Photoshop? If not, maybe try updating and see if you get the same numbers.

Wow! thank you so much for looking into that… I just tried with a brand new 300x600.psd with just a red background and I do get a 15KB jpg file …

Now, i am comparing the 2 PSDs to catch any differences.

So, I think that I spotted the difference between the 2 PSDs:

The green one has a FILL LAYER. In Photoshop: Layer > New Fill Layer > Solid Color…
When selected, this layer has no properties in the properties panel.

The red one is just a PIXEL layer filled with red.
When selected, this layer has properties in the properties panel, like Transform, Align, etc..

Using uxp SaveAs jpg, the PSD with Fill Layer is not compressed (624KB) but the one with Pixel is (15KB)…


1 Like

Wait… This makes SaveAs JPEG via API pretty much useless :confused:

Well, I am going to ask the designers at my company NOT to use that FILL LAYER in their PSDs for now …

Or merge all layers to new raster layer on a new document, then export and close that document

Yeah, I would think it shouldn’t matter. Maybe first flatten the image in your script and then use the export to ensure you get the smallest file size. Seems like a bug in the API to me.

Hello, thank you all for your help.
I tried to flatten the PSD before SaveAs jpg and … it doesn’t work :frowning: The exported jpg with quality = 1 is 630KB … this is crazy. I am filling a bug about that.
Cheer,
Fred

const photoshop = require("photoshop");
const { constants } = photoshop;
const fs = require("uxp").storage.localFileSystem;
const app = photoshop.app;
const { showAlert } = photoshop.core;

    await require('photoshop').core.executeAsModal(async () => {
       
        try {

            let options = {
                embedColorProfile: false, // Disable color profiles
                quality: 1, // Adjust quality (1-12)
                formatOptions: constants.JPEGFormatOptions.OPTIMIZEDBASELINE
            };

            await app.activeDocument.flatten();

            const myFolder =  await fs.getFolder();
            await showAlert("myFolder: "  + myFolder)
            const uniqueFileName = `JPG_quality_${options.quality}.jpg`;
            const exportFile = await fs.createEntryWithUrl(`${myFolder.nativePath}/${uniqueFileName}`, { overwrite: true });
            await app.activeDocument.saveAs.jpg(exportFile, options, true);
                    
        } catch (error) {
            await showAlert("error: "  + error)
            console.error("Error during export:", error.message);
        }
    });