MagickCore API adalah antarmuka tingkat rendah antara bahasa pemrograman C dan pustaka pemrosesan gambar ImageMagick, serta hanya direkomendasikan untuk programmer tingkat pakar (wizard-level). Berbeda dengan API C MagickWand yang hanya menggunakan sedikit tipe opak dan accessor, dengan MagickCore Anda hampir selalu mengakses anggota struktur secara langsung. Deskripsi metode publik MagickCore dapat ditemukan di GitHub:
- Inisialisasi atau hancurkan lingkungan ImageMagick
- Membentuk gambar
- Mengomposisikan gambar
- Metode gambar
- Metode kanal gambar
- Menghitung jumlah warna dalam gambar
- Metode colormap
- Metode ruang warna
- Distorsi gambar
- Menangani layer gambar
- Menangani profil gambar
- Mengurangi jumlah warna unik dalam gambar
- Histogram gambar
- Menyegmentasi gambar dengan ambang batas Fuzzy c-Means
- Mengubah ukuran gambar
- Mentransformasikan gambar
- Memiringkan (shear) atau memutar gambar dengan sudut sembarang
- Meningkatkan kualitas gambar
- Menambahkan efek
- Erosi, dilasi, opening, dan closing morfologis
- Menambahkan efek khusus
- Mendekorasi gambar
- Mendapatkan/mengatur atribut gambar
- Mendapatkan/mengatur properti gambar
- Mendapatkan statistik gambar
- Mendapatkan fitur gambar
- Memberi anotasi pada gambar
- Melukis pada gambar
- Menggambar pada gambar
- Membuat thumbnail gambar
- Menghitung transformasi Fourier diskret (DFT)
- Membandingkan gambar dengan gambar hasil rekonstruksi
- Visi komputer
- Menampilkan dan mengedit gambar secara interaktif
- Menganimasikan urutan gambar secara interaktif
- Mengonversi ke dan dari piksel tersandi (cipher)
- Bekerja dengan daftar gambar
- Metode ImageView
- Mendapatkan atau mengatur piksel gambar
- Bekerja dengan CacheView
- FIFO piksel
- Membaca atau menulis Binary Large OBjects (BLOB)
- Modul yang dapat dimuat
- Menghitung message digest untuk gambar
- Registry gambar
- Menangani exception
- Alokasi memori
- Memantau atau membatasi konsumsi sumber daya
- Memantau progres operasi gambar
- Mendapatkan versi dan hak cipta
- Metode Mime
- Metode yang sudah usang (deprecated)
- Kode error dan peringatan
Setelah Anda menulis program MagickCore, kompilasi seperti berikut ini:
cc `MagickCore-config --cflags --cppflags` -O2 -o core core.c `MagickCore-config --ldflags --libs`
Atur variabel lingkungan PKG_CONFIG_PATH jika ImageMagick tidak berada di path default sistem Anda:
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
Berikut adalah contoh program yang menggunakan MagickCore API untuk membantu Anda memulai, core.c. Program ini membaca gambar GIF, membuat thumbnail, dan menulisnya ke disk dalam format gambar 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);
}
Sekarang mari kita melakukan peningkatan kontras yang sama sambil memanfaatkan sistem pemrosesan dual-core atau quad-core kita, dengan menjalankan algoritmenya secara paralel menggunakan wand view. Modul sigmoidal-contrast.c membaca gambar, menerapkan kontrol kontras non-linearitas sigmoidal, dan menulis hasilnya ke disk seperti program peningkatan kontras sebelumnya, tetapi kali ini prosesnya dilakukan secara paralel (dengan asumsi ImageMagick dibangun dengan dukungan 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() adalah fungsi dalam pustaka ImageMagick yang digunakan untuk membersihkan dan melepaskan sumber daya saat aplikasi yang menggunakan ImageMagick dimatikan (shutdown). Fungsi ini harus dipanggil pada thread utama proses aplikasi selama proses shutdown berlangsung. Sangat penting agar fungsi ini hanya dipanggil setelah semua thread yang menggunakan fungsi-fungsi ImageMagick selesai berjalan.
ImageMagick mungkin menggunakan thread secara internal melalui OpenMP (metode pemrograman paralel). Karena itu, penting untuk memastikan bahwa semua pemanggilan fungsi ke ImageMagick telah selesai sebelum memanggil MagickCoreTerminus(). Hal ini mencegah masalah pada worker thread OpenMP yang mengakses sumber daya yang telah dihancurkan oleh fungsi terminasi ini.
Jika OpenMP digunakan (mulai dari versi 5.0), implementasi OpenMP itu sendiri yang menangani proses memulai dan menghentikan worker thread serta mengalokasikan dan membebaskan sumber daya menggunakan metodenya sendiri. Ini berarti bahwa setelah memanggil MagickCoreTerminus(), sebagian sumber daya dan worker thread OpenMP mungkin masih tetap teralokasi. Untuk mengatasi hal ini, fungsi omp_pause_resource_all(omp_pause_hard) dapat dipanggil. Fungsi ini, yang diperkenalkan pada OpenMP versi 5.0, memastikan bahwa semua sumber daya yang dialokasikan oleh OpenMP (seperti thread dan memori khusus thread) dibebaskan. Disarankan untuk memanggil fungsi ini setelah MagickCoreTerminus() selesai dijalankan.