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

时间:2013-08-17 08:00:53

标签: c++ winapi bitmap save draw

//背景可随意跳过

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

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

//问题

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

我在google搜索时发现的代码必须在屏幕上绘画,我显然不想这样做。

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

感谢您的帮助。

2 个答案:

答案 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;

}