Optimize images for Desktop Background display

Oct 26, '10 07:30:00AM

Contributed by: philostein

I have a large number of irregularly shaped images that I use as Desktop Backgrounds. In Desktop & Screen Saver preferences, 'Fill Screen' or 'Fit to Screen' makes small images ugly, and 'Center' crops large images quite badly -- and I'd rather keep all the images in one folder, and displayed properly.

I wrote a script to pad small images to the screen size, and large images to the screen aspect ratio. It works on the Finder selection and overwrites the input files, so use duplicates. Open the script in AppleScript Editor and change _screenWidth and _screenHeight to match your display. Now, with 'Fill Screen' selected, padded images are always displayed correctly (with a black border), and un-padded images (for me, photos) fill the whole display.

Image events can't read the dimensions of some images such as PICT files. The script will pass over these, and other non-image files. Properly proportioned large images will also be passed over (correct to 2 decimal places). The script contains some notes. Errors are logged by the script.

WARNING: The script overwrites original files, so work on copies. The code follows. It's long, so you may wish to download it from the link above.

--WARNING: This script overwrites original files, work on copies.

-- Change these variables to your screen dimensions…
set _screenWidth to 1280
set _screenHeight to 800

-- Don't change this!
set _screenRatio to _screenWidth / _screenHeight

try
  tell application "Finder"
    with timeout of 600 seconds
      set _selection to selection
    end timeout
    if _selection = {} then error "No files selected…" number 1
  end tell
  
  display dialog "Warning: This script will overwrite selected files.

Please work on duplicates." with title "Pad Images for the Desktop" buttons {"Cancel", "Continue"} default button "Cancel"
  
  set _fileNames to {}
  repeat with _file in _selection
    try
      tell application "Finder" to set _alias to _file as alias
      set _aliasText to _alias as text
      set end of _fileNames to _aliasText
    end try
  end repeat
  if _fileNames = {} then error "No filenames" number 1
  
  tell application "Image Events"
    launch
    repeat with _fileName in _fileNames
      try
        set _image to open _fileName
        
        -- This will throw an error if file is not valid - _image is undefined
        set _dimensions to dimensions of _image
        if _dimensions = {} then error "No dimensions for this file…" number 1 --Not an image, or unable to get dimensions
        
        set {_width, _height} to {item 1 of _dimensions as integer, item 2 of _dimensions as integer}
        
        set _ratio to (_width / _height) -- image aspect ratio
        set _ratio to (_ratio * 100 as integer) / 100 -- round to 2 decimal places
        
        if _width < _screenWidth and _height < _screenHeight then
          -- Image smaller than the screen, pad to screen size
          set {_newWidth, _newHeight} to {_screenWidth, _screenHeight}
        else
          if _ratio = _screenRatio then
            -- Do nothing!
            error "The image doesn't need padding." number 1
          end if
          
          if _width ≥ _height then
            -- 'Landscape' image
            
            if _ratio < _screenRatio then
              -- Pad sides
              set _newWidth to (_height * _screenRatio) as integer
              set _newHeight to _height
            end if
            
            if _ratio > _screenRatio then
              -- Pad top and bottom
              set _newHeight to (_width / _screenRatio) as integer
              set _newWidth to _width
            end if
          else
            -- 'Portrait' image
            set _newWidth to (_height * _screenRatio) as integer
            set _newHeight to _height
          end if
        end if
        
        
        pad _image to dimensions {_newWidth, _newHeight} with pad color {0, 0, 0} -- black
        
        save _image in _fileName
        
        close _image
        
      on error a number b
        try
          close _image
        end try
        log a
      end try
      
    end repeat
  end tell
  
  delay 2
  
  tell application "Finder"
    with timeout of 600 seconds
      set selection to _selection
    end timeout
  end tell
on error a number b
  log "Error: " & a
end try


[crarko adds: I tested this, and it works as described. The easiest way to use this is to put the script in your Scripts menu. I put it in ~/Library/Scripts/Applications/Finder. Then select the images in the Finder and run the script. The script is also mirrored here.]

Comments (6)


Mac OS X Hints
http://hints.macworld.com/article.php?story=20101023175641568