当前位置:编程学习 > VC++ >>

控制台应用程序下使用GDI在内存中画图

控制台应用程序下使用GDI在内存中画图

1      背景
以前写MFC应用程序的时候,就接触到GDI了。只不过那个时候,Visual Studio已经帮你生成了MFC应用的基本框架,在Visual Studio生成的View文件里,存在一个方法::OnDraw(CDC* /*pDC*/),Visual Studio会添加注释“// TODO: 在此处为本机数据添加绘制代码”,即是说,请在此处调用CDC进行绘制操作。CDC的创建和初始化MFC都帮你完成了,你只需要添加一些个性化代码即可,当然,这对于一个MFC应用来说,当然够了,但是如果你想写一个不使用MFC的应用,我该怎么获得CDC呢?

很多时候,我们并不需要将绘制的图像显示在窗口,只需要将图像绘制在内存中,然后将内存中的图像保存成图片文件。说到内存绘制,也许有人会说,我直接创建一块内存像素数据,然后计算每个图形的像素结构,填充内存像素数据不就可以了么,没有必要使用GDI呀,对于大部分几何图像来说,这么做完全没问题,但是如果你想绘制字符的时候,这么做就很困难了,因为你很难去计算一个字符的像素结构,所以当你需要绘制字符的时候,你还是得使用GDI。

接下来,我将介绍:(1)如何在控制台应用程序下使用GDI在内存中画图;(2)将内存中的图像存储为图片。

2      使用GDI在内存中画图
GDI是Windows API,因此只要是Win32程序(包括Win32应用程序和Win32控制台程序),都可以使用GDI。为了简单起见,如果你想运行本文介绍的代码,新建一个空的Win32控制台程序即可。我觉得在代码中加注释比在这描述更加明了,那么让我们看看代码吧:


[cpp]
#include <Windows.h>  
#include <tchar.h>  
#include <stdio.h>  
 
/**
 * 将HBITMAP保存为BMP图片,实现细节见第三节
 */ 
static void hbitmapToImage(HDC hdc, HBITMAP hbm); 
 
int main(int argc, char *argv[]) 

    // 创建绘制环境  
    HDC memDC = CreateCompatibleDC(NULL); 
    // 创建画布  
    HBITMAP hbm = CreateBitmap(100, 100, 1, 32, NULL); 
    // 创建一个字体,其中40是字体大小,参数可以根据自己需求调整  
    HFONT hfont = CreateFont(40, 0, 0, 0, FW_THIN, false, false, false,  
        DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,  
        DEFAULT_QUALITY, FF_MODERN, _T("宋体")); 
    // 选择画布和字体,你可以保存之前的画布和字体用于恢复,为了篇幅起见,在此就不这样做了  
    SelectObject(memDC, hbm); 
    SelectObject(memDC, hfont); 
    // 开始绘制操作  
    RECT imgRect = {0, 0, 100, 100};// 设置为画布的宽高  
    SIZE fontPixSize;               // 字符的像素大小,对于一种字体来说,其字符的高是一致的,但是宽基本不同  
    // 将背景填充为黑色  
    FillRect(memDC, &imgRect, (HBRUSH)GetStockObject(BLACK_BRUSH)); 
    // 得到字符串的像素宽高,可以为任意字符串  
    GetTextExtentPoint32(memDC, _T("我"), 1, &fontPixSize); 
    SetTextColor(memDC, RGB(255, 255, 255));    // 设置文本颜色  
    SetBkMode(memDC, TRANSPARENT);              // 设置背景模式  
    // 计算绘制起始位置,使字符在画布的中间;当然你也可以添加更多的绘制操作,如PolyDraw,LineTo等  
    TextOut(memDC, (100 - fontPixSize.cx) / 2, (100 - fontPixSize.cy) / 2, _T("我"), 1); 
    // 将HBITMAP保存为BMP图片  
    hbitmapToImage(memDC, hbm); 
    // 释放资源  
    DeleteObject((HGDIOBJ)hfont); 
    DeleteObject((HGDIOBJ)hbm); 
    DeleteDC(memDC); 
    return 0; 

#include <Windows.h>
#include <tchar.h>
#include <stdio.h>

/**
 * 将HBITMAP保存为BMP图片,实现细节见第三节
 */
static void hbitmapToImage(HDC hdc, HBITMAP hbm);

int main(int argc, char *argv[])
{
 // 创建绘制环境
 HDC memDC = CreateCompatibleDC(NULL);
 // 创建画布
 HBITMAP hbm = CreateBitmap(100, 100, 1, 32, NULL);
 // 创建一个字体,其中40是字体大小,参数可以根据自己需求调整
 HFONT hfont = CreateFont(40, 0, 0, 0, FW_THIN, false, false, false,
  DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,
  DEFAULT_QUALITY, FF_MODERN, _T("宋体"));
 // 选择画布和字体,你可以保存之前的画布和字体用于恢复,为了篇幅起见,在此就不这样做了
 SelectObject(memDC, hbm);
 SelectObject(memDC, hfont);
 // 开始绘制操作
 RECT imgRect = {0, 0, 100, 100};// 设置为画布的宽高
 SIZE fontPixSize;    // 字符的像素大小,对于一种字体来说,其字符的高是一致的,但是宽基本不同
 // 将背景填充为黑色
 FillRect(memDC, &imgRect, (HBRUSH)GetStockObject(BLACK_BRUSH));
 // 得到字符串的像素宽高,可以为任意字符串
 GetTextExtentPoint32(memDC, _T("我"), 1, &fontPixSize);
 SetTextColor(memDC, RGB(255, 255, 255)); // 设置文本颜色
 SetBkMode(memDC, TRANSPARENT);    // 设置背景模式
 // 计算绘制起始位置,使字符在画布的中间;当然你也可以添加更多的绘制操作,如PolyDraw,LineTo等
 TextOut(memDC, (100 - fontPixSize.cx) / 2, (100 - fontPixSize.cy) / 2, _T("我"), 1);
 // 将HBITMAP保存为BMP图片
 hbitmapToImage(memDC, hbm);
 // 释放资源
 DeleteObject((HGDIOBJ)hfont);
 DeleteObject((HGDIOBJ)hbm);
 DeleteDC(memDC);
 return 0;
}
3      将HBITMAP保存为BMP图片
第2节描述了如何使用GDI在内存中画图,本节介绍如何将HBITMAP保存为BMP图片。代码如下:


[cpp]
/**
 * 将HBITMAP保存为BMP图片
 */ 
void hbitmapToImage(HDC hdc, HBITMAP hbm) 

    // 得到hbm中每个像素所占的位数  
    int bmPixBitCount = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES); 
    int wBitCount = 0; 
    if(bmPixBitCount <=  1)                                                  
        wBitCount = 1;            
    else if(bmPixBitCount <=  4)                              
        wBitCount = 4;            
    else if(bmPixBitCount <=  8)                              
        wBitCount = 8;   

补充:软件开发 , Vc ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,