VC++中图像处理类CBitmap的用法

VC++中图像处理类CBitmap的用法

简介

CBitmap是MFC框架下的一个图像处理类,可以方便地进行图像的读取、处理和展示。它封装了基本的位图信息和位图文件的操作方法,可以很好地处理bmp、jpg、png等格式的图像。

CBitmap类的常用方法

1. 构造函数

CBitmap提供了多个构造函数,其中最常用的是默认构造函数CBitmap()和参数为位图资源ID的构造函数CBitmap(UINT nIDResource)。

例如:

CBitmap bmp;                            // 创建一个空指针
bmp.LoadBitmap(IDB_BITMAP1);            // 加载位图资源

2. 位图信息的获取

CBitmap提供了GetBitmap()方法用于获取位图信息。

例如:

BITMAP bmpInfo;
bmp.GetBitmap(&bmpInfo);                // 获取位图信息
TRACE("bmp Width:%d, Height:%d", bmpInfo.bmWidth, bmpInfo.bmHeight);

3. 位图文件的加载

CBitmap提供了LoadBitmap()方法用于加载资源中的位图文件,也提供了LoadImage()方法用于加载磁盘上的位图文件。

例如:

CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1);            // 加载位图资源
HBITMAP hBmp = (HBITMAP)LoadImage(NULL, "C:\\test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
bmp.Attach(hBmp);                       // 将位图文件附加到CBitmap对象

4. 位图的绘制

CBitmap提供了很多不同类型的Draw()方法用于在设备环境中绘制位图。

例如:

CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1);            // 加载位图资源

CDC *pDC = GetDC();
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);          // 创建和当前设备环境兼容的设备环境
dcMem.SelectObject(bmp);                // 选择当前的位图
pDC->BitBlt(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, &dcMem, 0, 0, SRCCOPY);
ReleaseDC(pDC);

FreeDC(dcMem);

5. 位图文件的保存

CBitmap提供了SaveImage()方法用于将位图文件保存到磁盘上。

例如:

CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1);                    // 加载位图资源

BITMAP bmpInfo;
bmp.GetBitmap(&bmpInfo);                        // 获取位图信息

CImage image;
image.Attach(bmp);
image.Save(_T("C:\\test.jpg"), Gdiplus::ImageFormatJPEG);

示例一:将位图文件转换成灰度图像

CBitmap bmp;
bmp.LoadBitmap(IDB_BITMAP1);                    // 加载位图资源

BITMAP bmpInfo;
bmp.GetBitmap(&bmpInfo);                        // 获取位图信息

int nWidth = bmpInfo.bmWidth;
int nHeight = bmpInfo.bmHeight;

CImage image;
image.Create(nWidth, nHeight, 8, 0);            // 创建一张8位深度的位图

CDC dc;
dc.CreateCompatibleDC(NULL);
dc.SelectObject(image);

dc.BitBlt(0, 0, nWidth, nHeight, &dc, 0, 0, SRCCOPY);   // 原图赋值到新位图中

for (int i = 0; i < nWidth; i++)
{
    for (int j = 0; j < nHeight; j++)
    {
        COLORREF color = dc.GetPixel(i, j);
        BYTE red = GetRValue(color);
        BYTE green = GetGValue(color);
        BYTE blue = GetBValue(color);
        BYTE gray = static_cast<BYTE>((red + green + blue) / 3.0);
        dc.SetPixel(i, j, RGB(gray, gray, gray));
    }
}

image.Save(_T("C:\\test_gray.bmp"), Gdiplus::ImageFormatBMP);

示例二:叠加一个png图像到jpg图像上

CImage image;
image.Load(_T("C:\\test.jpg"));         // 加载jpg图像

CImage image2;
image2.Load(_T("C:\\test.png"));        // 加载png图像

CDC dc;
dc.CreateCompatibleDC(NULL);
dc.SelectObject(image);

CDC dc2;
dc2.CreateCompatibleDC(NULL);
dc2.SelectObject(image2);

BITMAP bmpInfo;
image.GetBitmap(&bmpInfo);

BITMAPINFO bmp;
ZeroMemory(&bmp, sizeof(BITMAPINFO));
bmp.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmp.bmiHeader.biWidth = bmpInfo.bmWidth;
bmp.bmiHeader.biHeight = bmpInfo.bmHeight;
bmp.bmiHeader.biPlanes = 1;
bmp.bmiHeader.biBitCount = 24;
bmp.bmiHeader.biCompression = BI_RGB;

BYTE *pSrcData = NULL;
image2.GetBitmapBits(bmpInfo.bmWidthBytes * bmpInfo.bmHeight, pSrcData);

BYTE *pDestData = NULL;
image.GetBitmapBits(bmpInfo.bmWidthBytes * bmpInfo.bmHeight, pDestData);

for (int i = 0; i < bmpInfo.bmWidth; i++)
{
    for (int j = 0; j < bmpInfo.bmHeight; j++)
    {
        BYTE R, G, B;
        R = pDestData[(j * bmpInfo.bmWidth + i) * 3 + 2];
        G = pDestData[(j * bmpInfo.bmWidth + i) * 3 + 1];
        B = pDestData[(j * bmpInfo.bmWidth + i) * 3];

        BYTE alpha = pSrcData[(j * bmpInfo.bmWidth + i) * 4 + 3];

        BYTE R2, G2, B2;
        R2 = pSrcData[(j * bmpInfo.bmWidth + i) * 4 + 2];
        G2 = pSrcData[(j * bmpInfo.bmWidth + i) * 4 + 1];
        B2 = pSrcData[(j * bmpInfo.bmWidth + i) * 4];

        pDestData[(j * bmpInfo.bmWidth + i) * 3 + 2] = static_cast<BYTE>((R * (255 - alpha) + R2 * alpha) / 255.f);
        pDestData[(j * bmpInfo.bmWidth + i) * 3 + 1] = static_cast<BYTE>((G * (255 - alpha) + G2 * alpha) / 255.f);
        pDestData[(j * bmpInfo.bmWidth + i) * 3] = static_cast<BYTE>((B * (255 - alpha) + B2 * alpha) / 255.f);
    }
}

image.Save(_T("C:\\test_result.jpg"), Gdiplus::ImageFormatJPEG);

结语

本文简单介绍了CBitmap类的一些常用方法,并且给出了两个简单的示例,希望读者可以在实际应用中更好地掌握CBitmap类的用法。当然,本文仅仅提供了一些简单的例子,实际的图像处理过程可能更加复杂,需要考虑到文件格式、速度等一系列因素,需要读者自行进一步学习去研究。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:VC++中图像处理类CBitmap的用法 - Python技术站

(0)
上一篇 2023年5月25日
下一篇 2023年5月25日

相关文章

  • Pytorch 高效使用GPU的操作

    PyTorch 高效使用GPU的操作 PyTorch是一个开源的深度学习框架,能够方便地运行模型,并且支持使用GPU加速计算。在这篇文章中,我们将会讲解如何高效地将PyTorch代码转移到GPU上,并优化模型的运行速度。 1. GPU加速 使用GPU加速是PyTorch中提高模型性能的一个关键方法,因为GPU相较于CPU更加适合同时处理大量计算密集型数据。在…

    人工智能概论 2023年5月25日
    00
  • python for循环如何实现控制步长

    下面我将为你详细讲解“python for循环如何实现控制步长”的完整攻略。 什么是python for循环? for 循环是 Python 中用于循环序列或其他可迭代对象的语句。循环主体将在序列中的每个元素(或其他可迭代对象)上执行一次。Python具有两种类型的循环:for循环和while循环。在本次回答中,我们关注for循环。 for 循环的一般形式如…

    人工智能概览 2023年5月25日
    00
  • 在lnmp环境中的nginx编译安装

    在 LNMP 环境中安装 Nginx 的步骤大概如下: 1. 安装编译工具 在 Linux 中编译 Nginx 需要用到一些编译工具,比如 gcc、make 等,可以通过以下命令安装: yum -y install gcc make pcre pcre-devel zlib zlib-devel openssl openssl-devel 2. 下载并解压 …

    人工智能概览 2023年5月25日
    00
  • c++ 读写yaml配置文件

    标题:C++读写YAML配置文件完整攻略 简介 YAML是一种人类可读的数据序列化格式,通常用于配置文件、数据交换、日志记录等。本文将介绍如何在C++中读写YAML配置文件的完整攻略。 依赖 yaml-cpp:一个C++的YAML解析库,用于读写YAML格式文件,可以在官网(https://github.com/jbeder/yaml-cpp)上下载。 基本…

    人工智能概览 2023年5月25日
    00
  • 编写每天定时切割Nginx日志的脚本

    编写每天定时切割Nginx日志的脚本可以有效的管理日志文件,避免日志文件过大导致服务器性能问题,同时还能提供更好的日志管理体验。下面介绍一下具体的步骤。 1. 安装 logrotate 工具 logrotate 是一个日志管理工具,可以用于指定日志目录,日志文件切割方式和周期等相关操作。在 CentOS 上,通过以下命令安装: yum install -y …

    人工智能概览 2023年5月25日
    00
  • IDEA 重新导入依赖maven 命令 reimport的方法

    以下是“IDEA 重新导入依赖maven 命令 reimport的方法”的完整攻略: 什么是依赖? 在开发过程中,我们常常需要引用各种第三方库(例如 JDK、Spring 框架等),这些库就称为依赖(dependencies)。Maven 是一个Java 项目管理工具,可以自动化地管理项目依赖。开发者只需要在 Maven 的配置文件 pom.xml 中指定依…

    人工智能概览 2023年5月25日
    00
  • python3使用python-redis-lock解决并发计算问题

    Python3使用python-redis-lock解决并发计算问题:完整攻略 1. 简介 在多线程或多进程并发计算的场景中,为了防止多个线程或进程同时访问同一个资源而产生竞争,我们需要考虑使用锁机制进行资源协调和管理。锁机制能够确保同一时刻只有一个线程或进程能够访问并修改共享资源,从而防止数据的损坏或丢失。 Python-redis-lock是一种基于Re…

    人工智能概论 2023年5月25日
    00
  • Nginx源码研究之nginx限流模块详解

    首先,需要明确Nginx限流模块的概念,即通过对请求的流量进行控制和限制,保护服务端资源免受过载而导致的服务不可用或响应缓慢。下面是nginx限流模块的完整攻略。 1. 理解Nginx限流模块的工作原理 Nginx限流模块的工作原理是基于Token Bucket算法,该算法与令牌桶算法类似,主要由三个核心参数组成:令牌速率,桶容量和最大可用令牌数。其中,令牌…

    人工智能概览 2023年5月25日
    00
合作推广
合作推广
分享本页
返回顶部