使用.NET中的代码更改桌面壁纸

发布于 2024-07-26 15:05:57 字数 24 浏览 10 评论 0原文

如何使用 C# 代码更改桌面壁纸?

How can I change the desktop wallpaper using C# Code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

韵柒 2024-08-02 15:05:57

这是从我一两年前编写的应用程序中提取的一个类:

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);
    }
}

我没有对其进行广泛的测试,因此使用时请自行承担风险。

Here's a class yanked from an app I wrote a year or two ago:

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);
    }
}

I haven't tested it extensively, so use at your own risk.

末骤雨初歇 2024-08-02 15:05:57

基于这个有用的答案,我还做了我自己的应用,用于设置与屏幕分辨率匹配的壁纸。

但注册表设置错误。 以下是正确的值(在 Win 7、Win 8.1、Win 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());
}

Bases on this useful answer, I've also made my own app to set wallpaper matching screen resolution.

But the registry settings were wrong. Here are the correct values (tested on Win 7, Win 8.1, Win 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());
}
左岸枫 2024-08-02 15:05:57

如果您想临时设置桌面壁纸而不污染 Windows 设置历史记录,这里是我提出的要点。

它会在设置之前备份壁纸历史记录(存储在注册表中)临时壁纸,之后您可以将其恢复。

https://gist.github.com/Drarig29/4aa001074826f7da69b5bb73a83ccd39

If you want to temporarily set a desktop wallpaper without polluting the Windows settings history, here is a gist I made.

It backups the wallpaper history (stored in the registry) before setting the temporary wallpaper and you can restore it back afterwards.

https://gist.github.com/Drarig29/4aa001074826f7da69b5bb73a83ccd39

ζ澈沫 2024-08-02 15:05:57

如果您在 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);
   }
}

其实我觉得还可以更简单
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);

If you're using UWP in c# , here's the code I found here

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);
   }
}

Actually I think it can be more simple
file.png is your photo ,it can be .jpg or something else

StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync("file.png", CreationCollisionOption.ReplaceExisting);
bool success = false;
UserProfilePersonalizationSettings profileSettings = UserProfilePersonalizationSettings.Current;
success = await profileSettings.TrySetWallpaperImageAsync(file);
红衣飘飘貌似仙 2024-08-02 15:05:57

调整 Neal N 对 Gif 的回答:

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;

最后,右键单击您的项目,添加引用,然后(在程序集和框架中)添加Presentation Core、System.Xaml 和 WindowsBase。

然后右键单击您的项目并进入“属性”,并确保目标框架是.Net Framework 4.5。 如果更改此设置,您可能需要重新启动 Visual Studio。

Tweaking Neal N's answer for Gifs:

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();
}

Also note that you need to use:

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;

Finally, right click on your Project, Add Reference, and (in Assemblies and Framework) add Presentation Core, System.Xaml, and WindowsBase.

Then right click on your Project and go into Properties, and make sure Target Framework is .Net Framework 4.5. If you change this you may need to restart Visual Studio.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文