Skip to content

Instantly share code, notes, and snippets.

@sandcastle
Last active August 29, 2015 14:01
Show Gist options
  • Save sandcastle/c54836e461d54171598c to your computer and use it in GitHub Desktop.
Save sandcastle/c54836e461d54171598c to your computer and use it in GitHub Desktop.
Native wrapper for Image Magick using the Linux Share Object Library.
public class ImageMagick : IDisposable
{
IntPtr _wand;
public ImageMagick(string file)
{
var data = File.ReadAllBytes(file);
Initialise(data);
}
public int Width { get; private set; }
public int Height { get; private set; }
void Initialise(byte[] data)
{
ImageMagickWrapper.WandGenesis();
_wand = ImageMagickWrapper.NewWand();
ImageMagickWrapper.ReadImageBlob(_wand, data);
Width = (int)ImageMagickWrapper.GetWidth(_wand);
Height = (int)ImageMagickWrapper.GetHeight(_wand);
}
public void Resize(int width, int height)
{
var size = GetTargetSize(width, height);
ImageMagickWrapper.ResizeImage(_wand, (IntPtr)size.Width, (IntPtr)size.Height, ImageMagickWrapper.Filter.Lanczos, 1.0);
}
public void Save(string file)
{
var data = ImageMagickWrapper.GetImageBlob(_wand);
File.WriteAllBytes(file, data);
}
Size GetTargetSize(int targetWidth, int targetHeight)
{
var ratioWidth = Width / targetWidth;
var ratioHeight = Height / targetHeight;
if (ratioWidth > ratioHeight)
{
targetHeight = targetHeight * (ratioHeight / ratioWidth);
}
else
{
if (ratioWidth < ratioHeight)
{
targetWidth = targetWidth * (ratioWidth / ratioHeight);
}
}
return new Size(targetWidth, targetHeight);
}
public void Dispose()
{
ImageMagickWrapper.DestroyWand(_wand);
ImageMagickWrapper.WandTerminus();
}
}
public class ImageMagickWrapper
{
public enum Filter
{
Undefined,
Point,
Box,
Triangle,
Hermite,
Hanning,
Hamming,
Blackman,
Gaussian,
Quadratic,
Cubic,
Catrom,
Mitchell,
Lanczos,
Bessel,
Sinc,
Kaiser,
Welsh,
Parzen,
Lagrange,
Bohman,
Bartlett,
SincFast
};
public enum InterpolatePixel
{
Undefined,
Average,
Bicubic,
Bilinear,
Filter,
Integer,
Mesh,
NearestNeighbor,
Spline
};
[DllImport("libMagickWand.so.5", EntryPoint = "MagickResizeImage")]
public static extern bool ResizeImage(IntPtr mgck_wand, IntPtr columns, IntPtr rows, Filter filter_type, double blur);
[DllImport("libMagickWand.so.5", EntryPoint = "MagickWandGenesis")]
public static extern void WandGenesis();
[DllImport("libMagickWand.so.5", EntryPoint = "MagickWandTerminus")]
public static extern void WandTerminus();
[DllImport("libMagickWand.so.5", EntryPoint = "NewMagickWand")]
public static extern IntPtr NewWand();
[DllImport("libMagickWand.so.5", EntryPoint = "DestroyMagickWand")]
public static extern IntPtr DestroyWand(IntPtr wand);
[DllImport("libMagickWand.so.5", EntryPoint = "MagickGetImageBlob")]
public static extern IntPtr GetImageBlob(IntPtr wand, [Out] out IntPtr length);
[DllImport("libMagickWand.so.5", EntryPoint = "MagickReadImageBlob")]
public static extern bool ReadImageBlob(IntPtr wand, IntPtr blob, IntPtr length);
[DllImport("libMagickWand.so.5", EntryPoint = "MagickRelinquishMemory")]
public static extern IntPtr RelinquishMemory(IntPtr resource);
[DllImport("libMagickWand.so.5", EntryPoint = "MagickGetImageWidth")]
public static extern IntPtr GetWidth(IntPtr wand);
[DllImport("libMagickWand.so.5", EntryPoint = "MagickGetImageHeight")]
public static extern IntPtr GetHeight(IntPtr wand);
// Interop
public static bool ReadImageBlob(IntPtr wand, byte[] blob)
{
var pinnedArray = GCHandle.Alloc(blob, GCHandleType.Pinned);
var pointer = pinnedArray.AddrOfPinnedObject();
var bRetv = ReadImageBlob(wand, pointer, (IntPtr)blob.Length);
pinnedArray.Free();
return bRetv;
}
// Interop
public static byte[] GetImageBlob(IntPtr wand)
{
// Get the blob
IntPtr len;
var buf = GetImageBlob(wand, out len);
// Copy it
var dest = new byte[len.ToInt32()];
Marshal.Copy(buf, dest, 0, len.ToInt32());
// Relinquish
RelinquishMemory(buf);
return dest;
}
}
static class Program
{
static void Main()
{
var input = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "source.jpg");
var output = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "target.jpg");
using (var image = new ImageMagick(input))
{
image.Resize(150, 150);
image.Save(output);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment