c++在位图上绘制图像并保存

c++ draw images on bitmap and save

本文关键字:图像 保存 绘制 位图 c++      更新时间:2023-10-16

//后台可以跳过

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

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

//问题

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

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

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

感谢您的帮助。

这个问题更多的是关于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+可能是最好的。

事实证明,Win32(c++)代码可以快速更改桌面背景(在i5 3.2ghz上不到20ms),其中托管c#代码的时间从500到3000ms不等。但是,非托管c++代码绘制图像需要花费很长时间(300到1500毫秒)。所以我做的是制作两个可以一起工作的程序。托管C#程序创建映像(20ms以下)并保存。非托管C++将保存的映像设置为桌面背景。

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

        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){系统参数信息(SPI_SETDESKWALLPAPER,0,L"C:\background.bmp",SPIF_UPDATEINIFILE);int MS=(int)(((长)floor((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;

}