코드를 사용하여 데스크톱의 벽지를 변경합니다.그물
C# 코드를 사용하여 데스크톱 배경화면을 변경하는 방법
여기 내가 1~2년 전에 만든 앱에서 가져온 수업이 있다.
public sealed class Wallpaper
{
Wallpaper() { }
const int SPI_SETDESKWALLPAPER = 20;
const int SPIF_UPDATEINIFILE = 0x01;
const int SPIF_SENDWININICHANGE = 0x02;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);
public enum Style : int
{
Tiled,
Centered,
Stretched
}
public static void Set(Uri uri, Style style)
{
System.IO.Stream s = new System.Net.WebClient().OpenRead(uri.ToString());
System.Drawing.Image img = System.Drawing.Image.FromStream(s);
string tempPath = Path.Combine(Path.GetTempPath(), "wallpaper.bmp");
img.Save(tempPath, System.Drawing.Imaging.ImageFormat.Bmp);
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop", true);
if (style == Style.Stretched)
{
key.SetValue(@"WallpaperStyle", 2.ToString());
key.SetValue(@"TileWallpaper", 0.ToString());
}
if (style == Style.Centered)
{
key.SetValue(@"WallpaperStyle", 1.ToString());
key.SetValue(@"TileWallpaper", 0.ToString());
}
if (style == Style.Tiled)
{
key.SetValue(@"WallpaperStyle", 1.ToString());
key.SetValue(@"TileWallpaper", 1.ToString());
}
SystemParametersInfo(SPI_SETDESKWALLPAPER,
0,
tempPath,
SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
}
}
광범위한 테스트는 하지 않았으니 본인 부담으로 사용하세요.
이 편리한 답변을 바탕으로 화면 해상도에 맞는 벽지를 설정할 수 있는 앱도 만들었습니다.
그러나 레지스트리 설정이 잘못되었다.다음은 올바른 값입니다(Windows 7, Windows 8.1, Windows 10에서 테스트됨).
if (style == Style.Fill)
{
key.SetValue(@"WallpaperStyle", 10.ToString());
key.SetValue(@"TileWallpaper", 0.ToString());
}
if (style == Style.Fit)
{
key.SetValue(@"WallpaperStyle", 6.ToString());
key.SetValue(@"TileWallpaper", 0.ToString());
}
if (style == Style.Span) // Windows 8 or newer only!
{
key.SetValue(@"WallpaperStyle", 22.ToString());
key.SetValue(@"TileWallpaper", 0.ToString());
}
if (style == Style.Stretch)
{
key.SetValue(@"WallpaperStyle", 2.ToString());
key.SetValue(@"TileWallpaper", 0.ToString());
}
if (style == Style.Tile)
{
key.SetValue(@"WallpaperStyle", 0.ToString());
key.SetValue(@"TileWallpaper", 1.ToString());
}
if (style == Style.Center)
{
key.SetValue(@"WallpaperStyle", 0.ToString());
key.SetValue(@"TileWallpaper", 0.ToString());
}
Windows 의 설정 이력을 오염시키지 않고 데스크탑의 벽지를 일시적으로 설정하는 경우는, 다음과 같이 정리합니다.
임시 배경화면을 설정하기 전에 배경화면 이력(레지스트리에 저장)을 백업하고 나중에 복원할 수 있습니다.
https://gist.github.com/Drarig29/4aa001074826f7da69b5bb73a83ccd39
c#에서 UWP를 사용하고 있는 경우는, 이하에 나타내는 코드를 참조해 주세요.
using Windows.System.UserProfile;
// Pass in a relative path to a file inside the local appdata folder
async Task<bool> SetWallpaperAsync(string localAppDataFileName)
{
bool success = false;
if (UserProfilePersonalizationSettings.IsSupported())
{
var uri = new Uri("ms-appx:///Local/" + localAppDataFileName);
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(uri);
UserProfilePersonalizationSettings profileSettings = UserProfilePersonalizationSettings.Current;
success = await profileSettings.TrySetWallpaperImageAsync(file);
}
}
사실 난 그게 더 간단한 파일이라고 생각해. png는 너의 사진이야. .jpg일 수도 있고 다른 것일 수도 있어.
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync("file.png", CreationCollisionOption.ReplaceExisting);
bool success = false;
UserProfilePersonalizationSettings profileSettings = UserProfilePersonalizationSettings.Current;
success = await profileSettings.TrySetWallpaperImageAsync(file);
Gifs에 대한 Neal N의 답변 조정:
private const int SPI_SETDESKWALLPAPER = 20;
private const int SPIF_UPDATEINIFILE = 0x01;
private const int SPIF_SENDWININICHANGE = 0x02;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);
public enum Style : int
{
Tiled,
Centered,
Stretched
}
/// <summary>
/// Loops numFrames times, animating the desktop background as the given gif.
/// Remember this will sorta bog down your computer, and probably isn't best to be running 24/7.
/// If numFrames is negative this will loop forever
/// </summary>
/// <param name="gifPath">The gif to be animated</param>
/// <param name="transparencyReplace">If the gif has transparency, it will be "replaced" with this color.</param>
/// <param name="framesPerSecond">How many frames to play per second. This is a max: most likely it will be a little slower than this especially at first.</param>
/// <param name="style">Whether to tile, center, or stretch each gif frame as it's played.</param>
/// <param name="numFrames">The number of frames to play. If negative, this method will loop forever.</param>
public static void SetDesktopBackgroundAsGifAsync(string gifPath, System.Drawing.Color transparencyReplace, int framesPerSecond, Style style, int numFrames)
{
Thread workerThread = new Thread(() => SetDesktopBackgroundAsGif(gifPath, transparencyReplace, framesPerSecond, style, numFrames));
workerThread.Start();
}
/// <summary>
/// Loops numFrames times, animating the desktop background as the given gif.
/// Remember this will sorta bog down your computer, and probably isn't best to be running 24/7.
/// If num frames is negative this will loop forever.
//// <summary>
/// <param name="gifPath">The gif to be animated</param>
/// <param name="backgroundImage">Image to render the gif on top of (because of transparency)</param>
/// <param name="framesPerSecond">How many frames to play per second. This is a max: most likely it will be a little slower than this.</param>
/// <param name="style">Whether to tile, center, or stretch each gif frame as it's played.</param>
/// <param name="numFrames">The number of frames to play. If negative, this method will loop forever.</param>
public static void SetDesktopBackgroundAsGifAsync(string gifPath, System.Drawing.Image backgroundImage, int framesPerSecond, Style style, int numFrames)
{
Thread workerThread = new Thread(() => SetDesktopBackgroundAsGif(gifPath, backgroundImage, framesPerSecond, style, numFrames));
workerThread.Start();
}
/// <summary>
/// Loops numFrames times, animating the desktop background as the given gif.
/// Remember this will sorta bog down your computer, and probably isn't best to be running 24/7.
/// if numFrames is negative this will loop forever
/// </summary>
/// <param name="gifPath">The gif to be animated</param>
/// <param name="transparencyReplace">If the gif has transparency, it will be "replaced" with this color.</param>
/// <param name="framesPerSecond">How many frames to play per second. This is a max: most likely it will be a little slower than this.</param>
/// <param name="style">Whether to tile, center, or stretch each gif frame as it's played.</param>
/// <param name="numFrames">The number of frames to play. If negative, this method will loop forever.</param>
public static void SetDesktopBackgroundAsGif(string gifPath, System.Drawing.Color transparencyReplace, int framesPerSecond, Style style, int numFrames)
{
if (!File.Exists(gifPath))
throw new Exception("Given gif: '" + gifPath + "' not found");
FileStream gifFile = new FileStream(gifPath, FileMode.Open);
GifBitmapDecoder gifDecoder = new GifBitmapDecoder(gifFile, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
if (gifDecoder.Frames.Count == 0)
throw new Exception("No frames in given gif");
Bitmap backgroundImage = new Bitmap(gifDecoder.Frames[0].PixelWidth, gifDecoder.Frames[0].PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using(Graphics g = Graphics.FromImage(backgroundImage))
{
g.FillRectangle(new System.Drawing.SolidBrush(transparencyReplace), 0, 0, gifDecoder.Frames[0].PixelWidth, gifDecoder.Frames[0].PixelHeight);
}
gifFile.Close();
SetDesktopBackgroundAsGif(gifPath, backgroundImage, framesPerSecond, style, numFrames);
}
/// <summary>
/// Loops infinitely, animating the desktop background as the given gif.
/// Remember this will sorta bog down your computer, and probably isn't best to be running 24/7.
/// </summary>
/// <param name="gifPath">The gif to be animated</param>
/// <param name="backgroundImage">Image to render the gif on top of (because of transparency)</param>
/// <param name="framesPerSecond">How many frames to play per second. This is a max: most likely it will be a little slower than this.</param>
/// <param name="style">Whether to tile, center, or stretch each gif frame as it's played.</param>
/// <param name="numFrames">The number of frames to play. If negative, this method will loop forever.</param>
private static void SetDesktopBackgroundAsGif(string gifPath, System.Drawing.Image backgroundImage, int framesPerSecond, Style style, int numFrames)
{
if (!File.Exists(gifPath))
throw new Exception("Given gif: '" + gifPath + "' not found");
FileStream gifFile = new FileStream(gifPath, FileMode.Open);
GifBitmapDecoder gifDecoder = new GifBitmapDecoder(gifFile, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
if (gifDecoder.Frames.Count == 0)
throw new Exception("No frames in given gif");
Console.WriteLine("Saving frames to temporary files:");
int numFramesSoFar = 0;
for (int i = 0; i < gifDecoder.Frames.Count; i++)
{
BitmapFrame gifFrame = gifDecoder.Frames[i];
PngBitmapEncoder pngEncoder = new PngBitmapEncoder();
pngEncoder.Frames.Add(gifFrame);
MemoryStream pngStream = new MemoryStream();
pngEncoder.Save(pngStream);
Image frameImage = Image.FromStream(pngStream);
Bitmap bmp = new Bitmap(frameImage.Width, frameImage.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawImage(backgroundImage, 0, 0);
g.DrawImageUnscaled(frameImage, 0, 0);
}
string tempPath = Path.Combine(Path.GetTempPath(), gifPath + i + ".bmp");
bmp.Save(tempPath, System.Drawing.Imaging.ImageFormat.Bmp);
Console.WriteLine("Saved frame " + i);
numFramesSoFar++;
if (numFrames >= 0 && numFramesSoFar >= numFrames) break;
}
Console.WriteLine("Setting frames to desktop background at about " + framesPerSecond + " FPS");
// 1.0/... to convert to seconds per frame (instead of frames per second)
// * 1000 to convert to milliseconds per frame
// * 1000 to convert to microseconds per frame
// * 10 to convert to 0.1s of microseconds per frame = 100s of nanoseconds per frame
long ticksBetweenFrames = (long)Math.Round(1.0 / framesPerSecond) * 1000*1000*10;
Stopwatch timer = new Stopwatch();
timer.Start();
numFramesSoFar = 0;
while(numFrames < 0 || numFramesSoFar < numFrames)
{
for (int i = 0; i < gifDecoder.Frames.Count; i++)
{
// Sleep until we're at the desired frame rate, if needed.
if(ticksBetweenFrames > timer.ElapsedTicks)
Thread.Sleep(new TimeSpan(Math.Max(0, ticksBetweenFrames - timer.ElapsedTicks)));
timer.Restart();
// From http://stackoverflow.com/a/1061682/2924421
string filePath = Path.Combine(Path.GetTempPath(), "wallpaper" + i + ".bmp");
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop", true);
if (style == Style.Stretched)
{
key.SetValue(@"WallpaperStyle", 2.ToString());
key.SetValue(@"TileWallpaper", 0.ToString());
}
if (style == Style.Centered)
{
key.SetValue(@"WallpaperStyle", 1.ToString());
key.SetValue(@"TileWallpaper", 0.ToString());
}
if (style == Style.Tiled)
{
key.SetValue(@"WallpaperStyle", 1.ToString());
key.SetValue(@"TileWallpaper", 1.ToString());
}
SystemParametersInfo(SPI_SETDESKWALLPAPER,
0,
filePath,
SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
numFramesSoFar++;
if (numFrames >= 0 && numFramesSoFar >= numFrames) break;
}
}
gifFile.Close();
}
또한 다음을 사용해야 합니다.
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Media.Imaging;
마지막으로 [프로젝트], [참조 추가]를 오른쪽 클릭하여 (어셈블리와 프레임워크에서) 프레젠테이션의 핵심, 시스템을 추가합니다.Xaml 및 WindowsBase.
그런 다음 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 Properties로 이동하여 Target Framework가 인 것을 확인합니다.넷 프레임워크 4.5이 설정을 변경하면 Visual Studio를 다시 시작해야 할 수 있습니다.
언급URL : https://stackoverflow.com/questions/1061678/change-desktop-wallpaper-using-code-in-net
'programing' 카테고리의 다른 글
공백으로 구분된 문자열을 Bash에서 배열로 읽기 (0) | 2023.04.12 |
---|---|
개체 목록에 특정 속성 값을 가진 개체가 포함되어 있는지 확인합니다. (0) | 2023.04.12 |
정수 배열을 쉼표로 구분된 문자열로 변환 (0) | 2023.04.12 |
Swift 클래스 오류: super.init 호출 시 속성이 초기화되지 않았습니다. (0) | 2023.04.12 |
HRESULT로부터의 예외: 0x80070057 (E_INVALIDARG) (0) | 2023.04.12 |