-
Notifications
You must be signed in to change notification settings - Fork 21
/
magick_wand.go
1879 lines (1662 loc) · 69.2 KB
/
magick_wand.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
package gmagick
/*
#include <unistd.h>
#include <wand/wand_api.h>
*/
import "C"
import (
"errors"
"os"
"runtime"
"sync"
"sync/atomic"
"syscall"
"unsafe"
)
// This struct represents the MagickWand C API of GraphicsMagick
type MagickWand struct {
mw *C.MagickWand
init sync.Once
}
func newMagickWand(cmw *C.MagickWand) *MagickWand {
mw := &MagickWand{mw: cmw}
runtime.SetFinalizer(mw, Destroy)
mw.IncreaseCount()
return mw
}
// Returns a wand required for all other methods in the API. A fatal exception is thrown if there is not enough memory to allocate the wand.
func NewMagickWand() *MagickWand {
return newMagickWand(C.NewMagickWand())
}
// Makes an exact copy of the MagickWand object
func (mw *MagickWand) Clone() *MagickWand {
return newMagickWand(C.CloneMagickWand(mw.mw))
}
// Deallocates memory associated with an MagickWand
func (mw *MagickWand) Destroy() {
if mw.mw == nil {
return
}
mw.init.Do(func() {
C.DestroyMagickWand(mw.mw)
mw.mw = nil
mw.DecreaseCount()
})
}
// Increase MagickWand ref counter and set according "can`t be terminated status"
func (mw *MagickWand) IncreaseCount() {
atomic.AddInt64(&magickWandCounter, int64(1))
unsetCanTerminate()
}
// Decrease MagickWand ref counter and set according "can be terminated status"
func (mw *MagickWand) DecreaseCount() {
atomic.AddInt64(&magickWandCounter, int64(-1))
setCanTerminate()
}
// Returns the position of the iterator in the image list
func (mw *MagickWand) GetImageIndex() uint {
return uint(C.MagickGetImageIndex(mw.mw))
}
// Selects an individual threshold for each pixel based on the range of
// intensity values in its local neighborhood. This allows for thresholding
// of an image whose global intensity histogram doesn't contain distinctive
// peaks.
func (mw *MagickWand) AdaptiveThresholdImage(width, height uint, offset int) error {
ok := C.MagickAdaptiveThresholdImage(mw.mw, C.ulong(width), C.ulong(height), C.long(offset))
return mw.getLastErrorIfFailed(ok)
}
// Adds a clone of the images from the second wand and inserts them into the
// first wand. Use SetLastIterator(), to append new images into an existing
// wand, current image will be set to last image so later adds with also be
// appened to end of wand. Use SetFirstIterator() to prepend new images into
// wand, any more images added will also be prepended before other images in
// the wand. However the order of a list of new images will not change.
// Otherwise the new images will be inserted just after the current image, and
// any later image will also be added after this current image but before the
// previously added images. Caution is advised when multiple image adds are
// inserted into the middle of the wand image list.
func (mw *MagickWand) AddImage(wand *MagickWand) error {
ok := C.MagickAddImage(mw.mw, wand.mw)
return mw.getLastErrorIfFailed(ok)
}
// Adds random noise to the image
func (mw *MagickWand) AddNoiseImage(noiseType NoiseType) error {
ok := C.MagickAddNoiseImage(mw.mw, C.NoiseType(noiseType))
return mw.getLastErrorIfFailed(ok)
}
// Transforms an image as dictaded by the affine matrix of the drawing wand
func (mw *MagickWand) AffineTransformImage(drawingWand *DrawingWand) error {
ok := C.MagickAffineTransformImage(mw.mw, drawingWand.dw)
return mw.getLastErrorIfFailed(ok)
}
// Animates an image or image sequence
func (mw *MagickWand) AnimateImages(server string) error {
csserver := C.CString(server)
defer C.free(unsafe.Pointer(csserver))
ok := C.MagickAnimateImages(mw.mw, csserver)
return mw.getLastErrorIfFailed(ok)
}
// Annotates an image with text
//
// x: ordinate to left of text
//
// y: ordinate to text baseline
//
// angle: rotate text relative to this angle
//
func (mw *MagickWand) AnnotateImage(drawingWand *DrawingWand, x, y, angle float64, text string) error {
cstext := C.CString(text)
defer C.free(unsafe.Pointer(cstext))
ok := C.MagickAnnotateImage(mw.mw, drawingWand.dw, C.double(x), C.double(y), C.double(angle), cstext)
return mw.getLastErrorIfFailed(ok)
}
// Append the images in a wand from the current image onwards, creating a new
// wand with the single image result. This is affected by the gravity and
// background setting of the first image. Typically you would call either
// ResetIterator() or SetFirstImage() before calling this function to ensure
// that all the images in the wand's image list will be appended together.
// By default, images are stacked left-to-right. Set topToBottom to true to
// stack them top-to-bottom.
func (mw *MagickWand) AppendImages(topToBottom bool) *MagickWand {
return newMagickWand(C.MagickAppendImages(mw.mw, b2i(topToBottom)))
}
// Average a set of images
func (mw *MagickWand) AverageImages() *MagickWand {
return newMagickWand(C.MagickAverageImages(mw.mw))
}
// This is like ThresholdImage() but forces all pixels below the threshold
// into black while leaving all pixels above the threshold unchanged.
func (mw *MagickWand) BlackThresholdImage(threshold *PixelWand) error {
ok := C.MagickBlackThresholdImage(mw.mw, threshold.pw)
return mw.getLastErrorIfFailed(ok)
}
// Blurs an image. We convolve the image with a gaussian operator of the
// given radius and standard deviation (sigma). For reasonable results, the
// radius should be larger than sigma. Use a radius of 0 and BlurImage()
// selects a suitable radius for you.
//
// radius: the radius of the, in pixels, not counting the center pixel.
//
// sigma: the standard deviation of the, in pixels
//
func (mw *MagickWand) BlurImage(radius, sigma float64) error {
ok := C.MagickBlurImage(mw.mw, C.double(radius), C.double(sigma))
return mw.getLastErrorIfFailed(ok)
}
// Surrounds the image with a border of the color defined by the bordercolor
// pixel wand.
func (mw *MagickWand) BorderImage(borderColor *PixelWand, width, height uint) error {
ok := C.MagickBorderImage(mw.mw, borderColor.pw, C.ulong(width), C.ulong(height))
return mw.getLastErrorIfFailed(ok)
}
// Simulates a charcoal drawing
//
// radius: the radius of the Gaussian, in pixels, not counting the center pixel
//
// sigma: the standard deviation of the Gaussian, in pixels
//
func (mw *MagickWand) CharcoalImage(radius, sigma float64) error {
ok := C.MagickCharcoalImage(mw.mw, C.double(radius), C.double(sigma))
return mw.getLastErrorIfFailed(ok)
}
// Removes a region of an image and collapses the image to occupy the removed
// portion.
//
// width, height: the region width and height
//
// x, y: the region x and y offsets
//
func (mw *MagickWand) ChopImage(width, height uint, x, y int) error {
ok := C.MagickChopImage(mw.mw, C.ulong(width), C.ulong(height), C.long(x), C.long(y))
return mw.getLastErrorIfFailed(ok)
}
// Clips along the first path from the 8BIM profile, if present
func (mw *MagickWand) ClipImage() error {
ok := C.MagickClipImage(mw.mw)
return mw.getLastErrorIfFailed(ok)
}
// Composites a set of images while respecting any page offsets and disposal
// methods. GIF, MIFF, and MNG animation sequences typically start with an
// image background and each subsequent image varies in size and offset.
// CoalesceImages() returns a new sequence where each image in the sequence
// is the same size as the first and composited with the next image in the
// sequence.
func (mw *MagickWand) CoalesceImages() *MagickWand {
return newMagickWand(C.MagickCoalesceImages(mw.mw))
}
// Blends the fill color with each pixel in the image
func (mw *MagickWand) ColorizeImage(colorize, opacity *PixelWand) error {
ok := C.MagickColorizeImage(mw.mw, colorize.pw, opacity.pw)
return mw.getLastErrorIfFailed(ok)
}
// Adds a comment to your image
func (mw *MagickWand) CommentImage(comment string) error {
cscomment := C.CString(comment)
defer C.free(unsafe.Pointer(cscomment))
ok := C.MagickCommentImage(mw.mw, cscomment)
return mw.getLastErrorIfFailed(ok)
}
// Compares one or more image channels of an image to a reconstructed image
// and returns the difference image
func (mw *MagickWand) CompareImageChannels(reference *MagickWand, channel ChannelType, metric MetricType) (wand *MagickWand, distortion float64) {
cmw := C.MagickCompareImageChannels(mw.mw, reference.mw, C.ChannelType(channel), C.MetricType(metric), (*C.double)(&distortion))
wand = newMagickWand(cmw)
return
}
// CompareImages() compares an image to a reconstructed image and returns the
// specified difference image. Returns the new MagickWand and the computed
// distortion between the images
func (mw *MagickWand) CompareImages(reference *MagickWand, metric MetricType) (wand *MagickWand, distortion float64) {
cmw := C.MagickCompareImages(mw.mw, reference.mw, C.MetricType(metric), (*C.double)(&distortion))
wand = newMagickWand(cmw)
return
}
// Composite one image onto another at the specified offset.
// source: The magick wand holding source image.
// compose: This operator affects how the composite is applied to the image.
// The default is Over.
//
// x: the column offset of the composited image.
//
// y: the row offset of the composited image.
//
func (mw *MagickWand) CompositeImage(source *MagickWand, compose CompositeOperator, x, y int) error {
ok := C.MagickCompositeImage(mw.mw, source.mw, C.CompositeOperator(compose), C.long(x), C.long(y))
return mw.getLastErrorIfFailed(ok)
}
// Enhances the intensity differences between the lighter and darker elements
// of the image. Set sharpen to a value other than 0 to increase the image
// contrast otherwise the contrast is reduced.
//
// sharpen: increase or decrease image contrast
//
func (mw *MagickWand) ContrastImage(sharpen bool) error {
ok := C.MagickContrastImage(mw.mw, b2i(sharpen))
return mw.getLastErrorIfFailed(ok)
}
// Applies a custom convolution kernel to the image.
//
// order: the number of cols and rows in the filter kernel
//
// kernel: an array of doubles, representing the convolution kernel
//
func (mw *MagickWand) ConvolveImage(order uint, kernel []float64) error {
ok := C.MagickConvolveImage(mw.mw, C.ulong(order), (*C.double)(&kernel[0]))
return mw.getLastErrorIfFailed(ok)
}
// Extracts a region of the image
func (mw *MagickWand) CropImage(width, height uint, x, y int) error {
ok := C.MagickCropImage(mw.mw, C.ulong(width), C.ulong(height), C.long(x), C.long(y))
return mw.getLastErrorIfFailed(ok)
}
// Displaces an Image's colormap by a given number of positions. If you cycle
// the colormap a number of times you can produce a psychodelic effect.
func (mw *MagickWand) CycleColormapImage(displace int) error {
ok := C.MagickCycleColormapImage(mw.mw, C.long(displace))
return mw.getLastErrorIfFailed(ok)
}
// Compares each image with the next in a sequence and returns the maximum
// bouding region of any pixel differences it discovers.
func (mw *MagickWand) DeconstructImages() *MagickWand {
return newMagickWand(C.MagickDeconstructImages(mw.mw))
}
// Describes an image by formatting its attributes
// to an allocated string which must be freed by the user. Attributes
// include the image width, height, size, and others. The string is
// similar to the output of 'identify -verbose'.
func (mw *MagickWand) DescribeImage() string {
description := C.MagickDescribeImage(mw.mw)
defer C.MagickRelinquishMemory(unsafe.Pointer(description))
return C.GoString(description)
}
// Reduces the speckle noise in an image while perserving the edges of the
// original image.
func (mw *MagickWand) DespeckleImage() error {
ok := C.MagickDespeckleImage(mw.mw)
return mw.getLastErrorIfFailed(ok)
}
// Displays and image
func (mw *MagickWand) DisplayImage(server string) error {
cstring := C.CString(server)
defer C.free(unsafe.Pointer(cstring))
ok := C.MagickDisplayImage(mw.mw, cstring)
return mw.getLastErrorIfFailed(ok)
}
// Displays and image or image sequence
func (mw *MagickWand) DisplayImages(server string) error {
cstring := C.CString(server)
defer C.free(unsafe.Pointer(cstring))
ok := C.MagickDisplayImages(mw.mw, cstring)
return mw.getLastErrorIfFailed(ok)
}
// Draws vectors on the image as described by DrawingWand.
func (mw *MagickWand) DrawImage(dw *DrawingWand) error {
ok := C.MagickDrawImage(mw.mw, dw.dw)
return mw.getLastErrorIfFailed(ok)
}
// Enhance edges within the image with a convolution filter of the given
// radius. Use a radius of 0 and Edge() selects a suitable radius for you.
//
// radius: the radius of the pixel neighborhood
//
func (mw *MagickWand) EdgeImage(radius float64) error {
ok := C.MagickEdgeImage(mw.mw, C.double(radius))
return mw.getLastErrorIfFailed(ok)
}
// Returns a grayscale image with a three-dimensional effect. We convolve the
// image with a Gaussian operator of the given radius and standard deviation
// (sigma). For reasonable results, radius should be larger than sigma. Use a
// radius of 0 and Emboss() selects a suitable radius for you.
//
// radius: the radius of the Gaussian, in pixels, not counting the center pixel
//
// sigma: the standard deviation of the Gaussian, in pixels
//
func (mw *MagickWand) EmbossImage(radius, sigma float64) error {
ok := C.MagickEmbossImage(mw.mw, C.double(radius), C.double(sigma))
return mw.getLastErrorIfFailed(ok)
}
// Applies a digital filter that improves the quality of a noisy image
func (mw *MagickWand) EnhanceImage() error {
ok := C.MagickEnhanceImage(mw.mw)
return mw.getLastErrorIfFailed(ok)
}
// Equalizes the image histogram.
func (mw *MagickWand) EqualizeImage() error {
ok := C.MagickEqualizeImage(mw.mw)
return mw.getLastErrorIfFailed(ok)
}
// Extends the image as defined by the geometry, gravitt, and wand background
// color. Set the (x,y) offset of the geometry to move the original wand
// relative to the extended wand.
//
// width: the region width.
//
// height: the region height.
//
// x: the region x offset.
//
// y: the region y offset.
//
func (mw *MagickWand) ExtentImage(width, height uint, x, y int) error {
ok := C.MagickExtentImage(mw.mw, C.size_t(width), C.size_t(height), C.ssize_t(x), C.ssize_t(y))
return mw.getLastErrorIfFailed(ok)
}
// Creates a vertical mirror image by reflecting the pixels around the central
// x-axis.
func (mw *MagickWand) FlipImage() error {
ok := C.MagickFlipImage(mw.mw)
return mw.getLastErrorIfFailed(ok)
}
// Creates a horizontal mirror image by reflecting the pixels around the
// central y-axis.
func (mw *MagickWand) FlopImage() error {
ok := C.MagickFlopImage(mw.mw)
return mw.getLastErrorIfFailed(ok)
}
// Adds a simulated three-dimensional border around the image. The width and
// height specify the border width of the vertical and horizontal sides of the
// frame. The inner and outer bevels indicate the width of the inner and outer
// shadows of the frame.
//
// matteColor: the frame color pixel wand.
//
// width: the border width.
//
// height: the border height.
//
// innerBevel: the inner bevel width.
//
// outerBevel: the outer bevel width.
//
func (mw *MagickWand) FrameImage(matteColor *PixelWand, width, height uint, innerBevel, outerBevel int) error {
ok := C.MagickFrameImage(mw.mw, matteColor.pw, C.ulong(width), C.ulong(height), C.long(innerBevel), C.long(outerBevel))
return mw.getLastErrorIfFailed(ok)
}
// Evaluate expression for each pixel in the image.
func (mw *MagickWand) FxImage(expression string) (fxmw *MagickWand, err error) {
csexpression := C.CString(expression)
defer C.free(unsafe.Pointer(csexpression))
fxmw = newMagickWand(C.MagickFxImage(mw.mw, csexpression))
err = mw.GetLastError()
return
}
// Evaluate expression for each pixel in the image's channel
func (mw *MagickWand) FxImageChannel(channel ChannelType, expression string) *MagickWand {
csexpression := C.CString(expression)
defer C.free(unsafe.Pointer(csexpression))
return newMagickWand(C.MagickFxImageChannel(mw.mw, C.ChannelType(channel), csexpression))
}
// Gamma-corrects an image. The same image viewed on different devices will
// have perceptual differences in the way the image's intensities are
// represented on the screen. Specify individual gamma levels for the red,
// green, and blue channels, or adjust all three with the gamma parameter.
// Values typically range from 0.8 to 2.3. You can also reduce the influence
// of a particular channel with a gamma value of 0.
func (mw *MagickWand) GammaImage(gamma float64) error {
ok := C.MagickGammaImage(mw.mw, C.double(gamma))
return mw.getLastErrorIfFailed(ok)
}
// Gamma-corrects an image's channel. The same image viewed on different
// devices will have perceptual differences in the way the image's intensities
// are represented on the screen. Specify individual gamma levels for the red,
// green, and blue channels, or adjust all three with the gamma parameter.
// Values typically range from 0.8 to 2.3. You can also reduce the influence
// of a particular channel with a gamma value of 0.
func (mw *MagickWand) GammaImageChannel(channel ChannelType, gamma float64) error {
ok := C.MagickGammaImageChannel(mw.mw, C.ChannelType(channel), C.double(gamma))
return mw.getLastErrorIfFailed(ok)
}
// Returns the filename associated with an image sequence.
func (mw *MagickWand) GetFilename() string {
p := C.MagickGetFilename(mw.mw)
defer C.MagickRelinquishMemory(unsafe.Pointer(p))
return C.GoString(p)
}
// Returns an image attribute as a string
func (mw *MagickWand) GetImageAttribute(attributeName string) string {
n := C.CString(attributeName)
defer C.free(unsafe.Pointer(n))
p := C.MagickGetImageAttribute(mw.mw, n)
defer C.MagickRelinquishMemory(unsafe.Pointer(p))
return C.GoString(p)
}
// Returns the image background color.
func (mw *MagickWand) GetImageBackgroundColor() (bgColor *PixelWand, err error) {
cbgcolor := NewPixelWand()
ok := C.MagickGetImageBackgroundColor(mw.mw, cbgcolor.pw)
return cbgcolor, mw.getLastErrorIfFailed(ok)
}
// Returns the chromaticy blue primary point for the image.
//
// x: the chromaticity blue primary x-point.
//
// y: the chromaticity blue primary y-point.
//
func (mw *MagickWand) GetImageBluePrimary() (x, y float64, err error) {
ok := C.MagickGetImageBluePrimary(mw.mw, (*C.double)(&x), (*C.double)(&y))
err = mw.getLastErrorIfFailed(ok)
return
}
// Returns the image border color.
func (mw *MagickWand) GetImageBorderColor() (borderColor *PixelWand, err error) {
cbc := NewPixelWand()
ok := C.MagickGetImageBorderColor(mw.mw, cbc.pw)
return cbc, mw.getLastErrorIfFailed(ok)
}
// Gets the depth for one or more image channels.
func (mw *MagickWand) GetImageChannelDepth(channel ChannelType) uint {
return uint(C.MagickGetImageChannelDepth(mw.mw, C.ChannelType(channel)))
}
// Gets the mean and standard deviation of one or more image channels.
func (mw *MagickWand) GetImageChannelMean(channel ChannelType) (mean, stdev float64, err error) {
ok := C.MagickGetImageChannelMean(mw.mw, C.ChannelType(channel), (*C.double)(&mean), (*C.double)(&stdev))
err = mw.getLastErrorIfFailed(ok)
return
}
// Returns the color of the specified colormap index.
func (mw *MagickWand) GetImageColormapColor(index uint) (color *PixelWand, err error) {
cpw := NewPixelWand()
ok := C.MagickGetImageColormapColor(mw.mw, C.ulong(index), cpw.pw)
return cpw, mw.getLastErrorIfFailed(ok)
}
// Gets the number of unique colors in the image.
func (mw *MagickWand) GetImageColors() uint {
return uint(C.MagickGetImageColors(mw.mw))
}
// Gets the image colorspace.
func (mw *MagickWand) GetImageColorspace() ColorspaceType {
return ColorspaceType(C.MagickGetImageColorspace(mw.mw))
}
// Returns the composite operator associated with the image.
func (mw *MagickWand) GetImageCompose() CompositeOperator {
return CompositeOperator(C.MagickGetImageCompose(mw.mw))
}
// Gets the image compression.
func (mw *MagickWand) GetImageCompression() CompressionType {
return CompressionType(C.MagickGetImageCompression(mw.mw))
}
// Gets the image delay.
func (mw *MagickWand) GetImageDelay() uint {
return uint(C.MagickGetImageDelay(mw.mw))
}
// Gets the image depth.
func (mw *MagickWand) GetImageDepth() uint {
return uint(C.MagickGetImageDepth(mw.mw))
}
// Gets the image disposal method.
func (mw *MagickWand) GetImageDispose() DisposeType {
return DisposeType(C.MagickGetImageDispose(mw.mw))
}
// Returns the filename of a particular image in a sequence.
func (mw *MagickWand) GetImageFilename() string {
p := C.MagickGetImageFilename(mw.mw)
defer C.MagickRelinquishMemory(unsafe.Pointer(p))
return C.GoString(p)
}
// Returns the format of a particular image in a sequence.
func (mw *MagickWand) GetImageFormat() string {
p := C.MagickGetImageFormat(mw.mw)
defer C.MagickRelinquishMemory(unsafe.Pointer(p))
return C.GoString(p)
}
// Gets the image fuzz.
func (mw *MagickWand) GetImageFuzz() float64 {
return float64(C.MagickGetImageFuzz(mw.mw))
}
// Gets the image gamma.
func (mw *MagickWand) GetImageGamma() float64 {
return float64(C.MagickGetImageGamma(mw.mw))
}
// Gets the image geometry string. NULL is
// returned if the image does not contain a geometry string.
func (mw *MagickWand) MagickGetImageGeometry() string {
p := C.MagickGetImageGeometry(mw.mw)
if p != nil {
defer C.MagickRelinquishMemory(unsafe.Pointer(p))
return C.GoString(p)
}
return ""
}
// Gets the image gravity.
func (mw *MagickWand) GetImageGravity() GravityType {
return GravityType(C.MagickGetImageGravity(mw.mw))
}
// Gets the image at the current image index.
func (mw *MagickWand) GetImage() *MagickWand {
return newMagickWand(C.MagickGetImage(mw.mw))
}
// Returns the chromaticy green primary point.
//
// x: the chromaticity green primary x-point.
//
// y: the chromaticity green primary y-point.
//
func (mw *MagickWand) GetImageGreenPrimary() (x, y float64, err error) {
ok := C.MagickGetImageGreenPrimary(mw.mw, (*C.double)(&x), (*C.double)(&y))
err = mw.getLastErrorIfFailed(ok)
return
}
// Returns the image height.
func (mw *MagickWand) GetImageHeight() uint {
return uint(C.MagickGetImageHeight(mw.mw))
}
// Returns the image histogram as an array of PixelWand wands.
//
// numberColors: the number of unique colors in the image and the number of
// pixel wands returned.
func (mw *MagickWand) GetImageHistogram() (numberColors uint, pws []PixelWand) {
cnc := C.ulong(0)
p := C.MagickGetImageHistogram(mw.mw, &cnc)
defer C.MagickRelinquishMemory(unsafe.Pointer(p))
q := uintptr(unsafe.Pointer(p))
for {
p = (**C.PixelWand)(unsafe.Pointer(q))
if *p == nil {
break
}
pws = append(pws, *newPixelWand(*p))
q += unsafe.Sizeof(q)
}
numberColors = uint(cnc)
return
}
// Gets the image interlace scheme.
func (mw *MagickWand) GetImageInterlaceScheme() InterlaceType {
return InterlaceType(C.MagickGetImageInterlaceScheme(mw.mw))
}
// Gets the image iterations.
func (mw *MagickWand) GetImageIterations() uint {
return uint(C.MagickGetImageIterations(mw.mw))
}
// Returns the image matte color.
func (mw *MagickWand) GetImageMatteColor() (matteColor *PixelWand, err error) {
cptrpw := NewPixelWand()
ok := C.MagickGetImageMatteColor(mw.mw, cptrpw.pw)
return cptrpw, mw.getLastErrorIfFailed(ok)
}
// Returns the page geometry associated with the image.
//
// w, h: the page width and height
//
// x, h: the page x-offset and y-offset.
//
func (mw *MagickWand) GetImagePage() (w, h uint, x, y int, err error) {
var cw, ch C.ulong
var cx, cy C.long
ok := C.MagickGetImagePage(mw.mw, &cw, &ch, &cx, &cy)
return uint(cw), uint(ch), int(cx), int(cy), mw.getLastErrorIfFailed(ok)
}
// Returns the chromaticy red primary point.
//
// x, y: the chromaticity red primary x/y-point.
//
func (mw *MagickWand) GetImageRedPrimary() (x, y float64, err error) {
var cdx, cdy C.double
ok := C.MagickGetImageRedPrimary(mw.mw, &cdx, &cdy)
return float64(cdx), float64(cdy), mw.getLastErrorIfFailed(ok)
}
// Gets the image X and Y resolution.
func (mw *MagickWand) GetImageResolution() (x, y float64, err error) {
var dx, dy C.double
ok := C.MagickGetImageResolution(mw.mw, &dx, &dy)
return float64(dx), float64(dy), mw.getLastErrorIfFailed(ok)
}
// Gets the image type that will be used when the
// image is saved. This may be different to the current image type, returned
// by GetImageType().
func (mw *MagickWand) GetImageSavedType() ImageType {
return ImageType(C.MagickGetImageSavedType(mw.mw))
}
// Generates an SHA-256 message digest for the image pixel stream.
func (mw *MagickWand) GetImageSignature() string {
p := C.MagickGetImageSignature(mw.mw)
defer C.MagickRelinquishMemory(unsafe.Pointer(p))
return C.GoString(p)
}
// Gets the potential image type
// To ensure the image type matches its potential, use SetImageType():
// wand.SetImageType(wand.GetImageType())
func (mw *MagickWand) GetImageType() ImageType {
return ImageType(C.MagickGetImageType(mw.mw))
}
// Gets the image units of resolution.
func (mw *MagickWand) GetImageUnits() ResolutionType {
return ResolutionType(C.MagickGetImageUnits(mw.mw))
}
// Returns the chromaticy white point.
//
// x, y: the chromaticity white x/y-point.
//
func (mw *MagickWand) GetImageWhitePoint() (x, y float64, err error) {
ok := C.MagickGetImageWhitePoint(mw.mw, (*C.double)(&x), (*C.double)(&y))
err = mw.getLastErrorIfFailed(ok)
return
}
// Returns the image width.
func (mw *MagickWand) GetImageWidth() uint {
return uint(C.MagickGetImageWidth(mw.mw))
}
// Returns the number of images associated with a magick wand.
func (mw *MagickWand) GetNumberImages() uint {
return uint(C.MagickGetNumberImages(mw.mw))
}
// Gets the horizontal and vertical sampling factor.
func (mw *MagickWand) GetSamplingFactors() (factors []float64) {
num := C.ulong(0)
pd := C.MagickGetSamplingFactors(mw.mw, &num)
defer C.MagickRelinquishMemory(unsafe.Pointer(pd))
factors = sizedDoubleArrayToFloat64Slice(pd, num)
return
}
// Returns the size associated with the magick wand.
func (mw *MagickWand) GetSize() (uint, uint, error) {
w := C.ulong(0)
h := C.ulong(0)
ok := C.MagickGetSize(mw.mw, &w, &h)
return uint(w), uint(h), mw.getLastErrorIfFailed(ok)
}
// Replaces colors in the image from a Hald color lookup table. A Hald color
// lookup table is a 3-dimensional color cube mapped to 2 dimensions. Create
// it with the HALD coder. You can apply any color transformation to the Hald
// image and then use this method to apply the transform to the image.
func (mw *MagickWand) HaldClutImage(hald *MagickWand) error {
ok := C.MagickHaldClutImage(mw.mw, hald.mw)
return mw.getLastErrorIfFailed(ok)
}
// Returns true if the wand has more images when traversing the list in the
// forward direction
func (mw *MagickWand) HasNextImage() bool {
return 1 == C.MagickHasNextImage(mw.mw)
}
// Returns true if the wand has more images when traversing the list in the
// reverse direction
func (mw *MagickWand) HasPreviousImage() bool {
return 1 == C.MagickHasPreviousImage(mw.mw)
}
// Creates a new image that is a copy of an existing one with the image pixels
// "implode" by the specified percentage.
func (mw *MagickWand) ImplodeImage(radius float64) error {
ok := C.MagickImplodeImage(mw.mw, C.double(radius))
return mw.getLastErrorIfFailed(ok)
}
// Adds a label to your image.
func (mw *MagickWand) LabelImage(label string) error {
cslabel := C.CString(label)
defer C.free(unsafe.Pointer(cslabel))
ok := C.MagickLabelImage(mw.mw, cslabel)
return mw.getLastErrorIfFailed(ok)
}
// Adjusts the levels of an image by scaling the colors falling between
// specified white and black points to the full available quantum range. The
// parameters provided represent the black, mid, and white points. The black
// point specifies the darkest color in the image. Colors darker than the
// black point are set to zero. Mid point specifies a gamma correction to
// apply to the image. White point specifies the lightest color in the image.
// Colors brighter than the white point are set to the maximum quantum value.
func (mw *MagickWand) LevelImage(blackPoint, gamma, whitePoint float64) error {
ok := C.MagickLevelImage(mw.mw, C.double(blackPoint), C.double(gamma), C.double(whitePoint))
return mw.getLastErrorIfFailed(ok)
}
// Adjusts the levels of an image by scaling the colors falling between
// specified white and black points to the full available quantum range. The
// parameters provided represent the black, mid, and white points. The black
// point specifies the darkest color in the image. Colors darker than the
// black point are set to zero. Mid point specifies a gamma correction to
// apply to the image. White point specifies the lightest color in the image.
// Colors brighter than the white point are set to the maximum quantum value.
func (mw *MagickWand) LevelImageChannel(channel ChannelType, blackPoint, gamma, whitePoint float64) error {
ok := C.MagickLevelImageChannel(mw.mw, C.ChannelType(channel), C.double(blackPoint), C.double(gamma), C.double(whitePoint))
return mw.getLastErrorIfFailed(ok)
}
// This is a convenience method that scales an image proportionally to twice
// its original size.
func (mw *MagickWand) MagnifyImage() error {
ok := C.MagickMagnifyImage(mw.mw)
return mw.getLastErrorIfFailed(ok)
}
// Replaces the colors of an image with the closest color from a reference image.
//
// from: reference image
//
// dither: Set this integer value to something other than zero to dither the mapped image.
//
func (mw *MagickWand) MapImage(from *MagickWand, dither uint) error {
ok := C.MagickMapImage(mw.mw, from.mw, C.uint(dither))
return mw.getLastErrorIfFailed(ok)
}
// Changes the transparency value of any pixel that
// matches target and is an immediate neighbor. If the method
// FillToBorderMethod is specified, the transparency value is changed for any
// neighbor pixel that does not match the bordercolor member of image.
func (mw *MagickWand) MatteFloodfillImage(opacity Quantum, fuzz float64, borderColor *PixelWand, x int, y int) error {
ok := C.MagickMatteFloodfillImage(mw.mw, C.Quantum(opacity), C.double(fuzz), borderColor.pw, C.long(x), C.long(y))
return mw.getLastErrorIfFailed(ok)
}
// Applies a digital filter that improves the quality
// of a noisy image. Each pixel is replaced by the median in a set of
// neighboring pixels as defined by radius.
func (mw *MagickWand) MedianFilterImage(radius float64) error {
ok := C.MagickMedianFilterImage(mw.mw, C.double(radius))
return mw.getLastErrorIfFailed(ok)
}
// This is a convenience method that scales an image proportionally to
// one-half its original size
func (mw *MagickWand) MinifyImage() error {
ok := C.MagickMinifyImage(mw.mw)
return mw.getLastErrorIfFailed(ok)
}
// Lets you control the brightness, saturation, and hue of an image. Hue is
// the percentage of absolute rotation from the current position. For example
// 50 results in a counter-clockwise rotation of 90 degrees, 150 results in a
// clockwise rotation of 90 degrees, with 0 and 200 both resulting in a
// rotation of 180 degrees. To increase the color brightness by 20 and
// decrease the color saturation by 10 and leave the hue unchanged, use: 120,
// 90, 100.
//
// brightness: the percent change in brighness.
//
// saturation: the percent change in saturation.
//
// hue: the percent change in hue.
//
func (mw *MagickWand) ModulateImage(brightness, saturation, hue float64) error {
ok := C.MagickModulateImage(mw.mw, C.double(brightness), C.double(saturation), C.double(hue))
return mw.getLastErrorIfFailed(ok)
}
// Creates a composite image by combining several separate images. The images
// are tiled on the composite image with the name of the image optionally
// appearing just below the individual tile.
//
// dw: the drawing wand. The font name, size, and color are obtained from this
// wand.
//
// tileGeo: the number of tiles per row and page (e.g. 6x4+0+0).
//
// thumbGeo: Preferred image size and border size of each thumbnail (e.g.
// 120x120+4+3>).
//
// mode: Thumbnail framing mode: Frame, Unframe, or Concatenate.
//
// frame: Surround the image with an ornamental border (e.g. 15x15+3+3). The
// frame color is that of the thumbnail's matte color.
//
func (mw *MagickWand) MontageImage(dw *DrawingWand, tileGeo string, thumbGeo string, mode MontageMode, frame string) *MagickWand {
cstile := C.CString(tileGeo)
defer C.free(unsafe.Pointer(cstile))
csthumb := C.CString(thumbGeo)
defer C.free(unsafe.Pointer(csthumb))
csframe := C.CString(frame)
defer C.free(unsafe.Pointer(csframe))
return newMagickWand(C.MagickMontageImage(mw.mw, dw.dw, cstile, csthumb, C.MontageMode(mode), csframe))
}
// Method morphs a set of images. Both the image pixels and size are linearly
// interpolated to give the appearance of a meta-morphosis from one image to
// the next.
//
// numFrames: the number of in-between images to generate.
func (mw *MagickWand) MorphImages(numFrames uint) *MagickWand {
return newMagickWand(C.MagickMorphImages(mw.mw, C.ulong(numFrames)))
}
// inlays an image sequence to form a single coherent
// picture. It returns a wand with each image in the sequence composited at
// the location defined by the page offset of the image.
func (mw *MagickWand) MosaicImages() *MagickWand {
return newMagickWand(C.MagickMosaicImages(mw.mw))
}
// Simulates motion blur. We convolve the image with a Gaussian operator of
// the given radius and standard deviation (sigma). For reasonable results,
// radius should be larger than sigma. Use a radius of 0 and MotionBlurImage()
// selects a suitable radius for you. Angle gives the angle of the blurring
// motion.
//
// radius: the radius of the Gaussian, in pixels, not counting the center pixel.
//
// sigma: the standard deviation of the Gaussian, in pixels.
//
// angle: apply the effect along this angle.
//
func (mw *MagickWand) MotionBlurImage(radius, sigma, angle float64) error {
ok := C.MagickMotionBlurImage(mw.mw, C.double(radius), C.double(sigma), C.double(angle))
return mw.getLastErrorIfFailed(ok)
}
// Negates the colors in the reference image. The Grayscale option means that
// only grayscale values within the image are negated. You can also reduce the
// influence of a particular channel with a gamma value of 0.
//
// gray: If true, only negate grayscale pixels within the image.
//
func (mw *MagickWand) NegateImageChannel(channel ChannelType, gray bool) error {
ok := C.MagickNegateImageChannel(mw.mw, C.ChannelType(channel), b2i(gray))
return mw.getLastErrorIfFailed(ok)
}
// Negates the colors in the reference image. The Grayscale option means that
// only grayscale values within the image are negated. You can also reduce the
// influence of a particular channel with a gamma value of 0.
//
// gray: If true, only negate grayscale pixels within the image.
//
func (mw *MagickWand) NegateImage(gray bool) error {
ok := C.MagickNegateImage(mw.mw, b2i(gray))
return mw.getLastErrorIfFailed(ok)
}
// Sets the next image in the wand as the current image. It is typically used
// after ResetIterator(), after which its first use will set the first image
// as the current image (unless the wand is empty). It will return false when
// no more images are left to be returned which happens when the wand is empty,
// or the current image is the last image. When the above condition (end of
// image list) is reached, the iterator is automaticall set so that you can
// start using PreviousImage() to again/ iterate over the images in the
// reverse direction, starting with the last image (again). You can jump to
// this condition immeditally using SetLastIterator().
func (mw *MagickWand) NextImage() bool {
return 1 == C.MagickNextImage(mw.mw)
}
// Enhances the contrast of a color image by adjusting the pixels color to
// span the entire range of colors available. You can also reduce the
// influence of a particular channel with a gamma value of 0.
func (mw *MagickWand) NormalizeImage() error {
ok := C.MagickNormalizeImage(mw.mw)
return mw.getLastErrorIfFailed(ok)
}
// Applies a special effect filter that simulates an oil painting. Each pixel
// is replaced by the most frequent color occurring in a circular region
// defined by radius.
//
// radius: the radius of the circular neighborhood.
//
func (mw *MagickWand) OilPaintImage(radius float64) error {
ok := C.MagickOilPaintImage(mw.mw, C.double(radius))
return mw.getLastErrorIfFailed(ok)
}
//
func (mw *MagickWand) OpaqueImage(target, fill *PixelWand, fuzz float64) error {
ok := C.MagickOpaqueImage(mw.mw, target.pw, fill.pw, C.double(fuzz))
return mw.getLastErrorIfFailed(ok)
}
// This is like ReadImage() except the only valid information returned is the
// image width, height, size, and format. It is designed to efficiently obtain
// this information from a file without reading the entire image sequence into
// memory.