Code Monkey home page Code Monkey logo

graphicsmagick's Introduction

GraphicsMagick

A simple Lua wrapper to GraphicsMagick.

Only tested on Mac OSX, with GraphicsMagick installed via Homebrew.

gm.convert

This is just a binding to the command line convert utility (images are not loaded into Lua's memory). Examples:

gm = require 'graphicsmagick'
gm.convert{
   input = '/path/to/image.png',
   output = '/path/to/image.jpg',
   size = '128x128',
   quality = 95,
   verbose = true
}

gm.info

Similarly, gm.info(file) is a simple binding to the command line utility. It's handy to extra the geometry of an image, as well as its exif metadata. On top of it, if geolocation is found, the GPS location is nicely formatted.

gm = require 'graphicsmagick'
info = gm.info('some.jpeg')
print(info)
{
   width : 1024
   height : 768
   date : 2013:01:01 00:00:01
   location :
     {
       longitude : W80.13
       latitude : N25.79
     }
   format : JPEG
   exif :
     {
        Make : Apple
        FocalLength : 413/100
        ...
     }
}

gm.Image

This is a full C interface to GraphicsMagick's Wand API. We expose one Class: the Image class, which allows loading and saving images, transforming them, and importing/exporting them from/to torch Tensors.

Load library:

gm = require 'graphicsmagick'

First, we provide two high-level functions to load/save directly into/form tensors:

img = gm.load('/path/to/image.png' [, type])    -- type = 'float' (default) | 'double' | 'byte'
gm.save('/path/to/image.jpg' [,quality])        -- quality = 0 to 100 (for jpegs only)

The following provide a more controlled flow for loading/saving jpegs.

Create an image, from a file:

image = gm.Image('/path/to/image.png')
-- or
image = gm.Image()
image:load('/path/to/image.png')

Create an image, from a file, with a hint about the max size to be used:

image:load('/path/to/image.png', width [, height])

-- this tells the image loader that we won't need larger images than
-- what's specified. This can speedup loading by factors of 5 to 10.

Save an image to disk:

image:save('filename.ext')

-- where:
-- ext must be a know image format (jpg, JPEG, PNG, ...)
-- (GraphicsMagick supports tons of them)

Create an image, from a Tensor:

image = gm.Image(tensor,colorSpace,dimensions)
-- or
image = gm.Image()
image:load(tensor,colorSpace,dimensions)

-- where:
-- colorSpace is: a string made of these characters: R,G,B,A,C,Y,M,K,I
--                (for example: 'RGB', 'RGBA', 'I', or 'BGRA', ...)
--                R: red, G: green, ... I: intensity
--
-- dimensions is: a string made of these characters: D,H,W
--                (for example: 'DHW' or 'HWD')
--                D: depth, H: height, W: width

Export an image to a Tensor:

image = gm.Image('path.jpg')
image:toTensor(type,colorSpace,dimensions)

-- where:
-- type : 'float', 'double', or 'byte'
-- colorSpace : same as above
-- dimensions : same as above

When exporting Tensors, we can specify the color space:

lab = image:toTensor('float', 'LAB')
-- equivalent to:
image:colorspace('LAB')
lab = image:toTensor('float')

-- color spaces available, for now:
-- 'LAB', 'HSL', 'HWB' and 'YUV'

Images can also be read/written from/to Lua strings, or binary blobs. This is convenient for in memory manipulation (e.g. when downloading images from the web, no need to write it to disk):

blob,size = image:toBlob()
image:fromBlob(blob,size)

str = image:toString()
image:fromString(str)

In this library, we use a single function to read/write parameters (instead of the more classical get/set).

Here's an example of a resize:

-- get dimensions:
width,height = image:size()

-- resize:
image:size(512,384)

-- resize by only imposing the largest dimension:
image:size(512)

-- resize by imposing the smallest dimension:
image:size(nil,512)

Some basic transformations:

-- flip or flop an image:
image:flip()
image:flop()

Sharpen:

-- Sharpens the image whith radius=0, sigma=0.6
image:sharpen(0, 0.6)

Show an image (this makes use of Tensors, and Torch's Qt backend):

image:show()

One cool thing about this library is that all the functions can be cascaded. Here's an example:

-- Open, transform and save back:
gm.Image('input.jpg'):flip():size(128):save('thumb.jpg')

graphicsmagick's People

Contributors

btnc avatar clementfarabet avatar gdesjardins avatar jucor avatar nagadomi avatar soumith avatar zhka avatar zywj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

graphicsmagick's Issues

cannot convert 'const char *' to 'void *'

in Image.lua

-- Description:
function Image:info()
   -- Get information
   local str = ffi.gc(clib.MagickDescribeImage(self.wand), ffi.C.free)
   return ffi.string(str)
end

clib.MagickDescribeImage(self.wand) returns const char * and it can't be freed by ffi.C.free
get err: cannot convert 'const char *' to 'void *'
see here MagickDescribeImage()

MagickSetCompressionQuality Assertion when resize image

local gm = require("graphicsmagick")
local image = gm.Image("world.png")
local w,h = image:size()
image:size(w/2,h/2)
image.save("w.png")

got this error

luajit: wand/magick_wand.c:7535: MagickSetCompressionQuality: Assertion `wand != (MagickWand *) ((void *)0)' failed.
Magick: abort due to signal 6 (SIGABRT) "Abort

How to fix this?

graphicsmagick breaks torch matrix multiplication

Sounds strange first but I have this phenomena on three different Ubuntu 14.04.3 LTS machines and it is perfectly reproductible on my side.

As soon as I load the graphicsmagick module torch matrix multiplications of larger tensors end in an endlessloop with 100% CPU:

torch.ones(100, 100) * torch.ones(100, 100) -- no problem
require 'graphicsmagick'
torch.ones(10, 10) * torch.ones(10, 10) -- no problem
torch.ones(100, 100) * torch.ones(100, 100) -- never returns [!]

Smaller tensor-multiplications (e.g. 10x10) interestingly even work after the require 'graphicsmagick' statement.

Could somebody please check whether this effect only occurs on Ubuntu machines?

Error when trying to read an image

I'm getting the following exception when trying to run /test/loadsave.lua:

*** Error in `/usr/local/bin/luajit': double free or corruption (!prev): 0x0000000001034db0 ***

I'm running on:
Ubuntu 14.04.1
LuaJIT 2.0.3
GCC 4.9.2

Any ideas?

nil global value 'dok' when gm.convert is called

called by

gm.convert{ input = imgPath[i], output = imgPath[i], size = tostring( opt.height..'x'..opt.width), verbose = false }

the imgPath is a string list, and opt.height and opt.width are float number.

Error messages:

/usr/local/bin/luajit: /usr/local/share/lua/5.1/graphicsmagick/convert.lua:14: attempt to index global 'dok' (a nil value)
stack traceback:
    /usr/local/share/lua/5.1/graphicsmagick/convert.lua:14: in function 'convert'

Maybe require dok is needed here?

Setting the image index before any transforming process.

At the end of method MagickReadImage, MagickReadImageBlob and MagickReadImageFile, the wand->image was pointed to the last frame in the image list. For multi-frame image, the image index should be set to 0 (first frame) before any transforming process.

Invoke MagickSetImageIndex after reading image, e.g.

clib.MagickReadImageBlob(self.wand, ffi.cast('const void *', blob), size)
clib.MagickSetImageIndex(self.wand, 0)

or add new method:

-- Setting the image index:
function Image:setImageIndex(i)
    clib.MagickSetImageIndex(self.wand, i or 0)
end
...
image:setImageIndex(0)
image:size(120, 120)

Drawing text on an image ?

Hi Clément

I don't see any wrapper for the GM possibilities to draw text over images, for example DrawAnnotation() described in GraphicMagick's API Any idea how hard that would be to implement, please?
Thanks,

Julien

libGraphicsMagickWand.so: undefined symbol: InitializeMagick

centos 7 GraphicsMagick version is 1.3.25
GraphicsMagick 1.3.25 2016-09-05 Q8 http://www.GraphicsMagick.org/
Where commands include:
batch - issue multiple commands in interactive or batch mode
benchmark - benchmark one of the other commands
compare - compare two images
composite - composite images together
conjure - execute a Magick Scripting Language (MSL) XML script
convert - convert an image or sequence of images
help - obtain usage message for named command
identify - describe an image or image sequence
mogrify - transform an image or sequence of images
montage - create a composite image (in a grid) from separate images
time - time one of the other commands
version - obtain release version

use luarocks install graphicsmagick

torch
th>require "graphicsmagick"
error :
../torch/install/share/lua/5.1/trepl/init.lua:389: ../torch/install/share/lua/5.1/trepl/init.lua:389: ...enp/torch/install/share/lua/5.1/graphicsmagick/Image.lua:335: /usr/local/lib/libGraphicsMagickWand.so: undefined symbol: InitializeMagick
stack traceback:
[C]: in function 'error'
/home/chenp/torch/install/share/lua/5.1/trepl/init.lua:389: in function 'require'
[string "_RESULT={require "graphicsmagick"}"]:1: in main chunk
[C]: in function 'xpcall'
/home/chenp/torch/install/share/lua/5.1/trepl/init.lua:661: in function 'repl'
...henp/torch/install/lib/luarocks/rocks/trepl/scm-1/bin/th:204: in main chunk
[C]: at 0x004064f0

in openresty lua file local gm = require("graphicsmagick")
error:
lua entry thread aborted: runtime error: ...enp/torch/install/share/lua/5.1/graphicsmagick/Image.lua:335: /usr/local/lib/libGraphicsMagickWand.so: undefined symbol: InitializeMagick

in centos 6 this is ok,and in centos6 the gm version is 1.3.24

Need help for loading tiff images with this lib

Image used in my program is tiff file.
When it is loaded in torch, the gm.info shows the image is 256x256 not 256x256x3, however, when the same image is loaded into MATLAB, the ans array is 256x256x3 unit8.
What should I do to change the loaded result from 256x256 to 256x256x3?

Thx~

documentation on pixel access

what is the syntax for getting the value of a pixel?

I have loaded an image and have tried:

width, length = myimage:size() --this works

but there does not appear to be a method in Image.lua that gives pixel access, does one need to be written? something like, Image:get_pixel(x,y) that returns a value and/or Image:get_pixels(x,y,w,h) that returns a table of values indexed by column, row.

or can MagickGetImagePixels be used?

GIF处理

local gm = require 'graphicsmagick'
local image = gm.Image("/data/images/testgif.gif")
image:save("/data/images/testgif2.gif")

执行上面代码后,GIT动画变成静态图片了? 怎么破

Quality and ToBlob

Is there an easy way to compress before sending toBlob?

I see how to do it with save, but I would have to load, save and reload.

Can we add:

-- Set quality:
   quality = quality or 85
   clib.MagickSetCompressionQuality(self.wand, quality) 

in the function toBlob? I am not sure if it will do the trick though.

attempt to redefine 'UndefinedFilter' at line 41

any idea what this indicates?

Failed to load and run script from 
ERROR[main]: .../.minetest/mods/realterrain/init.lua:
ERROR[main]: .../.minetest/mods/realterrain/graphicsmagick/Image.lua:295: attempt to redefine 'UndefinedFilter' at line 41
ERROR[main]: stack traceback:
ERROR[main]:    [C]: in function 'cdef'
ERROR[main]:    .../.minetest/mods/realterrain/graphicsmagick/Image.lua:295: in main chunk
ERROR[main]:    [C]: in function 'require'
ERROR[main]:    .../.minetest/mods/realterrain/graphicsmagick/init.lua:2: in main chunk
ERROR[main]:    [C]: in function 'require'
ERROR[main]:    ....minetest/mods/realterrain/init.lua:32: in main chunk

Memory leak problem in function Image:toBlob()

In function Image:toBlob() :

local blob = clib.MagickWriteImageBlob(self.wand, sizep)

the blob is a detached one from the original image->blob, so it must be freed by hand or change the above line with:

local blob = ffi.gc(clib.MagickWriteImageBlob(self.wand, sizep), ffi.C.free)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.