Nice work.There's a number of bindings floating around currently (another cgo version here, https://github.com/gographics/imagick), and we have our own we use internally for GraphicsMagick.Did you by chance compare the gographics library?
As an aside, the developer on the gographics/imagick library had mentioned writing a Go version of the {Image|Graphics}Magick api. I think that would be great if some of the image library users got together to start work on a GoMagick library. https://groups.google.com/d/msg/golang-nuts/6qVpOGyDuHI/kpjrtX39aHgJ
A first step that I think would be interesting, is cgo bindings to the native image encoders, where you could `import _ "image/jpeg_cgo"` and get faster encode/decode performance with the stdlib.
Thanks! I wasn't aware of any other bindings for IM nor GM. We've been using this internally since August 2012 and there were no public bindings at that time, so we wrote our own. From a quick look at go graphics, it seems they're wrapping the MagickWand library, while we're wrapping MagickCore, so it seems both packages are intended for different use cases.
I think that would be a terrible waste of time and the developer is severely underestimating the effort required. IM or GM are big projects, around 500K lines for IM and I guess GM is in the same ballpark. Furthermore, they rely on other C libraries for some other tasks, like decoding some formats. Porting everything from C to Go would require many many hours and, probably, you'll end up with a slower implementation than using cgo to call to the C libraries. The only benefit would be able to run on environments when using cgo/unsafe is not allowed (like GAE), but I personally have zero interest in those.
We already have written (and thrown away) decoders for png, jpeg and gif, with both encoding and decoding support. We initially wrote them to get better decoding/encoding support (image/gif didn't support encoding at the time, and all image/* packages failed to decode 20-30% of our sample set), but we found that even with libpng/libjpeg/libgif based decoders, Go's image package still sucked. Want to resize an image? Write your own algorithm! Need to work with animated GIFs? Not supported! If you need to do anything barely advanced with images, just forget about the packages in the standard library. You'll eventually hit a wall and will have to rewrite all your image handling code using a real image library.
Hi. I'm the author of Go's standard image library.
On Thu, Oct 31, 2013 at 3:29 AM, Alberto García Hierro
<alb...@garciahierro.com> wrote:
> In our performance tests, we've found that GM is around 120x faster than the
> image related modules in the standard library when it comes to
> decoding/resizing/cropping/encoding images.
120x surprises me. Do you have some example Go code and test data that
shows this?
One thing is that newcomers to Go's standard library often use the
generic At and Set methods in their inner loops, which are the easiest
to use but slower, and definitely not how I would e.g. do resizing or
cropping. For example,
https://groups.google.com/forum/#!topic/golang-nuts/f0X0I_JZP0I
describes a 3x speed-up by using the Pix field directly.
fiam@ubuntu:~/gocode/src/magick$ go test -v -tags gm -run=TestDecode$ -bench=ResizePng
=== RUN TestDecode
--- PASS: TestDecode (0.25 seconds)
magick_test.go:90: Using backend GraphicsMagick
BenchmarkResizePng 20 72172794 ns/op
BenchmarkResizePngNative 1 9352362699 ns/op
On Thu, Oct 31, 2013 at 5:32 AM, Alberto García Hierro
<alb...@garciahierro.com> wrote:
> The only benefit would be able to run on environments when using
> cgo/unsafe is not allowed (like GAE), but I personally have zero interest in
> those.
Another benefit is that decoding untrusted, third party images is far
less likely to result in remote code execution through buffer
overflows, as Go is a memory-safe language, but I don't know how
important that is to you.
> all image/* packages failed to decode 20-30% of our sample set),
20-30% also sounds surprisingly large to me. Can you send me some of
these failed images (off-list)? How many of these are 'optimized
GIFs'?
I looked at the 7 image files in
https://github.com/rainycape/magick/tree/master/test_data, and Go's
decoders only failed on optimized.gif, in the LZW code, and I note
that you said that GraphicsMagick also fails to decode this.
> Want to resize an image? Write your own algorithm!
There are many different resizing algorithms and approaches. I would
imagine that pure Go image resizing can and should be done by a "go
get"table third party library. Not everything has to be in the
standard library.
> Need to work with animated GIFs? Not supported!
Animated GIFs are supported, via gif.DecodeAll. It's true that
image.Decode will only give you the first frame, but the image
package's format.go is trivial to fork if you really need a catch-all
decoder that can give you Image or *GIF (or []Image).
At the end of the day, though, if binding ImageMagick works for you,
then don't let me stop you. :-)
> Want to resize an image? Write your own algorithm!
There are many different resizing algorithms and approaches. I would
imagine that pure Go image resizing can and should be done by a "go
get"table third party library. Not everything has to be in the
standard library.I totally agree, resizing algorithms should be pluggable. However, I think the standard library should provide a basic framework for them, so users could write only the code for the interpolation.e.g.type Interpolator interface... or type Interpolator func... for better performancefunc Resize(im Image, width, height int, inter Interpolator) (Image, error)