# lua-imagick **Repository Path**: tyy123456/lua-imagick ## Basic Information - **Project Name**: lua-imagick - **Description**: No description available - **Primary Language**: Lua - **License**: WTFPL - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-04-26 - **Last Updated**: 2025-04-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Lua IMagick [![Build Status](https://travis-ci.org/isage/lua-imagick.svg?branch=master)](https://travis-ci.org/isage/lua-imagick) Pure-C lua bindings to ImageMagick ## Why? Because existing FFI-based bindings are hackish and buggy, duh. ## Table of Contents * [FAQ](#faq) * [Requirements](#requirements) * [Installation](#installation) * [Usage](#usage) * [Examples](#examples) * [Authors](#authors) * [Copyright and License](#copyright-and-license) ## FAQ 1. Q) Will this work with openresty/nginx-lua? A) Yes. But remember, that IM operations **are** blocking. 2. Q) Is this production ready? A) Yes, we're using it for couple of months now without problems. 3. Q) Is this feature-complete? A) Hell no. There's lot of uncovered IM api. I've implemented only needed for me api for now. 4. Q) How do i properly resize animated gif? A) Firstly, coalesce() it, then resize as usual, then optimize() it back. You really should cache coalesce()'ed image if you resizing it frequently. ## Requirements * ImageMagick developer headers (>=6.8.8.3) * Lua (5.1/5.2) or LuaJit * Cmake 2.8.12 or later * Working C compiler ## Installation As easy as ```bash mkdir build cd build cmake .. make make install ``` You can also use `make unittest` after make to run tests. By default module compiles with support for luajit For other Lua interpreters see cmake options. ## Usage ### Synopsis ```lua local magick = require "imagick" local img = magick.open("filename.jpg") img:set_gravity(magick.gravity["NorthGravity"]) img:smart_resize("100x100^") img:extent(100, 100) img:set_quality(90) img:strip() img:write("out.jpg") ``` ### Enumerations #### imagick.gravity Gravity values See [here](https://imagemagick.org/api/MagickCore/geometry_8h.html#afd1e527b17eba5305ea949fa7c717069) Example ```lua local magick = require "imagick" print(magick.gravity["WestGravity"]) ``` #### imagick.interlace Interlace scheme values See [here](https://imagemagick.org/api/MagickCore/image_8h.html#af89b808293a7faf805254d1b01e69dc2) Example ```lua local magick = require "imagick" print(magick.interlace["JPEGInterlace"]) ``` #### imagick.colorspace Colorspace values See [here](https://imagemagick.org/api/MagickCore/colorspace_8h.html#a5d516b430fa42c1f83b557f08128f3c2) Example ```lua local magick = require "imagick" print(magick.colorspace["YUVColorspace"]) ``` #### imagick.filters Scale filters See [here](https://imagemagick.org/api/MagickCore/resample_8h.html#a12be80da7313b1cc5a7e1061c0c108ea) Example ```lua local magick = require "imagick" print(magick.filters["LanczosSharpFilter"]) ``` #### imagick.composite_op Composite operations See [here](https://imagemagick.org/api/MagickCore/composite_8h.html#a55ded0ef54def8597243db2375b987fb) Example ```lua local magick = require "imagick" local img = magick.open("input.jpg") local logo = magick.open("logo.jpg") img:set_compose( magick.composite_op["CopyCompositeOp"] ) img:composite(logo, 0, 0) img:write("out.jpg") ``` #### imagick.font_style Font styles * UndefinedStyle * NormalStyle * ItalicStyle * ObliqueStyle * AnyStyle #### imagick.text_align Font align * UndefinedAlign * LeftAlign * CenterAlign * RightAlign #### imagick.channel Color channels See [here](https://imagemagick.org/Magick++/Enumerations.html#ChannelType) #### imagick.distort_method methods for MagickDistortImage See [here](https://imagemagick.org/api/MagickCore/distort_8h.html#a3f53506aaaafd01ef4d52174edfce258) Color channels See [here](https://imagemagick.org/Magick++/Enumerations.html#ChannelType) ### imagick functions #### `image, error = imagick.open( filepath)` Opens image from given filepath or image definition Example ```lua local img = magick.open("input.jpg") -- open jpg file ``` ****** #### `image, error = imagick.open_blob( data)` Open image from data blob ****** #### `image, error = imagick.open_pseudo( width, height, definition)` Create image from pseudo-image definition. See [here](https://imagemagick.org/script/formats.php#pseudo) ****** ### imagick image functions #### ` img:destroy()` Manually free all allocated for image memory. Use with caution. Never call to any image methods afterwards. ****** #### `width = img:width()` Get image width in pixels ****** #### `height = img:height()` Get image height in pixels ****** #### `count = img:count()` Get number of images inside an image (e.g. frames in GIF or pages in PDF) ****** #### `image = img:clone()` Clone image with all current settings/values ****** #### `status, error = img:write( filename)` Write image to file _This outputs only first frame_ ****** #### `status, error = img:write_all( filename, join)` Write all image frames to file If **join** is **false** this will create sequentaly numbered file for each image frame If **join** is **true** this will create one file with all frames (this demends on image format, works with gif, for example) ****** #### `data, lenght = img:blob()` Return raw image data as string ****** #### `format = img:get_format()` Get image format ("JPEG"/"GIF"/"PNG"/etc.) ****** #### `result, error = img:set_format( format)` Set image format ("JPEG"/"GIF"/"PNG"/etc.) ****** #### `quality = img:get_quality()` Get image compression quality (0-100) ****** #### `status, error = img:set_quality( quality)` Set image compression quality (0-100) ****** #### `gravity = img:get_gravity()` Get current image gravity ****** #### `status, error = img:set_gravity( gravity)` Set image gravity (See imagick.gravity enum) ****** #### `scheme = img:get_interlace()` Get current image interlace scheme ****** #### `status, error = img:set_interlace( scheme)` Set image interlace sheme (See imagick.interlace enum) e.g. for Progressive JPEG set it to JPEGInterlace ****** #### `value = img:get_option( name)` Get imagemagick option for image ****** #### `status, error = img:set_option( name, value)` Set imagemagick option for image ****** #### `value = img:get_artifact( name)` Get imagemagick artifact for image. See [here](https://imagemagick.org/script/command-line-options.php#define) ****** #### `status, error = img:set_artifact( name, value)` Set imagemagick artifact for image ****** #### `color = img:get_bg_color()` Get image background color Returns comma-separated color values. ****** #### `status, error = img:set_bg_color( color)` Set image background color (html hex notation or comma-separated) ****** #### `colorspace = img:get_colorspace()` Get image colorspace (See imagick.colorspace enum) ****** #### `status, error = img:set_colorspace( colorspace)` Set image colorspace (See imagick.colorspace enum) ****** #### `alpha = img:has_alphachannel()` Returns true if image has alpha-channel ****** #### `icc = img:has_icc_profile()` Returns true if image has embedded icc profile ****** #### `data = img:get_icc_profile()` Returns image icc profile as blob ****** #### `status, error = img:set_icc_profile( blob)` Set (and convert image to) image icc profile from blob ****** #### `status, error = img:load_icc_profile( filename)` Set (and convert image to) image icc profile from file ****** #### `status, error = img:set_compose( compose)` Set image composite operator (See imagick.composite_op) ****** #### `status, error = img:set_font( path)` Set font to use in annotate, full path to font file ****** #### `status, error = img:set_font_family( family)` Set font to use in annotate, font family string ****** #### `status, error = img:set_font_size( size)` Set font size to use in annotate ****** #### `status, error = img:set_font_style( style)` Set font style to use in annotate (See imagick.font_style enum) ****** #### `status, error = img:set_font_weight( weight)` Set font weight to use in annotate ****** #### `status, error = img:set_font_align( align)` Set font align to use in annotate (See imagick.font_align enum) ****** #### `status, error = img:annotate( color, text, x, y, angle)` Annotate image ****** #### `status, error = img:set_mask( mask)` Set image mask for compositing operations You can set it to `nil` to reset ****** #### `status, error = img:coalesce()` Coalesce (rebuild) all image frames ****** #### `status, error = img:optimize()` Optimise all image frames ****** #### `status, error = img:deconstruct()` Deconstruct all image frames (MagickDeconstructImages() ) ****** #### `status, error = img:strip()` Strip exif data and profiles from image ****** #### `status, error = img:swirl(degrees)` Apply swirl filter ****** #### `status, error = img:oilpaint( radius)` Apply oilpaint filter ****** #### `status, error = img:rotate(color, angle)` Rotate image on angle filling empty space with color ****** #### `status, error = img:modulate( brightness, saturation, hue)` Modify brightness, saturation, and hue of an image ****** #### `status, error = img:blur( sigma, radius)` Blur image ****** #### `status, error = img:flip()` Creates a vertical mirror image by reflecting the pixels around the central x-axis. ****** #### `status, error = img:flop()` Creates a horizontal mirror image by reflecting the pixels around the central y-axis. ****** #### `status, error = img:transpose()` Creates a vertical mirror image by reflecting the pixels around the central x-axis while rotating them 90-degrees. ****** #### `status, error = img:transverse ()` Creates a horizontal mirror image by reflecting the pixels around the central y-axis while rotating them 270-degrees. ****** #### `status, error = img:sharpen( sigma, radius)` Sharpen image ****** #### `status, error = img:adaptive_blur( sigma, radius)` Blur image adaptively ****** #### `status, error = img:adaptive_sharpen( sigma, radius)` Sharpen image adaptively ****** #### `status, error = img:blur_channel( channel, sigma, radius)` Blur image channel ****** #### `status, error = img:sharpen_channel( channel, sigma, radius)` Sharpen image channel ****** #### `status, error = img:adaptive_blur_channel( channel, sigma, radius)` Blur image channel adaptively ****** #### `status, error = img:adaptive_sharpen_channel( channel, sigma, radius)` Sharpen image channel adaptively ****** #### `status, error = img:gamma( gamma)` Modify image gamma ****** #### `status, error = img:gamma_channel( gamma, channel)` Modify image channel gamma ****** #### `status, error = img:auto_gamma()` Auto-adjust image gamma ****** #### `status, error = img:auto_gamma_channel( channel)` Auto-adjust image channel gamma ****** #### `status, error = img:level( black, white, gamma)` Adjust image levels. Black/white points is 0-100% ****** #### `status, error = img:level_channel( black, white, gamma, channel)` Adjust image levels for channel. Black/white points is 0-100% ****** #### `status, error = img:contrast( sharpen)` Enhances the intensity differences between the lighter and darker elements of the image. Set sharpen to 'true' to increase the image contrast, otherwise the contrast is reduced ****** #### `status, error = img:border( color, width, height)` Surrounds the image with a border of the color ****** #### `status, error = img:colorize( color, opacity)` Blends the fill color with each pixel in the image ****** #### `status, error = img:resize(width, height)` Resize image using current scale filter ****** #### `status, error = img:adaptive_resize(width, height)` Adaptively resize image with data dependent triangulation using current image filter ****** #### `status, error = img:resample(width, height, filter, blur)` Resample image. See [https://imagemagick.org/api/magick-image.php#MagickResampleImage](https://imagemagick.org/api/magick-image.php#MagickResampleImage) ****** #### `status, error = img:scale( width, height)` Fast scale image ****** #### `status, error = img:crop( width, height)` Crop image You can pass additional x,y coordinates, e.g.: `status, error = img:crop( width, height, x, y)` ****** #### `status, error = img:thumbnail( width, height)` Resize image and remove all profiles. ****** #### `status, error = img:composite( src, x, y, compositeop)` Apply one image on top of another at x/y with composite operator compositeop (See imagick.composite_op) ****** #### `status, error = img:composite_channel( src, channel, x, y, compositeop)` Apply one image channel on top of another at x/y with composite operator compositeop (See imagick.composite_op) ****** #### `status, error = img:extent( width, height)` Extent image ****** #### `status, error = img:smart_resize( size)` Smartly resize image. Format is one of: * WxH (Keep aspect-ratio, use higher dimension) * WxH^ (Keep aspect-ratio, use lower dimension (crop)) * WxH! (Ignore aspect-ratio) It uses Mitchell filter for upscaling/downscaling all formats and Lanczos for downscaling JPEG. You should use img:extent after it to really crop or add borders (with `img:get_bg_color()`) to image. ****** #### `status, error = img:set_fill_color( color)` Set DrawingWand fill color ****** #### `status, error = img:set_stroke_color( color)` Set DrawingWand stroke color ****** #### `img:query_metrics( text)` Query font metrics. See https://imagemagick.org/api/magick-wand.php#MagickQueryFontMetrics Returns 13 variables or nil,error ****** #### `img:query_multiline_metrics( text)` Query font metrics. See https://imagemagick.org/api/magick-wand.php#MagickQueryMultilineFontMetrics Returns 13 variables or nil,error ****** #### `status, error = img:distort( method, params, bestfit)` Distorts image. See https://imagemagick.org/api/magick-image.php#MagickDistortImage Example (https://imagemagick.org/Usage/distorts/#arc): ```lua local magick = require "imagick" local img = magick.open("rose.jpg") img:distort(magick.distort_method["ArcDistortion"], { 60, 90 }, false) img:write("out.jpg") ``` ****** #### `status, error = img:threshold( value)` Apply simultaneous black/white threshold to the image. See https://imagemagick.org/api/magick-image.php#MagickThresholdImage See https://imagemagick.org/script/command-line-options.php#threshold `value` is effective between `0` and `0xffff` ```lua local magick = require "imagick" local img = magick.open("rose.jpg") ---Converts percents to value function pct(pct) return 65535 * pct / 100 end img:threshold(pct(95)) img:write("out.jpg") ``` ****** #### `status, error = img:trim( fuzz)` Trim an image. This option removes any edges that are exactly the same color as the corner pixels. Use fuzz to make trim remove edges that are nearly the same color as the corner pixels. See https://imagemagick.org/api/magick-image.php#MagickTrimImage See https://imagemagick.org/script/command-line-options.php#trim `fuzz` is effective between `0` and `0xffff` ```lua local magick = require "imagick" local img = magick.open("rose.jpg") ---Converts percents to value function pct(pct) return 65535 * pct / 100 end img:trim(pct(5)) img:write("out.jpg") ``` ****** ## Examples ### Captcha ```lua local magick = require "imagick" local code ="hello" local i = 0 math.randomseed(os.time()) local r=100+math.random(35) local g=100+math.random(35) local b=100+math.random(35) local img = assert(magick.open_pseudo(150,50, "xc:rgb("..r..","..g..","..b..")")) for c in code:gmatch(".") do local r=150+math.random(105) local g=150+math.random(105) local b=150+math.random(105) img:set_font_size(25+math.random(10)) img:annotate("rgb("..r..","..g..","..b..")", c, (i*20)+10, math.random(50-50)+30, math.random(55)-20) i=i+1 end img:swirl(10) img:oilpaint(1) img:write("captcha.png") ``` ### Simple filters #### Gotham ```lua local ima = require("imagick") local img, err = ima.open("input.jpg") img:modulate(120, 10 ,100) img:colorize("#222b6d", 0.2) img:gamma(0.5) img:contrast(true) img:contrast(true) img:border('black', 20, 20) img:write("out.jpg") ``` #### Lomo ```lua local ima = require("imagick") local img, err = ima.open("input.jpg") img:level_channel(33, 66, 1.0, ima.channel["RedChannel"]) img:level_channel(33, 66, 1.0, ima.channel["GreenChannel"]) crop_x = math.floor(img:width() * 1.5) crop_y = math.floor(img:height() * 1.5) local gradient = ima.open_pseudo(crop_x, crop_y, "radial-gradient:none-black") gradient:set_gravity(ima.gravity['CenterGravity']) gradient:crop(img:width(), img:height()) img:composite(gradient, 0, 0, ima.composite_op['MultiplyCompositeOp']) img:border('black', 20, 20) img:write("out.jpg") ``` ## Authors Epifanov Ivan [Back to TOC](#table-of-contents) ## Copyright and License This module is licensed under the WTFPL license. (See LICENSE)