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、基于共享…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
