//背景可随意跳过
我正在为我的Windows桌面背景创建一个动画时钟。基本上我使用预先绘制的图像(时钟的数字)创建一个带代码的bmp图像,然后保存bmp图像并将桌面背景设置为该图像。我尝试使用c#和.Net但是为了设置桌面背景,我必须调用WinApi函数(SystemParametersInfo)。从c#调用此函数需要几乎一秒钟。动画太长了。
所以现在我想做同样的事情,除了在c ++中,我希望从非托管代码调用SystemParametersInfo会更快。编辑:我使用c#创建bmp和c ++来设置桌面背景,它更快
//问题
我使用Visual Studio 2012创建了一个Win32控制台项目,并设法将预先绘制的图像作为资源嵌入。现在我需要将图像组合到一个位图上并将其保存到hdd。我上次用c ++编程已经四年了,所以我不知道如何绘制图像并保存它。
我在google搜索时发现的代码必须在屏幕上绘画,我显然不想这样做。
那么如何创建位图,在其上绘制资源图像(也是位图),并将其全部保存在c ++中?
感谢您的帮助。
答案 0 :(得分: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 +可能是最好的。
答案 1 :(得分:0)
事实证明,Win32(c ++)代码可以快速更改桌面背景(i5 3.2ghz下20ms以下),其中托管C#代码需要500到3000毫秒。但是,非托管c ++代码需要永远绘制图像(300到1500毫秒)。所以我所做的就是让两个程序一起工作。托管的C#程序创建图像(20ms以下)然后保存它。非托管c ++将保存的图像设置为桌面背景。
C# static void Main(string [] args) { //手动和硬编码计算的图像位置 //第一张图片positoon // 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) { 而(真){ 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;
}