当前位置: 首页 > article >正文

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,PNGTIFF库都会对最终应用增加约100KB,而CxImage影响约为50KB.

因此,应该只支持和链接应用真正需要的格式.

格式#define必需的库[KB]大小
BMP,GIF,ICO,TGA,PCX,WBMP,WMF,SKACXIMAGE_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_JPGjpeg88
PNGCXIMAGE_SUPPORT_PNGpng,zlib104
MNGCXIMAGE_SUPPORT_MNGmng,zlib,jpeg148
TIFFCXIMAGE_SUPPORT_TIFTIFF,zlib,jpeg124
JBIGCXIMAGE_SUPPORT_JBGjbig28
PNM,PPM,PGM,RASCXIMAGE_SUPPORT_PNM,CXIMAGE_SUPPORT_RASjasper176
JPEG-2000格式CXIMAGE_SUPPORT_JP2``CXIMAGE_SUPPORT_JPC``CXIMAGE_SUPPORT_PGX同上176
RAWCXIMAGE_SUPPORT_RAWlibdcr132
选项#define[KB]大小
CxImage核心所有开关关闭20
几何变换CXIMAGE_SUPPORT_TRANSFORMATION16
处理图像CXIMAGE_SUPPORT_DSP24
绘画和窗口相关功能CXIMAGE_SUPPORT_WINDOWS12
透明CXIMAGE_SUPPORT_ALPHA4
选区CXIMAGE_SUPPORT_SELECTION4
多层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.hCXIMAGE_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_SELECTION
            if (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_ALPHA
                tmp.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);

http://www.kler.cn/a/421959.html

相关文章:

  • flink-connector-mysql-cdc:03 mysql-cdc常见问题汇总
  • CSS学习记录03
  • 互联网 Java 面试八股文汇总(2025 最新整理)
  • 论文阅读——量子退火Experimental signature of programmable quantum annealing
  • 十,[极客大挑战 2019]Secret File1
  • MySql:理解数据库
  • 怎么把项目提交到git上
  • 【WRF-Urban】Urban 模块是否运行完成及与标准 WRF 的区别
  • 编译MT7620 OpenWrt的所有机型的固件
  • PTA--数据结构预习报告: 考试排名汇总
  • Oracle篇—通过官网下载最新的数据库软件或者历史数据库软件
  • 解码气候:全球气候变化驱动因素预测!气候变化的驱动因素主要包括哪些?全球气候变化对哪些领域有影响?
  • MYSQL练习
  • 免交互运用
  • web五、元素尺寸和位置、节点操作(DOM,查找节点,增加节点,删除节点)、阶段案例
  • MySQL篇—通过官网下载linux系统下多种安装方式的MySQL社区版软件
  • 使用playwright自动化测试时,npx playwright test --ui打开图形化界面时报错
  • Hive基础篇
  • 【IMF靶场渗透】
  • Nginx配置限流,技能拉满!
  • Nodejs-初体验-1
  • C++ 游戏开发入门
  • Python将Excel文件转换为JSON文件
  • 真实情景之:处理用户密码时的“加盐”措施
  • 基于 MVC 的 SpringBoot 高校行政事务管理系统:设计布局与实现效能评估
  • 泷羽sec学习打卡-shell命令5