c ++在位图上绘制图像并保存
Posted
技术标签:
【中文标题】c ++在位图上绘制图像并保存【英文标题】:c++ draw images on bitmap and save 【发布时间】:2013-08-17 08:00:53 【问题描述】://后台可以跳过
我正在为我的 Windows 桌面背景创建一个动画时钟。基本上,我使用预先绘制的图像(时钟的数字)创建带有代码的 bmp 图像,然后保存 bmp 图像并将桌面背景设置为该图像。我尝试使用 c# 和 .Net,但为了设置桌面背景,我必须调用 WinApi 函数 (SystemParametersInfo)。从 c# 调用此函数几乎需要一秒钟。动画太长了。
所以现在我想在 c++ 中做同样的事情,我希望从非托管代码调用 SystemParametersInfo 会更快。编辑:我用c#创建bmp和c++来设置桌面背景,速度更快
//问题
我使用 Visual Studio 2012 创建了一个 Win32 控制台项目,并设法将预先绘制的图像作为资源嵌入。现在我需要将图像组合到一个位图上并将其保存到硬盘中。自从我上次用 C++ 编程已经四年了,所以我不知道如何绘制图像并保存它。
我在谷歌搜索时发现的所有代码都必须在屏幕上绘制,我显然不想这样做。
那么如何创建位图,在其上绘制资源图像(也是位图),并将其全部保存在 c++ 中?
感谢您的帮助。
【问题讨论】:
【参考方案1】:这个问题更多是关于 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+ 是最好的。
【讨论】:
我正忙于使用 GDI+ 编写我的 C# 程序的 c++ 版本(花了我一段时间才弄清楚)如果它有效,我将发布代码【参考方案2】:事实证明,Win32 (c++) 代码可以快速更改桌面背景(在 i5 3.2ghz 上不到 20 毫秒),而托管 C# 代码需要 500 到 3000 毫秒。但是,非托管 c++ 代码需要永远绘制图像(300 到 1500 毫秒)。所以我所做的就是制作两个可以协同工作的程序。托管 C# 程序创建图像(在 20 毫秒内)然后保存。非托管c++将保存的图片设置为桌面背景。
C# 静态无效主要(字符串 [] 参数) //手动计算和硬编码的图像位置 //第一张图片位置 //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;
【讨论】:
以上是关于c ++在位图上绘制图像并保存的主要内容,如果未能解决你的问题,请参考以下文章