用MIL做图像处理首先得学会如何输入图像Buffer来做处理和处理完的图像Buffer如何保存。本文详述详述了MIL中加载图像的三种方式、MIL支持的图像文件格式和MIL保存图像方法。
1.图像的加载
#include<stdio.h>
#include <mil.h>
#pragma comment(lib, "mil.lib")
int main(int argc, char* argv[])
{
MIL_ID MilApplication, /* Application identifier. */
MilSystem, /* System identifier. */
MilDisplay, /* Display identifier. */
MilBufferRestore, MilBufferImportR, MilBufferLoad, MilBufferDraw; /* Image buffer identifier. */
//初始化
MilApplication = MilSystem = MilDisplay = MilBufferRestore = MilBufferImportR = MilBufferLoad = MilBufferDraw = M_NULL;
//分配默认的应用、系统、显示,注意默认的显示是显示在MIL内建的演示windows窗口
MappAllocDefault(M_SETUP, &MilApplication, &MilSystem, &MilDisplay, M_NULL, M_NULL);
/************************************************************************/
/*
第一种:
从已有的图像文件(.bmp,.jpg格式文件)读入图像数据新建MIL Buffer,新建的Buffer
内存大小由图像大小来确定
*/
/************************************************************************/
MbufRestore(".\\image\\1.JPG", MilSystem, &MilBufferRestore);
//显示
printf("按<Enter>键显示Retore的图像\n");
getchar();
MdispSelect(MilDisplay, MilBufferRestore);
// 关闭显示.
printf("按<Enter>键停止显示Retore的图像\n");
getchar();
MdispSelect(MilDisplay, M_NULL);
MbufImport(".\\image\\bird.mim", M_MIL, M_RESTORE, MilSystem, &MilBufferImportR);
//显示
printf("按<Enter>键显示Import-Restore的图像\n");
getchar();
MdispSelect(MilDisplay, MilBufferImportR);
// 关闭显示.
printf("按<Enter>键停止显示Import-Restore的图像\n");
getchar();
MdispSelect(MilDisplay, M_NULL);
/************************************************************************/
/*
第二种:
先分配固定大小的MIL Buffer,再将图像文件(.bmp,.jpg格式文件)数据读到新建
MIL Buffer,图像文件分辨率不能比新建的Buffer大
*/
/************************************************************************/
//分配Buffer
MbufAlloc2d(MilSystem,
MbufDiskInquire(".\\image\\1.JPG", M_SIZE_X, M_NULL),
MbufDiskInquire(".\\image\\1.JPG", M_SIZE_Y, M_NULL),
32+M_UNSIGNED,
M_IMAGE + M_DISP,
&MilBufferLoad);
MbufLoad(".\\image\\1.JPG", MilBufferLoad);
//显示
printf("按<Enter>键显示Load的图像\n");
getchar();
MdispSelect(MilDisplay, MilBufferLoad);
// 关闭显示.
printf("按<Enter>键停止显示Load的图像\n");
getchar();
MdispSelect(MilDisplay, M_NULL);
MbufImport(".\\image\\1.JPG", MbufDiskInquire(".\\image\\1.JPG", M_FILE_FORMAT, M_NULL), M_LOAD, MilSystem, &MilBufferLoad);
//显示
printf("按<Enter>键显示Import-Load的图像\n");
getchar();
MdispSelect(MilDisplay, MilBufferLoad);
// 关闭显示.
printf("按<Enter>键停止显示Import-Load的图像\n");
getchar();
MdispSelect(MilDisplay, M_NULL);
/************************************************************************/
/*
第三种:
先分配固定大小的MIL Buffer,自己绘制图像内容并显示
*/
/************************************************************************/
//分配Buffer
MbufAlloc2d(MilSystem,
500,
500,
8+M_UNSIGNED,
M_IMAGE + M_DISP,
&MilBufferDraw);
//初始化buffer颜色
MbufClear(MilBufferDraw, 125);
//显示
printf("按<Enter>键显示初始化绘制的图像\n");
getchar();
MdispSelect(MilDisplay, MilBufferDraw);
// 关闭显示.
printf("按<Enter>键停止显示初始化绘制的图像\n");
getchar();
MdispSelect(MilDisplay, M_NULL);
//文字图像
MgraColor(M_DEFAULT, 200);
MgraText(M_DEFAULT, MilBufferDraw, 100, 100, "MIL Text");
//显示
printf("按<Enter>键显示自绘制的文字图像\n");
getchar();
MdispSelect(MilDisplay, MilBufferDraw);
// 关闭显示.
printf("按<Enter>键停止显示自绘制的文字图像\n");
getchar();
MdispSelect(MilDisplay, M_NULL);
// 释放资源
if (M_NULL != MilBufferRestore)
{
MbufFree(MilBufferRestore);
}
if (M_NULL != MilBufferImportR)
{
MbufFree(MilBufferImportR);
}
if (M_NULL != MilBufferLoad)
{
MbufFree(MilBufferLoad);
}
if (M_NULL != MilBufferDraw)
{
MbufFree(MilBufferDraw);
}
if (M_NULL != MilApplication)
{
MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL);
}
return 0;
}
对于三种加载方式流程,上面的程序已经讲得很清楚,结合注释和手册可以加深理解。
使用MbufRestore加载图像会自动识别图像文件格式和大小,保存成对应大小的最合适的图像内存存储格式(参见博文),也可以使用MbufImport指明M_STORE参数加载指定文件格式的图像。但是注意MIL支持加载的图像文件格式是有限的(MIL,RAW,JPG,TIF,BMP),同时还需要注意的就是即使要加载的图像格式是MIL支持的也有可能不成功,这是因为同一图像格式文件的标准也在不断发展和改变(如JPEG和JPEG2000等,具体参见MIL手册),另外同一格式的文件可能有不同的深度如有8bit BMP和16bit BMP等等,注意加载MIL支持的图像的格式、版本和深度,如果你发现用加载JPG不成功,那么很有可能是你的JPG文件版本或深度不对。其中,MIL格式文件是MIL内建的基于TIFF 6.0的图像格式,后缀名为MIM,你可以用一般的能打开tiff格式文件的图像查看软件来打开它(如windows自带的图像查看器),RAW格式文件只是为了保存矩阵数据而建立的内建格式,只支持MIL对应的规则来解析打开。
先分配固定大小的图像Buffer,再MbufLoad自动识别图像文件格式导入不大于它的图像文件,也可以使用MbufImport指明M_LOAD参数加载指定文件格式的图像。这里我们为了得到图像文件保存的图像格式和大小,使用MbufDiskInquire函数对硬盘上图像文件信息做相关查询工作,这是常用的技巧。如果待加载的图像格式是压缩的,分配的图像Buffer是不压缩的,加载时会自动解压缩,同样加载的图像格式是不压缩的,分配的图像Buffer是压缩的,加载时会自动压缩,总之,在待加载图像文件格式和Buffer存储格式之间做一个转换匹配。
如果是自己绘制图像的话,一般我们会使用MbufClear对整个Buffer做一个初始化操作,然后使用Mgra开头函数做绘制点、线、圆、文字等操作,类似windows的GDI。
2.图像的保存
MIL中使用MbufSave默认保存成TIFF 6.0兼容的MIL格式图像文件或MbufExport保存为指定格式的图像文件。同样 MIL支持保存的图像的格式、 版本和深度是有限的,如果待保存的Buffer保存为指定的图像类型,会根据指定的图像类型对Buffer做处理,如16bit Buffer保存成BMP就会只保存低 8bit,这是一定要注意的。下面给出图像保存流程代码,具体参看注释和手册自行分析
/************************************************************************/
/* 图像保存*/
/************************************************************************/
//保存为TIFF 6.0兼容
printf("按<Enter>键保存自绘制的文字图像为TIF兼容格式\n");
getchar();
MbufSave("1.tif", MilBufferDraw);
//保存为JPG
printf("按<Enter>键保存自绘制的文字图像为JPG格式\n");
getchar();
MbufExport("1.jpg", M_JPEG2000_LOSSY, MilBufferDraw);
//保存为BMP
printf("按<Enter>键保存自绘制的文字图像为BMP格式\n");
getchar();
MbufExport("1.bmp", M_BMP, MilBufferDraw);
//保存为TIFF
printf("按<Enter>键保存自绘制的文字图像为TIF格式\n");
getchar();
MbufExport("2.tif", M_TIFF, MilBufferDraw);
保存成功后,用windows自带图像查看器查看,笔者用的是Windows XP MIL8.0,可以发现1.tif,1.bmp,2.tif均可以正常打开而1.jpg无法打开,这估计是MIL总用的JPEG压缩格式标准太老的原因吧。和加载图像一样,在图像Buffer和保存的图像文件之间会做一个转换匹配,具体参见MIL手册。
博客中源代码下载链接
需要指出的是编写MIL程序时,为了防止操作"悬垂指针",最好对MIL_ID标识变量做初始化和释放时检测操作。