The MagickCore API 是 C 编程语言与 ImageMagick 图像处理库之间的底层接口,仅推荐给高级程序员使用。与仅使用少量不透明类型和访问器的 MagickWand C API 不同,在 MagickCore 中,您几乎完全直接访问结构成员。MagickCore 公共方法的描述在此处找到
- 初始化或销毁 ImageMagick 环境
- 构成图像
- 合成图像
- 图像方法
- 图像通道方法
- 计算图像中的颜色数量
- 颜色映射方法
- 颜色空间方法
- 图像变形
- 处理图像图层
- 处理图像配置文件
- 减少图像中唯一颜色的数量
- 图像直方图
- 使用阈值模糊 c 均值分割图像
- 调整图像大小
- 变换图像
- 以任意角度剪切或旋转图像
- 增强图像
- 添加效果
- 形态学腐蚀、膨胀、开运算和闭运算
- 添加特殊效果
- 装饰图像
- 获取/设置图像属性
- 获取/设置图像属性
- 获取图像统计信息
- 获取图像特征
- 注释图像
- 在图像上绘画
- 在图像上绘制
- 创建图像缩略图
- 计算离散傅里叶变换 (DFT)
- 将图像与重建图像进行比较
- 计算机视觉
- 交互式显示和编辑图像
- 交互式动画图像序列
- 转换为和从密码像素转换
- 使用图像列表
- 图像视图方法
- 图像缓存方法
- 获取或设置图像像素
- 使用缓存视图
- 像素 FIFO
- 读取或写入二进制大对象
- 可加载模块
- 计算图像的消息摘要
- 图像注册表
- 处理异常
- 内存分配
- 监视或限制资源消耗
- 监视图像操作的进度
- 获取版本和版权信息
- Mime 方法
- 已弃用的方法
- 错误和警告代码
编写 MagickCore 程序后,像这样编译它
cc `MagickCore-config --cflags --cppflags` -O2 -o core core.c `MagickCore-config --ldflags --libs`
如果 ImageMagick 不在您的默认系统路径中,请设置 PKG_CONFIG_PATH 环境变量
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
这是一个利用 MagickCore API 入门的示例程序,core.c。它读取 GIF 图像,创建缩略图,并将其以 PNG 图像格式写入磁盘。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <MagickCore/MagickCore.h> int main(int argc,char **argv) { ExceptionInfo *exception; Image *image, *images, *resize_image, *thumbnails; ImageInfo *image_info; if (argc != 3) { (void) fprintf(stdout,"Usage: %s image thumbnail\n",argv[0]); exit(0); } /* Initialize the image info structure and read an image. */ MagickCoreGenesis(*argv,MagickTrue); exception=AcquireExceptionInfo(); image_info=CloneImageInfo((ImageInfo *) NULL); (void) strcpy(image_info->filename,argv[1]); images=ReadImage(image_info,exception); if (exception->severity != UndefinedException) CatchException(exception); if (images == (Image *) NULL) exit(1); /* Convert the image to a thumbnail. */ thumbnails=NewImageList(); while ((image=RemoveFirstImageFromList(&images)) != (Image *) NULL) { resize_image=ResizeImage(image,106,80,LanczosFilter,exception); if (resize_image == (Image *) NULL) MagickError(exception->severity,exception->reason,exception->description); (void) AppendImageToList(&thumbnails,resize_image); DestroyImage(image); } /* Write the image thumbnail. */ (void) strcpy(thumbnails->filename,argv[2]); WriteImage(image_info,thumbnails,exception); /* Destroy the image thumbnail and exit. */ thumbnails=DestroyImageList(thumbnails); image_info=DestroyImageInfo(image_info); exception=DestroyExceptionInfo(exception); MagickCoreTerminus(); return(0); }
现在让我们在利用我们的双核或四核处理系统执行相同的对比度增强,方法是利用 wand 视图并行运行算法。The sigmoidal-contrast.c 模块读取图像,应用 S 型非线性对比度控制,并将结果写入磁盘,就像之前的对比度增强程序一样,但现在它并行执行其工作(假设 ImageMagick 使用 OpenMP 支持构建)。
#include <stdio.h> #include <stdlib.h> #include <math.h> #include <MagickCore/MagickCore.h> static MagickBooleanType SigmoidalContrast(ImageView *contrast_view, const ssize_t y,const int id,void *context) { #define QuantumScale ((MagickRealType) 1.0/(MagickRealType) QuantumRange) #define SigmoidalContrast(x) \ (QuantumRange*(1.0/(1+exp(10.0*(0.5-QuantumScale*x)))-0.0066928509)*1.0092503) RectangleInfo extent; register IndexPacket *indexes; register PixelPacket *pixels; register ssize_t x; extent=GetImageViewExtent(contrast_view); pixels=GetImageViewAuthenticPixels(contrast_view); for (x=0; x < (ssize_t) (extent.width-extent.x); x++) { SetPixelRed(pixels,RoundToQuantum(SigmoidalContrast(GetPixelRed(pixels))); SetPixelGreen(pixels,RoundToQuantum(SigmoidalContrast(GetPixelGreen(pixels))); SetPixelBlue(pixels,RoundToQuantum(SigmoidalContrast(GetPixelBlue(pixels))); SetPixelOpacity(pixels,RoundToQuantum(SigmoidalContrast(GetPixelOpacity(pixels))); pixels++; } indexes=GetImageViewAuthenticIndexes(contrast_view); if (indexes != (IndexPacket *) NULL) for (x=0; x < (ssize_t) (extent.width-extent.x); x++) SetPixelIndex(indexes+x,RoundToQuantum(SigmoidalContrast(GetPixelIndex(indexes+x)))); return(MagickTrue); } int main(int argc,char **argv) { #define ThrowImageException(image) \ { \ \ CatchException(exception); \ if (contrast_image != (Image *) NULL) \ contrast_image=DestroyImage(contrast_image); \ exit(-1); \ } #define ThrowViewException(view) \ { \ char \ *description; \ \ ExceptionType \ severity; \ \ description=GetImageViewException(view,&severity); \ (void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \ description=DestroyString(description); \ exit(-1); \ } ExceptionInfo *exception; Image *contrast_image; ImageInfo *image_info; ImageView *contrast_view; MagickBooleanType status; if (argc != 3) { (void) fprintf(stdout,"Usage: %s image sigmoidal-image\n",argv[0]); exit(0); } /* Read an image. */ MagickCoreGenesis(*argv,MagickTrue); image_info=AcquireImageInfo(); (void) CopyMagickString(image_info->filename,argv[1],MaxTextExtent); exception=AcquireExceptionInfo(); contrast_image=ReadImage(image_info,exception); if (contrast_image == (Image *) NULL) ThrowImageException(contrast_image); /* Sigmoidal non-linearity contrast control. */ contrast_view=NewImageView(contrast_image); if (contrast_view == (ImageView *) NULL) ThrowImageException(contrast_image); status=UpdateImageViewIterator(contrast_view,SigmoidalContrast,(void *) NULL); if (status == MagickFalse) ThrowImageException(contrast_image); contrast_view=DestroyImageView(contrast_view); /* Write the image then destroy it. */ status=WriteImages(image_info,contrast_image,argv[2],exception); if (status == MagickFalse) ThrowImageException(contrast_image); contrast_image=DestroyImage(contrast_image); exception=DestroyExceptionInfo(exception); image_info=DestroyImageInfo(image_info); MagickCoreTerminus(); return(0); }
MagickCoreTerminus() 是 ImageMagick 库中的一个函数,用于在关闭使用 ImageMagick 的应用程序时清理和释放资源。此函数应在应用程序进程的主线程的关闭过程中调用。至关重要的是,此函数仅在使用 ImageMagick 函数的任何线程终止后才调用。
ImageMagick 可能会通过 OpenMP(一种并行编程方法)在内部使用线程。因此,在调用 MagickCoreTerminus() 之前,务必确保对 ImageMagick 的任何函数调用都已完成。这可以防止 OpenMP 工作线程访问此终止函数销毁的资源的问题。
如果正在使用 OpenMP(从 5.0 版开始),OpenMP 实现本身会处理启动和停止工作线程以及使用其自身方法分配和释放资源。这意味着在调用 MagickCoreTerminus() 后,一些 OpenMP 资源和工作线程可能仍然保持分配状态。为了解决这个问题,可以调用函数 omp_pause_resource_all(omp_pause_hard)。此函数在 OpenMP 5.0 版中引入,可确保释放 OpenMP 分配的任何资源(例如线程和线程特定内存)。建议在 MagickCoreTerminus() 完成执行后调用此函数。