The MagickCore API is a low-level interface between the C programming language and ImageMagick's core processing libraries. Designed for wizard-level programmers, MagickCore gives you direct access to structure members—unlike the MagickWand C API, which uses opaque types and accessors.
MagickCore Public Methods Reference
Explore headers and function definitions directly on GitHub:
- • Environment Init & Destroy
- • Constitute an Image
- • Composite an Image
- • Core Image Methods
- • Image Channel Methods
- • Count Image Colors
- • Colormap Methods
- • Colorspace Methods
- • Image Distortions
- • Dealing with Layers
- • Image Profiles
- • Quantize & Color Reduction
- • Image Histograms
- • Fuzzy c-Means Segmentation
- • Resize Methods
- • Transform Methods
- • Shear or Rotate
- • Enhance Methods
- • Add Effects
- • Morphology Operations
- • Special Effects (FX)
- • Decorate Methods
- • Get/Set Attributes
- • Get/Set Properties
- • Image Statistics
- • Image Features
- • Annotate Image
- • Paint Methods
- • Vector Drawing
- • Thumbnails & Montage
- • Discrete Fourier Transform
- • Compare Images
- • Computer Vision
- • Interactive Display/Edit
- • Interactive Animation
- • Cipher Pixels
- • Image Lists
- • Image Views
- • Pixel Cache
- • Cache Views
- • Pixel FIFO Stream
- • Binary Large OBjects (BLOB)
- • Loadable Modules
- • Message Digest Signature
- • Image Registry
- • Exception Handling
- • Memory Allocation
- • Resource Limits
- • Progress Monitoring
- • Version & Copyright
- • MIME Type Methods
- • Deprecated Methods
- • Error & Warning Codes
Compiling MagickCore Programs
Compile your MagickCore C program using MagickCore-config flags:
$ cc `MagickCore-config --cflags --cppflags` -O2 -o core core.c `MagickCore-config --ldflags --libs`
If ImageMagick is installed outside your system's default path, export PKG_CONFIG_PATH:
$ export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
Code Examples
Example 1: Basic Image Resizing (core.c)
This example reads a GIF image, resizes it into a thumbnail, and writes it back as a PNG file:
#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);
}
Example 2: Parallel Processing with Wand Views (sigmoidal-contrast.c)
This program applies sigmoidal non-linearity contrast control across multicore systems in parallel using OpenMP-backed Wand Views:
#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);
}
Resource Cleanup and OpenMP Considerations
The MagickCoreTerminus() function cleans up and releases internal resources upon application shutdown. Call this in the main application thread only after all secondary worker threads using ImageMagick functions have completed.
OpenMP Resource Deallocation (v5.0+)
When OpenMP threading is used, the runtime handles worker thread lifecycles and thread-local memory allocation. Consequently, some OpenMP worker threads and memory allocations may persist after MagickCoreTerminus() completes. To release these remaining resources, call omp_pause_resource_all(omp_pause_hard) immediately following MagickCoreTerminus().