wallpapper
:computer: Console application for creating dynamic wallpapers for macOS Mojave and newer
Top Related Projects
Apple TV Aerial Screensaver for Mac
The modern video player for macOS.
💦 Make any website your Mac desktop wallpaper
Intelligent adaptive brightness for your external monitors
Retroactive has been discontinued. You should transition from Retroactive to supported apps such as Music, iTunes for Windows, iMazing, Photos, Darktable, Lightroom Classic, and DaVinci Resolve.
🌇 🌃 Create dynamic wallpapers for macOS.
Quick Overview
Wallpapper is a command-line tool written in Swift that generates dynamic wallpapers for macOS Mojave and later. It allows users to create wallpapers that change based on the time of day or the system's light/dark mode settings, using a set of images and a JSON configuration file.
Pros
- Easy to use command-line interface for creating dynamic wallpapers
- Supports both time-based and appearance-based (light/dark mode) wallpapers
- Cross-platform compatibility (macOS, Linux, Windows)
- Generates wallpapers compatible with macOS Mojave and later
Cons
- Limited to creating wallpapers for macOS, despite being cross-platform
- Requires manual creation of JSON configuration files
- No graphical user interface for less technical users
- Limited customization options compared to more advanced wallpaper creation tools
Getting Started
- Install Wallpapper using Homebrew:
brew install mczachurski/wallpapper/wallpapper
- Create a JSON configuration file (e.g.,
config.json
) with your wallpaper settings:
{
"images": [
{
"fileName": "day.jpg",
"isPrimary": true
},
{
"fileName": "night.jpg",
"isPrimary": false
}
],
"type": "appearance"
}
- Run Wallpapper to generate the dynamic wallpaper:
wallpapper -i config.json -o output.heic
- Set the generated
output.heic
file as your wallpaper in macOS System Preferences.
Competitor Comparisons
Apple TV Aerial Screensaver for Mac
Pros of Aerial
- Offers a more comprehensive screensaver experience with dynamic video content
- Includes a wider range of customization options and settings
- Supports multiple displays and various video playback modes
Cons of Aerial
- Larger file size and resource usage due to video content
- Requires more frequent updates to maintain video sources and compatibility
- May have a steeper learning curve for users due to more complex features
Code Comparison
Wallpapper (Swift):
let image = NSImage(contentsOf: URL(fileURLWithPath: imagePath))
let properties = CGImageProperties(kCGImagePropertyOrientation: orientation)
let destination = CGImageDestination(url: outputFileUrl as CFURL, type: kUTTypeJPEG, imageCount: 1, options: nil)
Aerial (Objective-C):
NSImage *image = [[NSImage alloc] initWithContentsOfFile:imagePath];
NSDictionary *properties = @{(NSString *)kCGImagePropertyOrientation: @(orientation)};
CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)outputFileURL, kUTTypeJPEG, 1, NULL);
Both projects use similar approaches for image handling, but Aerial's codebase is more extensive due to its broader feature set.
The modern video player for macOS.
Pros of IINA
- More comprehensive media player with broader functionality
- Active development with frequent updates and bug fixes
- Larger community and user base for support and contributions
Cons of IINA
- Larger project scope, potentially more complex for new contributors
- Higher resource usage due to its full-featured nature
- Not specifically focused on wallpaper management
Code Comparison
IINA (Swift):
class PlayerCore: NSObject {
static let playerCoreKey = Notification.Name("IINAPlayerCore")
var mpv: MPVController!
var info: PlaybackInfo!
}
Wallpapper (Swift):
struct Wallpapper {
static func generate(inputPath: String, outputPath: String, options: Options) throws {
let image = try WallpaperGenerator.generate(inputPath: inputPath, options: options)
try image.write(to: URL(fileURLWithPath: outputPath))
}
}
Summary
IINA is a full-featured media player for macOS, while Wallpapper is a tool for generating dynamic wallpapers. IINA offers a more comprehensive solution for media playback but may be overkill for users solely interested in wallpaper management. Wallpapper, on the other hand, is more focused and lightweight, specifically designed for creating dynamic wallpapers. The choice between the two depends on the user's specific needs and preferences.
💦 Make any website your Mac desktop wallpaper
Pros of Plash
- User-friendly GUI application for macOS, making it easier for non-technical users
- Supports live websites as wallpapers, offering dynamic and interactive backgrounds
- Includes features like auto-refresh and custom JavaScript injection for enhanced functionality
Cons of Plash
- Limited to macOS platform, reducing its accessibility for users on other operating systems
- Focuses primarily on web-based wallpapers, which may not suit users looking for static image options
- Requires the application to be running continuously for the wallpaper to remain active
Code Comparison
While a direct code comparison is not particularly relevant due to the different nature of these projects, we can highlight some key differences in their implementation:
Wallpapper (Swift):
let image = NSImage(contentsOf: URL(fileURLWithPath: imagePath))
let cgImage = image?.cgImage(forProposedRect: nil, context: nil, hints: nil)
let bitmapRep = NSBitmapImageRep(cgImage: cgImage!)
Plash (JavaScript/Electron):
const { BrowserWindow } = require('electron');
const win = new BrowserWindow({ fullscreen: true, frame: false });
win.loadURL(url);
win.setAlwaysOnTop(true, 'screen-saver');
These snippets illustrate the different approaches: Wallpapper manipulates image data directly, while Plash creates a fullscreen browser window to display web content as a wallpaper.
Intelligent adaptive brightness for your external monitors
Pros of Lunar
- Offers advanced display management features beyond wallpaper settings
- Provides a user-friendly GUI for easier configuration
- Supports a wider range of display adjustments, including brightness and contrast
Cons of Lunar
- More complex setup and installation process
- Larger codebase and resource footprint
- May include features unnecessary for users only interested in wallpaper management
Code Comparison
Wallpapper (Swift):
let image = NSImage(contentsOfFile: imagePath)
let imageData = image?.tiffRepresentation
let bitmap = NSBitmapImageRep(data: imageData!)
let jpegData = bitmap?.representation(using: .jpeg, properties: [:])
Lunar (Swift):
func setBrightness(_ brightness: Double, for screen: Screen) {
guard let display = screen.id else { return }
DDC.setBrightness(Int(brightness), for: display)
screen.brightness = brightness
}
While both projects are written in Swift, they serve different purposes. Wallpapper focuses on wallpaper generation and manipulation, whereas Lunar provides broader display management functionality. The code snippets reflect these differences, with Wallpapper handling image processing and Lunar managing display brightness settings.
Retroactive has been discontinued. You should transition from Retroactive to supported apps such as Music, iTunes for Windows, iMazing, Photos, Darktable, Lightroom Classic, and DaVinci Resolve.
Pros of Retroactive
- Broader functionality: Allows running legacy versions of various macOS apps, not just wallpaper creation
- User-friendly GUI: Provides a graphical interface for easier interaction
- Actively maintained: More recent updates and ongoing development
Cons of Retroactive
- Larger scope: May be overkill if only wallpaper functionality is needed
- macOS specific: Limited to Apple ecosystem, unlike Wallpapper's cross-platform nature
- More complex: Requires more system resources and setup due to its broader functionality
Code Comparison
While a direct code comparison is not particularly relevant due to the different scopes of these projects, we can highlight a key difference in their approach:
Wallpapper (Go):
func (w *Wallpapper) Generate() error {
// Wallpaper generation logic
}
Retroactive (Swift):
func launchApplication(_ bundleIdentifier: String) {
// Application launching logic
}
Wallpapper focuses on generating wallpapers, while Retroactive manages launching and running legacy applications. This fundamental difference in purpose is reflected in their codebases and overall project structures.
🌇 🌃 Create dynamic wallpapers for macOS.
Pros of Equinox
- User-friendly GUI for creating dynamic wallpapers
- Supports both light and dark mode themes
- Offers a preview feature for created wallpapers
Cons of Equinox
- Limited to macOS platform
- Fewer customization options for image transitions
- Lacks command-line interface for automation
Code Comparison
Wallpapper (Swift):
let solarPosition = SolarPosition(forDate: date, atLatitude: latitude, andLongitude: longitude)
let altitude = solarPosition.altitude
Equinox (Swift):
let solarCalculator = SolarCalculator(latitude: latitude, longitude: longitude)
let solarPosition = solarCalculator.calculate(for: date)
let altitude = solarPosition.altitude
Both projects use similar approaches for calculating solar positions, but Equinox encapsulates the calculation in a separate SolarCalculator
class, potentially offering better modularity.
Wallpapper provides a command-line tool for creating dynamic wallpapers, while Equinox offers a graphical user interface. Wallpapper supports more platforms and has more advanced customization options, but Equinox is more user-friendly for those who prefer a GUI. The choice between the two depends on the user's needs and preferences for creating dynamic wallpapers.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
ð» wallpapper / wallpapper-exif
This is simple console application for macOS to create dynamic wallpapers introduced in macOS Mojave. Here you can watch how dynamic wallpapers works. Also you can read more about dynamic wallpapers in following articles:
- macOS Mojave dynamic wallpaper
- macOS Mojave dynamic wallpapers (II)
- macOS Mojave dynamic wallpapers (III)
Examples
Below you can download prepared dynamic wallpapers:
Build and install
You need to have latest XCode (10.2) and Swift 5 installed.
Homebrew
Open your terminal and run following commands.
brew tap mczachurski/wallpapper
brew install wallpapper
Manually
Open your terminal and run following commands.
$ git clone https://github.com/mczachurski/wallpapper.git
$ cd wallpapper
$ swift build --configuration release
$ sudo cp .build/release/wallpapper /usr/local/bin
$ sudo cp .build/release/wallpapper-exif /usr/local/bin
If you are using swift in version 4.1, please edit Package.swift
file and put there your version of swift (in first line).
Also you can build using build.sh
script (it uses swiftc
instead Swift CLI).
$ git clone https://github.com/mczachurski/wallpapper.git
$ cd wallpapper
$ ./build.sh
$ sudo cp .output/wallpapper /usr/local/bin
$ sudo cp .output/wallpapper-exif /usr/local/bin
Now in the console you can run wallpapper -h
and you should got a response similar to the following one.
wallpapper: [command_option] [-i jsonFile] [-e heicFile]
Command options are:
-h show this message and exit
-v show program version and exit
-o output file name (default is 'output.heic')
-i input .json file with wallpaper description
-e input .heic file to extract metadata
That's all. Now you can build your own dynamic wallpappers.
Troubleshooting
If you get an error during the Swift build portion of install, try downloading the entire Xcode IDE (not just the tools) from the app store. Then run
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
and run the installation command again.
Getting started
If you have done above commands now you can build dynamic wallpaper. It's really easy. First you have to put all you pictures into one folder and in the same folder create json
file with picture's description. Application support three kinds of dynamic wallpapers.
Solar
For wallpaper which based on solar coordinates json
file have to have structure like on below snippet.
[
{
"fileName": "1.png",
"isPrimary": true,
"isForLight": true,
"altitude": 27.95,
"azimuth": 279.66
},
{
"fileName": "2.png",
"altitude": -31.05,
"azimuth": 4.16
},
...
{
"fileName": "16.png",
"isForDark": true,
"altitude": -28.63,
"azimuth": 340.41
}
]
Properties:
fileName
- name of picture file name (you can use same file for few nodes).isPrimary
- information about image which is primary image (it will be visible after creatingheic
file). Only one of the file can be primary.isForLight
- iftrue
picture will be displayed when user chose "Light (static)" wallpaperisForDark
- iftrue
picture will be displayed when user chose "Dark (static)" wallpaperaltitude
- is the angle between the Sun and the observer's local horizon.azimuth
- that is the angle of the Sun around the horizon.
To calculate proper altitude and azimuth you can use wallpapper-exif
application or web page: https://keisan.casio.com/exec/system/1224682277. In web page you have to put place where you take a photo and the date. Then system generate for you altitude and azimuth of the Sun during whole day.
Time
For wallpaper which based on OS time json
file have to have structure like on below snippet.
[
{
"fileName": "1.png",
"isPrimary": true,
"isForLight": true,
"time": "2012-04-23T10:25:43Z"
},
{
"fileName": "2.png",
"time": "2012-04-23T14:32:12Z"
},
{
"fileName": "3.png",
"time": "2012-04-23T18:12:01Z"
},
{
"fileName": "4.png",
"isForDark": true,
"time": "2012-04-23T20:10:45Z"
}
]
Properties:
fileName
- name of picture file name (you can use same file for few nodes).isPrimary
- information about image which is primary image (it will be visible after creatingheic
file). Only one of the file can be primary.isForLight
- iftrue
picture will be displayed when user chose "Light (static)" wallpaperisForDark
- iftrue
picture will be displayed when user chose "Dark (static)" wallpapertime
- time when wallpaper will be changed (most important is hour).
Apperance
For wallpapers based on OS apperance settings (light/dark) we have to prepare much simpler JSON file, and we have to use only two images (one for light and one for dark theme).
[
{
"fileName": "1.png",
"isPrimary": true,
"isForLight": true
},
{
"fileName": "2.png",
"isForDark": true
}
]
Properties:
fileName
- name of picture file name.isPrimary
- information about image which is primary image (it will be visible after creatingheic
file). Only one of the file can be primary.isForLight
- iftrue
picture will be displayed when user uses light themeisForDark
- iftrue
picture will be displayed when user uses dark theme
Preparing wallpapers
When you have json
file and all pictures then you can generate heic
file. You have to run following command:
wallpapper -i wallpapper.json
You should got a new file: output.heic
. Set this file as a new wallpaper and enjoy you own dynamic wallpaper!
Extracting metadata
You can extract metadata from existing heic
file. You have to run following command:
wallpapper -e Catalina.heic
Metadata should be printed as output on the console.
Also it's possible to extract and save whole plist
file:
wallpapper -e Catalina.heic -o output.plist
Calculating sun position
If your photos contains GPS Exif metadata and creation time you can use wallpapper-exif
application to generate json
file with Sun altitude
and azimuth
. Example application usage:
$ wallpapper-exif 1.jpeg 2.jpeg 3.jpeg
json
should be produced as output on the console.
Sun calculations has been created based on the JavaScript library created by Vladimir Agafonkin (@mourner).
Top Related Projects
Apple TV Aerial Screensaver for Mac
The modern video player for macOS.
💦 Make any website your Mac desktop wallpaper
Intelligent adaptive brightness for your external monitors
Retroactive has been discontinued. You should transition from Retroactive to supported apps such as Music, iTunes for Windows, iMazing, Photos, Darktable, Lightroom Classic, and DaVinci Resolve.
🌇 🌃 Create dynamic wallpapers for macOS.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot