2411C++,CXImage简单使用
介绍
CxImage是一个可非常简单快速的加载,保存,显示和转换图像的C++类.
文件格式和链接的C库
Cximage对象基本上是加了一些成员变量来保存有用信息的一个位图:
class CxImage{...protected:void* pDib;
//包含标题,调色板,像素BITMAPINFOHEADER head;
//标准头文件CXIMAGEINFO info;
//扩展信息BYTE* pSelection;
//所选区域BYTE* pAlpha;
//`α`通道CxImage** ppLayers;
//通用图层CxImage** ppFrames;
//动画帧}
CxImage::head是位图头,CxImage::pDib是普通位图(如CxImageBMP::Encode的实现所示).
CxImage::info是,包含不同格式间共享的许多信息及所有成员函数.
typedef struct tagCxImageInfo {DWORD dwEffWidth;
//`双字`对齐的扫描行宽度BYTE* pImage;
//图像位void* pGhost;
//如果这是重影,则`pGhost`指向身体DWORD dwType;
//原图像格式char szLastError[256];
//调试long nProgress;
//监听long nEscape;
//转义long nBkgndIndex;
//`GIF,PNG,MNG`RGBQUAD nBkgndColor;
//`RGB`透明BYTE nQuality;
//`JPEG`long nFrame;
//`TIF,GIF,MNG`:实际帧long nNumFrames;
//`用于TIF,GIF,MNG`:总帧数DWORD dwFrameDelay;
//`GIF,MNG`long xDPI;
//水平分辨率long yDPI;
//垂直分辨率RECT rSelectionBox;
//约束矩形BYTE nAlphaMax;
//最大暗度(淡化)bool bAlphaPaletteEnabled;
//如果启用了调色板中的`α`值,则为`真`.bool bEnabled;
//启用绘画函数long xOffset;long yOffset;DWORD dwEncodeOption;
//对`GIF,TIF:0=def.1=unc,2=fax3,3=fax4,4=pack,5=jpg`RGBQUAD last_c;
//用来`GetNearestIndex`优化BYTE last_c_index;bool last_c_isvalid;long nNumLayers;DWORD dwFlags;
} CXIMAGEINFO;
CxImage对象也是一组层.仅在必要时才分配每层中的缓冲.
CxImage::pDib是背景图像.CxImage::pAlpha是透明图层.CxImage::pSelection是创建处理图像的感兴趣区域的选择图层.
在这3个特定平面上,可添加在CxImage::ppLayers中保存的其他通用图层.通用层是完整的CxImage对象,因此可构建嵌套层的复杂结构.
CxImage::ppFrames用来保存(GIF)动画图像.
CxImage类成员和操作
CxImage是使用Doxygen记录的,但是因为历史原因,仍未记录许多不常见的功能.
支持的格式和选项
整个库非常大,在ximcfg.h主头文件中,可找到启用或禁止特定图形格式或特征的开关.每个JPG,PNG和TIFF库都会对最终应用增加约100KB,而CxImage影响约为50KB.
因此,应该只支持和链接应用真正需要的格式.
格式 | #define | 必需的库 | [KB]大小 |
|---|---|---|---|
BMP,GIF,ICO,TGA,PCX,WBMP,WMF,SKA | CXIMAGE_SUPPORT_BMP,CXIMAGE_SUPPORT_GIF,CXIMAGE_SUPPORT_ICO,CXIMAGE_SUPPORT_TGA,CXIMAGE_SUPPORT_PCX,CXIMAGE_SUPPORT_WBMP,CXIMAGE_SUPPORT_WMF,CXIMAGE_SUPPORT_SKA | 内置 | 24 |
JPEG格式 | CXIMAGE_SUPPORT_JPG | jpeg | 88 |
PNG | CXIMAGE_SUPPORT_PNG | png,zlib | 104 |
MNG | CXIMAGE_SUPPORT_MNG | mng,zlib,jpeg | 148 |
TIFF | CXIMAGE_SUPPORT_TIF | TIFF,zlib,jpeg | 124 |
JBIG | CXIMAGE_SUPPORT_JBG | jbig | 28 |
PNM,PPM,PGM,RAS | CXIMAGE_SUPPORT_PNM,CXIMAGE_SUPPORT_RAS | jasper | 176 |
JPEG-2000格式 | CXIMAGE_SUPPORT_JP2``CXIMAGE_SUPPORT_JPC``CXIMAGE_SUPPORT_PGX | 同上 | 176 |
RAW | CXIMAGE_SUPPORT_RAW | libdcr | 132 |
| 选项 | #define | [KB]大小 |
|---|---|---|
CxImage核心 | 所有开关关闭 | 20 |
几何变换 | CXIMAGE_SUPPORT_TRANSFORMATION | 16 |
处理图像 | CXIMAGE_SUPPORT_DSP | 24 |
绘画和窗口相关功能 | CXIMAGE_SUPPORT_WINDOWS | 12 |
透明 | CXIMAGE_SUPPORT_ALPHA | 4 |
选区 | CXIMAGE_SUPPORT_SELECTION | 4 |
多层 | CXIMAGE_SUPPORT_LAYERS | <4 |
图形格式转换 | CXIMAGE_SUPPORT_DECODE,CXIMAGE_SUPPORT_ENCODE | <4 |
插值功能 | CXIMAGE_SUPPORT_INTERPOLATION | <4 |
处理异常 | CXIMAGE_SUPPORT_EXCEPTION_HANDLING | <4 |
在项目中使用CxImage
CxImgLib.dsw客户区显示了构建应用(demo.exe)期望库,包括CxImage中可用的几乎所有函数和格式.必须先编译所有库,才能链接最终应用.
在源码中,你必须添加#include"ximage.h"
在CxImage中添加自定义功能
使用CxImage编写处理图像的新功能并不难.在此,我描述了非常简单的CxImage::Jitter,但它显示了在CxImage中工作时注意的许多方面.
首先,当然是声明:在ximage.h的CXIMAGE_SUPPORT_DSP部分中声明bool Jitter(longradius=2);,你可在类的公域中声明该函数.
现在是定义:
bool CxImage::Jitter(long radius)
{
//检查图像是否有效,这应该总是是函数中的第一行if (!pDib) return false;
//局部变量long nx,ny;
//临时图像来保存算法的部分结果CxImage tmp(*this,pSelection!=0,true,true);//仅在包含所选区域的最小矩形中限制函数的效果(使用`Selection...()`函数),这加快循环速度.long xmin,xmax,ymin,ymax;if (pSelection){xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;} else {xmin = ymin = 0;xmax = head.biWidth; ymax=head.biHeight;}
//`主循环`:在垂直方向扫描图像for(long y=ymin; y <ymax; y++){
//监听循环的进度info.nProgress = (long)(100*y/head.biHeight);
//让应用快速退出if (info.nEscape) break;
//`主循环`:在水平方向扫描图像for(long x=xmin; x<xmax; x++){
//如果启用该函数,则仅处理所选区域内的像素
#if CXIMAGE_SUPPORT_SELECTIONif (SelectionIsInside(x,y))
#endif
//`CXIMAGE_SUPPORT_SELECTION`{
//主要算法nx=x+(long)((rand()/(float)RAND_MAX - 0.5)*(radius*2));ny=y+(long)((rand()/(float)RAND_MAX - 0.5)*(radius*2));if (!IsInside(nx,ny)) {nx=x;ny=y;}//在临时图像中保存结果.如果可以,请仅对`24bpp`图像使用`PixelColor`,对`8,4`和`1bpp`图像使用`PixelIndex`:这样更快if (head.biClrUsed==0){tmp.SetPixelColor(x,y,GetPixelColor(nx,ny));} else {tmp.SetPixelIndex(x,y,GetPixelIndex(nx,ny));}
//如果启用了该功能,则还要处理`α`图层中的像素
#if CXIMAGE_SUPPORT_ALPHAtmp.AlphaSet(x,y,AlphaGet(nx,ny));
#endif
//`CXIMAGE_SUPPORT_ALPHA`}}}
//保存结果并退出Transfer(tmp);return true;
}
示例:如何…
…按另一个格式转换一个格式.
CxImage image;
//`BMP->JPG`
image.Load("image.bmp", CXIMAGE_FORMAT_BMP);
if (image.IsValid()){if(!image.IsGrayScale()) image.IncreaseBpp(24);image.SetJpegQuality(80);image.Save("image.jpg",CXIMAGE_FORMAT_JPG);
}
//`PNG->TIF`
image.Load("image.png", CXIMAGE_FORMAT_PNG);
if (image.IsValid()){image.Save("image.tif",CXIMAGE_FORMAT_TIF);
}
…加载图像资源
//从`PNG`资源类型加载资源`IDR_PNG1`
CxImage* newImage = new CxImage();
newImage->LoadResource(FindResource(NULL,MAKEINTRESOURCE(IDR_PNG1), "PNG"),CXIMAGE_FORMAT_PNG);
//或
//从`DLL`加载资源`IDR_JPG1`
CxImage* newImage = new CxImage();
HINSTANCE hdll=LoadLibrary("imagelib.dll");
if (hdll){HRSRC hres=FindResource(hdll,MAKEINTRESOURCE(IDR_JPG1),"JPG");newImage->LoadResource(hres,CXIMAGE_FORMAT_JPG,hdll);FreeLibrary(hdll);
}
//或:
//加载位图资源;
HBITMAP bitmap = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1)));
CxImage *newImage = new CxImage();
newImage->CreateFromHBITMAP(bitmap);
… 从内存解码图片
CxImage image((BYTE*)buffer,size,image_type);
//或
CxMemFile memfile((BYTE*)buffer,size);
CxImage image(&memfile,image_type);
//或
CxMemFile memfile((BYTE*)buffer,size);
CxImage* image = new CxImage();
image->Decode(&memfile,type);
…在内存中编码图像
long size=0;
BYTE* buffer=0;
image.Encode(buffer,size,image_type);
...
image.FreeMemory(buffer);
//或
CxMemFile memfile;
memfile.Open();
image.Encode(&memfile,image_type);
BYTE* buffer = memfile.GetBuffer();
long size = memfile.Size();
...
image.FreeMemory(buffer);
… 创建多页TIFF
CxImage *pimage[3];
pimage[0]=&image1;
pimage[1]=&image2;
pimage[2]=&image3;
FILE* hFile;
hFile = fopen("multipage.tif","w+b");
CxImageTIF multiimage;
multiimage.Encode(hFile,pimage,3);
fclose(hFile);//或
FILE* hFile;
hFile = fopen("c:\\multi.tif","w+b");
CxImageTIF image;
image.Load("c:\\1.tif",CXIMAGE_FORMAT_TIF);
image.Encode(hFile,true);
image.Load("c:\\2.bmp",CXIMAGE_FORMAT_BMP);
image.Encode(hFile,true);
image.Load("c:\\3.png",CXIMAGE_FORMAT_PNG);
image.Encode(hFile);
fclose(hFile);
…复制/粘贴图像
//复制
HANDLE hDIB = image->CopyToHandle();
if (::OpenClipboard(AfxGetApp()->m_pMainWnd->GetSafeHwnd())) {if(::EmptyClipboard()) {if (::SetClipboardData(CF_DIB,hDIB) == NULL ) {AfxMessageBox( "Unable to set Clipboard data" );
} } }
CloseClipboard();
//糊
HANDLE hBitmap=NULL;
CxImage *newima = new CxImage();
if (OpenClipboard()) hBitmap=GetClipboardData(CF_DIB);
if (hBitmap) newima->CreateFromHANDLE(hBitmap);
CloseClipboard();
在图片框中显示文件
HBITMAP m_bitmap = NULL;
CxImage image("myfile.png", CXIMAGE_FORMAT_PNG);
...
CDC* hdc = m_picture.GetDC();
HBITMAP m_bitmap = image.MakeBitmap(hdc->m_hDC);
HBITMAP hOldBmp = m_picture.SetBitmap(m_bitmap);
if (hOldBmp) DeleteObject(hOldBmp);
if (hdc->m_hDC) m_picture.ReleaseDC(hdc);
...
if (m_bitmap) DeleteObject(m_bitmap);
相关文章:
2411C++,CXImage简单使用
介绍 CxImage是一个可非常简单快速的加载,保存,显示和转换图像的C类. 文件格式和链接的C库 Cximage对象基本上是加了一些成员变量来保存有用信息的一个位图: class CxImage{...protected:void* pDib; //包含标题,调色板,像素BITMAPINFOHEADER head; //标准头文件CXIMAGEINFO…...
什么是 Kubernetes(K8s)?
什么是 Kubernetes(K8s)? Kubernetes(简称 K8s) 是一个用来管理容器的开源工具,它可以自动化部署、扩展和管理容器化应用。简单来说,K8s 就是一个“容器管家”,负责确保你的应用程序…...
深入解析:TypeScript 与 Vue 的完美结合
文章目录 前言一、准备工作二、基本用法三、进阶主题结语 前言 Vue.js 是一款流行的渐进式 JavaScript 框架,它以易于学习和灵活的特性而闻名。TypeScript 则是 JavaScript 的一个超集,它引入了静态类型检查等高级功能,有助于构建更大型且复…...
机器学习周志华学习笔记-第13章<半监督学习>
机器学习周志华学习笔记-第13章<半监督学习> 卷王,请看目录 13半监督学习13.1 生成式方法13.2 半监督SVM13.3 基于分歧的方法13.4 半监督聚类 13半监督学习 前面我们一直围绕的都是监督学习与无监督学习,监督学习指的是训练样本包…...
软件工程——期末复习(1)
名词解释: 名词解释--人月 答案:人月是软件开发工作量的单位,1人月表示1个程序员1个月的工作时间所开发的代码量。 请解释软件缺陷、错误和失败,并简单举例说明。 答案:缺陷(defect)指系统代…...
【JavaEE初阶 — 网络编程】实现基于TCP协议的Echo服务
TCP流套接字编程 1. TCP & UDP 的区别 TCP 的核心特点是面向字节流,读写数据的基本单位是字节 byte 2 API介绍 2.1 ServerSocket 定义 ServerSocket 是创建 TCP 服务端 Socket 的API。 构造方法 方法签名 方法说明 ServerS…...
vue结合canvas动态生成水印效果
在 Vue 项目中添加水印可以通过以下几种方式实现: 方法一:使用 CSS 直接通过 CSS 的 background 属性实现水印: 实现步骤 在需要添加水印的容器中设置背景。使用 rgba 设置透明度,并通过 background-repeat 和 background-size…...
Qt 5 中的 QTextStream 使用指南
文章目录 Qt 5 中的 QTextStream 使用指南介绍基本概念读取文件注意事项结论 Qt 5 中的 QTextStream 使用指南 介绍 QTextStream 是 Qt 框架中用于处理文本数据的类。它提供了方便的接口来读写文本文件或字符串,支持多种编码格式,并且可以与 QIODevice…...
中安证件OCR识别技术助力鸿蒙生态:智能化证件识别新体验
在数字化和智能化的浪潮中,伴随国产化战略的深入推进,国产操作系统和软件生态的建设逐渐走向成熟。鸿蒙操作系统(HarmonyOS Next)作为华为推出的重要操作系统,凭借其开放、灵活和高效的特点,正在加速在多个…...
SpringBoot 框架下基于 MVC 的高校办公室行政事务管理系统:设计开发全解析
2系统开发环境 2.1vue技术 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式JavaScript框架。 [5] 与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第…...
【ArkTS】使用AVRecorder录制音频 --内附录音机开发详细代码
系列文章目录 【ArkTS】关于ForEach的第三个参数键值 【ArkTS】“一篇带你读懂ForEach和LazyForEach” 【小白拓展】 【ArkTS】“一篇带你掌握TaskPool与Worker两种多线程并发方案” 【ArkTS】 一篇带你掌握“语音转文字技术” --内附详细代码 【ArkTS】技能提高–“用户授权”…...
Selenium3+Python如何操作键盘
selenium操作键盘,需要导入Keys类:“from selenium.webdriver.common.keys import Keys” 调用键盘操作的快捷键的方法 : 单键值:直接传入对应的键值“element.send_keys”(快捷键的键值) 组合键:键值之间由逗号分隔…...
PLC协议
PLC协议通常指的是可编程逻辑控制器(Programmable Logic Controller, PLC)与其他设备之间通信时所使用的协议。PLC广泛应用于工业自动化领域,用于控制和监控设备。不同厂商和应用场景可能使用不同的通信协议。 常见的PLC通信协议 1. Modbus …...
C_字符串的一些函数
1.字符串输入函数 scanf("%s",数组名); gets(数组名); 区别: scanf(“%s”,数组名); 把空格识别为输入结束 #include <stdio.h>int main() {char a[10];printf("输入:");scanf("%s",a)…...
使用Native AOT发布C# dll 提供给C++调用
Native AOT,即提前本地编译(Ahead-Of-Time Compilation),是一种将托管代码(如 C#)编译为本机可执行文件的技术,无需在运行时进行任何代码生成。 (Native AOT 优缺点截图摘自张善友博…...
Git 提交代码日志信息
前言 在项目中经常用到git提交代码,每次提交时需要添加日志信息,那么一套规范的日志信息会让整个git仓库看起来赏心悦目! 以下是Git 提交代码日志信息的建议: 一、格式规范 标题(Subject) 标题是日志信息中…...
Request method ‘POST‘ not supported(500)
前端路径检查 查看前端的请求路径地址、请求类型、方法名是否正确,结果没问题 后端服务检查 查看后端的传参uri、传参类型、方法名,结果没问题 nacos服务名检查 检查注册的服务是否对应(我这里是后端的服务名是‘ydlh-gatway’,服务列表走…...
终端环境下关闭显示器
终端环境下关闭显示器 使用vbetool vbetool 使用 lrmi 来运行视频 BIOS 中的代码。目前,它能够更改 DPMS 状态、保存/恢复视频卡状态并尝试从头开始初始化视频卡。 vbetool dpms off...
常见排序算法总结 (三) - 归并排序与归并分治
归并排序 算法思想 将数组元素不断地拆分,直到每一组中只包含一个元素,单个元素天然有序。之后用归并的方式收集跨组的元素,最终形成整个区间上有序的序列。 稳定性分析 归并排序是稳定的,拆分数组时会自然地将元素分成有先后…...
【后端开发】Go语言编程实践,Goroutines和Channels,基于共享变量的并发,反射与底层编程
【后端开发】Go语言编程实践,Goroutines和Channels,基于共享变量的并发,反射与底层编程 【后端开发】Go语言高级编程,CGO、Go汇编语言、RPC实现、Web框架实现、分布式系统 文章目录 1、并发基础, Goroutines和Channels2、基于共享…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
数据结构:递归的种类(Types of Recursion)
目录 尾递归(Tail Recursion) 什么是 Loop(循环)? 复杂度分析 头递归(Head Recursion) 树形递归(Tree Recursion) 线性递归(Linear Recursion)…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
WEB3全栈开发——面试专业技能点P4数据库
一、mysql2 原生驱动及其连接机制 概念介绍 mysql2 是 Node.js 环境中广泛使用的 MySQL 客户端库,基于 mysql 库改进而来,具有更好的性能、Promise 支持、流式查询、二进制数据处理能力等。 主要特点: 支持 Promise / async-await…...
计算机系统结构复习-名词解释2
1.定向:在某条指令产生计算结果之前,其他指令并不真正立即需要该计算结果,如果能够将该计算结果从其产生的地方直接送到其他指令中需要它的地方,那么就可以避免停顿。 2.多级存储层次:由若干个采用不同实现技术的存储…...
