Случайные обои от AI каждый день

Прочитав свежую статью про обои в разных окружениях, начиная с Microsoft Windows 11 и методах их смены, я заинтересовался — нет ли приложения, которое может выставлять не готовые обои из папки или подкачивать из ресурса, а создавать их периодически, используя любой доступный AI сервис.

Гугление ничего не дало. С ходу я не нашел ни одного сервиса, который бы создавал обои от любого AI сервиса на лету. В сущности, это очень простая операция — почему бы не набросать свой скрипт в свободный день?

Я уже писал плагин для Visual Code для проверки правописания и переводов русский-английский, так что OpenAI ключ у меня есть. Будем пробовать DALL-E 3, к которому этот ключ подходит. На Reddit упоминали, что DALL-E умеет создавать бесшовные плиточные изображения, что будет здорово для генерации обоев. Это впоследствии не подтвердилось, как я ни старался. Так что окончательный вариант работает с полным форматом изображения.

Самым простым вариантом мне показалось написать PowerShell скрипт и посадить его на расписание (task scheduler), чтобы он запускался сам каждый день и менял обои.

Отправной точкой является документ, описывающий современный API DALL-E 3.

Вот, собственно, и весь код получения изображения от DALL-E на PowerShell:

$body = @{
    "model"   = "dall-e-3"
    "prompt"  = "$prompt --ar 16:9"
    "size"    = "1792x1024"
    "style"   = "vivid"
} | ConvertTo-Json

$response = Invoke-RestMethod -Uri "https://api.openai.com/v1/images/generations" `
    -Method Post `
    -Headers @{ "Authorization" = "Bearer $apiKey"; "Content-Type" = "application/json" } `
    -Body $body

$imageUrl = $response.data[0].url

В переменную $prompt мы положим наш промпт. О разрешении хотелось бы сказать особо. Максимальное разрешение, поддерживаемое на данный момент DALL-E, есть 1792×1024. Но с ним возникают проблемы — через раз создается квадратное изображение, с полями по бокам. Проблема известная, описана тут. Помогает совет дополнить промпт указанием »--ar 16:9» в конце.

Хорошей идеей является не перезаписывать предыдущее полученное изображение, а создавать новое, со случайным именем. Во-первых, через некоторое время у нас появятся «любимчики», а во-вторых можно будет на разные мониторы назначать разные обои из уже имеющихся.

$chars = "abcdefghijklmnopqrstuvwxyz0123456789"
$randomString = -Join ((1..8) | ForEach-Object { $chars[(Get-Random -Maximum $chars.Length)] })
$outputFile = "$outputDir\dalle_generated_$randomString.jpg"

Ну, и осталось полученное изображение установить на десктоп:

$code = @"
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);
"@
$type = Add-Type -MemberDefinition $code -Name "Wallpaper" -Namespace "Win32" -PassThru
$SPI_SETDESKWALLPAPER = 0x0014
$SPIF_UPDATEINIFILE = 0x01
$SPIF_SENDCHANGE = 0x02
$type::SystemParametersInfo($SPI_SETDESKWALLPAPER, 0, $outputFile, $SPIF_UPDATEINIFILE -bor $SPIF_SENDCHANGE)

Я выбрал простой метод API SystemParametersInfo, но он не позволяет произвольно выставить, на какой монитор из имеющихся поставить обои — он ставит на все одновременно. Более сложный метод, который позволяет работать с произвольными мониторами и менять способы отображения обоев, описан у Pete Hinchley. У него создается полная обертка для COM на .NET. Для моих целей простого метода достаточно, не хочу слишком усложнять код.

Мой промпт — вкусовщина. Люблю обои в буквальном смысле, с текстурой бумаги и низким контрастом, чтобы не отвлекало и не мешало разглядеть иконки.»A full-sized wallpaper with flowers and birds and leaves. Muted dark colors, with the texture of rough paper.»

Вот так выглядит основной экран:

в процессе написания статьи

в процессе написания статьи

Скрипт заработал, генерируя каждый раз новое изображение (это занимает до десяти секунд). Осталось только запускать его каждый день автоматически.

Запускаем скрипт в task scheduler (внимание на командную строку):

настройка ежедневного запуска скрипта

настройка ежедневного запуска скрипта

Вот ссылка на гитхаб с исходником скрипта. Нужен только один файл, .ps1

Что в планах: работать со всеми мониторами независимо, используя обертку Windows API от Pete Hinchley (ссылка выше) и назначать на разные мониторы разные изображения автоматически. Еще надо в свободный день развернуть Stable Diffusion и поиграться с ним из PowerShell. Но я с самого начала не рассчитывал на Stable Diffusion — он требует серьезного GPU и много памяти. Предвижу много возни с настройкой, да и не на каждом десктопе или лаптопе найдется подходящая конфигурация. Но было бы интересно попробовать.

© Habrahabr.ru