2

//背景随意跳过

我正在为我的 Windows 桌面背景创建一个动画时钟。基本上,我使用预先绘制的图像(时钟的数字)创建带有代码的 bmp 图像,然后保存 bmp 图像并将桌面背景设置为该图像。我尝试使用 c# 和 .Net,但为了设置桌面背景,我必须调用 WinApi 函数 (SystemParametersInfo)。从 c# 调用此函数几乎需要一秒钟。动画太长了。

所以现在我想在 c++ 中做同样的事情,我希望从非托管代码调用 SystemParametersInfo 会更快。编辑:我用c#创建bmp和c++来设置桌面背景,速度更快

//问题

我使用 Visual Studio 2012 创建了一个 Win32 控制台项目,并设法将预先绘制的图像作为资源嵌入。现在我需要将图像组合到一个位图上并将其保存到硬盘中。自从我上次用 C++ 编程已经四年了,所以我不知道如何绘制图像并保存它。

我在谷歌搜索时发现的所有代码都必须在屏幕上进行绘制,我显然不想这样做。

那么如何创建位图,在其上绘制资源图像(也是位图),并将其全部保存在 C++ 中?

感谢您的任何帮助。

4

2 回答 2

0

这个问题更多的是关于 Windows API 而不是 C++。如果要使用 Windows API,请参考 GDI+:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms533798.aspx

.NET Framework 包装了 GDI+,因此您可能只在 C++ 中熟悉类,而不是在具有手动内存管理等的 C# 中。

还有一些其他库可以处理图像。我个人喜欢 GD,一个具有多种语言绑定的 C 风格图像处理库。

https://bitbucket.org/libgd/gd-libgd/downloads

但是,与开源一样,您必须自己构建它以及依赖项。所以,可能 GDI+ 是最好的。

于 2013-08-17T08:24:19.643 回答
0

事实证明,Win32 (c++) 代码可以快速更改桌面背景(在 i5 3.2ghz 上不到 20 毫秒),而托管 C# 代码需要 500 到 3000 毫秒。但是,非托管 c++ 代码需要永远绘制图像(300 到 1500 毫秒)。所以我所做的就是制作两个可以协同工作的程序。托管 C# 程序创建图像(在 20 毫秒内)然后保存。非托管 c++ 将保存的图像设置为桌面背景。

C# static void Main(string[] args) { //手动计算和硬编码的图像位置 //第一个图像位置 //X:532 //Y:335 位图 TheImage = new Bitmap(1366, 768);

        Graphics G = Graphics.FromImage(TheImage);

        DateTime DTNow = DateTime.Now;
        while (true)
        {
            //get the time 
            DTNow = DateTime.Now;
            //draw the canvas
            G.DrawImage(Resources.canvas, 0, 0,1366,768);

            //draw the first image of the hour
            G.DrawImage(GetImage(DTNow.Hour,0),532,330,174,217);
            //draw the second image of the hour
            G.DrawImage(GetImage(DTNow.Hour, 1), 711, 330, 174, 217);
            //draw the colon
            if (DTNow.Second % 2 == 0) G.DrawImage(Resources.aColon, 890, 365,57,147);
            //draw the first digit of the minute
            G.DrawImage(GetImage(DTNow.Minute, 0), 952, 330, 174, 217);
            //draw the second digit of the minute
            G.DrawImage(GetImage(DTNow.Minute, 1), 1131, 330, 174, 217);
            //save the file
            try
            {
                File.Delete("C:\\background.bmp");

                TheImage.Save("C:\\background.bmp", ImageFormat.Bmp);
            }
            catch
            {
            }
            //calculate sleep time and sleep until next second

            DTNow = DateTime.Now.AddSeconds(1);
            DateTime NextSecond = new DateTime(DTNow.Year,DTNow.Month,DTNow.Day, DTNow.Hour,DTNow.Minute, DTNow.Second,500);
            DTNow = DateTime.Now;
      System.Threading.Thread.Sleep((int)NextSecond.Subtract(DTNow).TotalMilliseconds);

        }

    }
    static Bitmap GetImage(int Number, int Index)
    {
        string NS = Number.ToString();
        if (NS.Length < 2) NS = "0" + NS;
        char[] digits = NS.ToCharArray();

        switch (digits[Index])
        {
            case '1': { return Resources.a1; } 
            case '2': { return Resources.a2; }
            case '3': { return Resources.a3; } 
            case '4': { return Resources.a4; } 
            case '5': { return Resources.a5; } 
            case '6': { return Resources.a6;} 
            case '7': { return Resources.a7;} 
            case '8': { return Resources.a8;} 
            case '9': { return Resources.a9; } 
            default: { return Resources.a0; } 
        }
    }
}

c++ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char*, int nShowCmd) { while(true){ SystemParametersInfo(SPI_SETDESKWALLPAPER,0, L"C:\background.bmp", SPIF_UPDATEINIFILE); int MS = (int)(((long)floor((long)clock()/(long)CLOCKS_PER_SEC)*1000l+1000l)-((long)clock()));

if(MS<=1000 && MS>0){
std::this_thread::sleep_for(std::chrono::milliseconds(MS));
}
else
{

}

}
return 0;

}

于 2013-08-28T11:23:55.807 回答