Class: Magick::Image

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/rmagick_internal.rb,
ext/RMagick/rmmain.c

Overview

Ruby-level Magick::Image methods

Defined Under Namespace

Classes: DrawOptions, Info, PolaroidOptions, View

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Object

Initialize a new Image object If the fill argument is omitted, fill with background color.

Ruby usage:

- @verbatim Image#initialize(cols,rows) @endverbatim
- @verbatim Image#initialize(cols,rows,fill) @endverbatim

Notes:

- Default fill is false

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object



9379
9380
9381
9382
9383
9384
9385
9386
9387
9388
9389
9390
9391
9392
9393
9394
9395
9396
9397
9398
9399
9400
9401
9402
9403
9404
9405
9406
9407
9408
9409
9410
9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
9431
9432
9433
9434
9435
# File 'ext/RMagick/rmimage.c', line 9379

VALUE
Image_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE fill = 0;
    Info *info;
    VALUE info_obj;
    Image *image;
    unsigned long cols, rows;

    switch (argc)
    {
        case 3:
            fill = argv[2];
        case 2:
            rows = NUM2ULONG(argv[1]);
            cols = NUM2ULONG(argv[0]);
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or 3)", argc);
            break;
    }

    // Create a new Info object to use when creating this image.
    info_obj = rm_info_new();
    Data_Get_Struct(info_obj, Info, info);

    image = rm_acquire_image(info);
    if (!image)
    {
        rb_raise(rb_eNoMemError, "not enough memory to continue");
    }

    rm_set_user_artifact(image, info);

    // NOW store a real image in the image object.
    UPDATE_DATA_PTR(self, image);

    SetImageExtent(image, cols, rows);

    // If the caller did not supply a fill argument, call SetImageBackgroundColor
    // to fill the image using the background color. The background color can
    // be set by specifying it when creating the Info parm block.
    if (!fill)
    {
        (void) SetImageBackgroundColor(image);
    }
    // fillobj.fill(self)
    else
    {
        (void) rb_funcall(fill, rm_ID_fill, 1, self);
    }

    RB_GC_GUARD(fill);
    RB_GC_GUARD(info_obj);

    return self;
}

Class Method Details

._load(str) ⇒ Object

Implement marshalling.

Ruby usage:

- @verbatim Image._load @endverbatim

Notes:

- calls BlobToImage

Parameters:

  • class

    Ruby class for Image

  • str

    the marshalled string

Returns:

  • a new image

See Also:

  • Image__dump


8245
8246
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302
8303
8304
8305
8306
8307
8308
# File 'ext/RMagick/rmimage.c', line 8245

VALUE
Image__load(VALUE class ATTRIBUTE_UNUSED, VALUE str)
{
    Image *image;
    ImageInfo *info;
    DumpedImage mi;
    ExceptionInfo *exception;
    char *blob;
    long length;

    blob = rm_str2cstr(str, &length);

    // Must be as least as big as the 1st 4 fields in DumpedImage
    if (length <= (long)(sizeof(DumpedImage)-MaxTextExtent))
    {
        rb_raise(rb_eTypeError, "image is invalid or corrupted (too short)");
    }

    // Retrieve & validate the image format from the header portion
    mi.id = ((DumpedImage *)blob)->id;
    if (mi.id != DUMPED_IMAGE_ID)
    {
        rb_raise(rb_eTypeError, "image is invalid or corrupted (invalid header)");
    }

    mi.mj = ((DumpedImage *)blob)->mj;
    mi.mi = ((DumpedImage *)blob)->mi;
    if (   mi.mj != DUMPED_IMAGE_MAJOR_VERS
           || mi.mi > DUMPED_IMAGE_MINOR_VERS)
    {
        rb_raise(rb_eTypeError, "incompatible image format (can't be read)\n"
                 "\tformat version %d.%d required; %d.%d given"
                 , DUMPED_IMAGE_MAJOR_VERS, DUMPED_IMAGE_MINOR_VERS
                 , mi.mj, mi.mi);
    }

    mi.len = ((DumpedImage *)blob)->len;

    // Must be bigger than the header
    if (length <= (long)(mi.len+sizeof(DumpedImage)-MaxTextExtent))
    {
        rb_raise(rb_eTypeError, "image is invalid or corrupted (too short)");
    }

    info = CloneImageInfo(NULL);

    memcpy(info->magick, ((DumpedImage *)blob)->magick, mi.len);
    info->magick[mi.len] = '\0';

    exception = AcquireExceptionInfo();

    blob += offsetof(DumpedImage,magick) + mi.len;
    length -= offsetof(DumpedImage,magick) + mi.len;
    image = BlobToImage(info, blob, (size_t) length, exception);
    (void) DestroyImageInfo(info);

    rm_check_exception(exception, image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(image);

    return rm_image_new(image);
}

.capture(*args) ⇒ Object

do a screen capture.

Ruby usage:

- @verbatim Image.capture @endverbatim
- @verbatim Image.capture(silent) { optional parms } @endverbatim
- @verbatim Image.capture(silent,frame) { optional parms } @endverbatim
- @verbatim Image.capture(silent,frame,descend) { optional parms } @endverbatim
- @verbatim Image.capture(silent,frame,descend,screen) { optional parms } @endverbatim
- @verbatim Image.capture(silent,frame,descend,screen,borders) { optional parms } @endverbatim

Notes:

- Default silent is false
- Default frame is false
- Default descent is false
- Default screen is false
- Default borders if false

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
# File 'ext/RMagick/rmimage.c', line 2072

VALUE
Image_capture(int argc, VALUE *argv, VALUE self ATTRIBUTE_UNUSED)
{
    Image *new_image;
    ImageInfo *image_info;
    VALUE info_obj;
    XImportInfo ximage_info;

    XGetImportInfo(&ximage_info);
    switch (argc)
    {
        case 5:
            ximage_info.borders = (MagickBooleanType)RTEST(argv[4]);
        case 4:
            ximage_info.screen  = (MagickBooleanType)RTEST(argv[3]);
        case 3:
            ximage_info.descend = (MagickBooleanType)RTEST(argv[2]);
        case 2:
            ximage_info.frame   = (MagickBooleanType)RTEST(argv[1]);
        case 1:
            ximage_info.silent  = (MagickBooleanType)RTEST(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 5)", argc);
            break;
    }

    // Get optional parms.
    // Set info->filename = "root", window ID number or window name,
    //  or nothing to do an interactive capture
    // Set info->server_name to the server name
    // Also info->colorspace, depth, dither, interlace, type
    info_obj = rm_info_new();
    Data_Get_Struct(info_obj, Info, image_info);

    // If an error occurs, IM will call our error handler and we raise an exception.
    new_image = XImportImage(image_info, &ximage_info);
    rm_check_image_exception(new_image, DestroyOnError);
    rm_ensure_result(new_image);

    rm_set_user_artifact(new_image, image_info);

    RB_GC_GUARD(info_obj);

    return rm_image_new(new_image);
}

.combineObject

.constitute(width_arg, height_arg, map_arg, pixels_arg) ⇒ Object

Creates an Image from the supplied pixel data. The pixel data must be in scanline order, top-to-bottom. The pixel data is an array of either all Fixed or all Float elements. If Fixed, the elements must be in the range [0..QuantumRange]. If Float, the elements must be normalized [0..1]. The “map” argument reflects the expected ordering of the pixel array. It can be any combination or order of R = red, G = green, B = blue, A = alpha, C = cyan, Y = yellow, M = magenta, K = black, or I = intensity (for grayscale).

The pixel array must have width X height X strlen(map) elements.

Ruby usage:

- @verbatim Image.constitute(width, height, map, pixels) @endverbatim

Parameters:

  • class

    the Ruby class for an Image (unused)

  • width_arg

    the width of the array

  • height_arg

    the height of the array

  • map_arg

    the map (expected ordering of the pixel array)

  • pixels_arg

    the pixel array

Returns:

  • a new image



3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
# File 'ext/RMagick/rmimage.c', line 3934

VALUE
Image_constitute(VALUE class ATTRIBUTE_UNUSED, VALUE width_arg, VALUE height_arg
                 , VALUE map_arg, VALUE pixels_arg)
{
    Image *new_image;
    VALUE pixel, pixel0;
    unsigned long width, height;
    long x, npixels;
    char *map;
    long map_l;
    volatile union
    {
        double *f;
        Quantum *i;
        void *v;
    } pixels;
    VALUE pixel_class;
    StorageType stg_type;
    ExceptionInfo *exception;

    // rb_Array converts objects that are not Arrays to Arrays if possible,
    // and raises TypeError if it can't.
    pixels_arg = rb_Array(pixels_arg);

    width = NUM2ULONG(width_arg);
    height = NUM2ULONG(height_arg);

    if (width == 0 || height == 0)
    {
        rb_raise(rb_eArgError, "width and height must be non-zero");
    }

    map = rm_str2cstr(map_arg, &map_l);

    npixels = (long)(width * height * map_l);
    if (RARRAY_LEN(pixels_arg) != npixels)
    {
        rb_raise(rb_eArgError, "wrong number of array elements (%ld for %ld)"
                 , RARRAY_LEN(pixels_arg), npixels);
    }

    // Inspect the first element in the pixels array to determine the expected
    // type of all the elements. Allocate the pixel buffer.
    pixel0 = rb_ary_entry(pixels_arg, 0);
    if (rb_obj_is_kind_of(pixel0, rb_cFloat) == Qtrue)
    {
        pixels.f = ALLOC_N(double, npixels);
        stg_type = DoublePixel;
        pixel_class = rb_cFloat;
    }
    else if (rb_obj_is_kind_of(pixel0, rb_cInteger) == Qtrue)
    {
        pixels.i = ALLOC_N(Quantum, npixels);
        stg_type = QuantumPixel;
        pixel_class = rb_cInteger;
    }
    else
    {
        rb_raise(rb_eTypeError, "element 0 in pixel array is %s, must be numeric"
                 , rb_class2name(CLASS_OF(pixel0)));
    }



    // Convert the array elements to the appropriate C type, store in pixel
    // buffer.
    for (x = 0; x < npixels; x++)
    {
        pixel = rb_ary_entry(pixels_arg, x);
        if (rb_obj_is_kind_of(pixel, pixel_class) != Qtrue)
        {
            xfree(pixels.v);
            rb_raise(rb_eTypeError, "element %ld in pixel array is %s, expected %s"
                     , x, rb_class2name(CLASS_OF(pixel)),rb_class2name(CLASS_OF(pixel0)));
        }
        if (pixel_class == rb_cFloat)
        {
            pixels.f[x] = (float) NUM2DBL(pixel);
            if (pixels.f[x] < 0.0 || pixels.f[x] > 1.0)
            {
                xfree(pixels.v);
                rb_raise(rb_eArgError, "element %ld is out of range [0..1]: %f", x, pixels.f[x]);
            }
        }
        else
        {
            pixels.i[x] = NUM2QUANTUM(pixel);
        }
    }

    // This is based on ConstituteImage in IM 5.5.7
    new_image = rm_acquire_image((ImageInfo *) NULL);
    if (!new_image)
    {
        xfree(pixels.v);
        rb_raise(rb_eNoMemError, "not enough memory to continue.");
    }

    SetImageExtent(new_image, width, height);
    exception = &new_image->exception;
    if (rm_should_raise_exception(exception, RetainExceptionRetention))
    {
        xfree(pixels.v);
        (void) DestroyImage(new_image);
        rm_raise_exception(exception);
    }

    (void) SetImageBackgroundColor(new_image);
    exception = &new_image->exception;
    if (rm_should_raise_exception(exception, RetainExceptionRetention))
    {
        xfree(pixels.v);
        (void) DestroyImage(new_image);
        rm_raise_exception(exception);
    }

    (void) ImportImagePixels(new_image, 0, 0, width, height, map, stg_type, (const void *)pixels.v);
    xfree(pixels.v);
    rm_check_image_exception(new_image, DestroyOnError);

    RB_GC_GUARD(pixel);
    RB_GC_GUARD(pixel0);
    RB_GC_GUARD(pixel_class);

    return rm_image_new(new_image);
}

.from_blob(blob_arg) ⇒ Object

Call BlobToImage.

Ruby usage:

- @verbatim Image.from_blob(blob) <{ parm block }> @endverbatim

Parameters:

  • class

    the Ruby Image class (unused)

  • blob_arg

    the blob as a Ruby string

Returns:

  • an array of new images



6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
# File 'ext/RMagick/rmimage.c', line 6776

VALUE
Image_from_blob(VALUE class ATTRIBUTE_UNUSED, VALUE blob_arg)
{
    Image *images;
    Info *info;
    VALUE info_obj;
    ExceptionInfo *exception;
    void *blob;
    long length;

    blob = (void *) rm_str2cstr(blob_arg, &length);

    // Get a new Info object - run the parm block if supplied
    info_obj = rm_info_new();
    Data_Get_Struct(info_obj, Info, info);

    exception = AcquireExceptionInfo();
    images = BlobToImage(info,  blob, (size_t)length, exception);
    rm_check_exception(exception, images, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(images);
    rm_set_user_artifact(images, info);

    RB_GC_GUARD(info_obj);

    return array_from_images(images);
}

.ping(file_arg) ⇒ Object

Call ImagePing.

Ruby usage:

- @verbatim Image.ping(file) @endverbatim

Parameters:

  • class

    the Ruby class for an Image

  • file_arg

    the file containing image info

Returns:

  • an array of 1 or more new image objects (without pixel data)

See Also:

  • Image_read
  • rd_image


10037
10038
10039
10040
10041
# File 'ext/RMagick/rmimage.c', line 10037

VALUE
Image_ping(VALUE class, VALUE file_arg)
{
    return rd_image(class, file_arg, PingImage);
}

.read(file_arg) ⇒ Object

Call ReadImage.

Ruby usage:

- @verbatim Image.read(file) @endverbatim

Parameters:

  • class

    the Ruby class for an Image

  • file_arg

    the file containing image data

Returns:

  • an array of 1 or more new image objects

See Also:

  • rd_image


10856
10857
10858
10859
10860
# File 'ext/RMagick/rmimage.c', line 10856

VALUE
Image_read(VALUE class, VALUE file_arg)
{
    return rd_image(class, file_arg, ReadImage);
}

.read_inline(content) ⇒ Object

Read a Base64-encoded image.

Ruby usage:

- @verbatim Image.read_inline(content) @endverbatim

Notes:

- This is similar to, but not the same as ReadInlineImage. ReadInlineImage
  requires a comma preceeding the image data. This method allows but does
  not require a comma.

Parameters:

  • self

    this object

  • content

    the content

Returns:

  • an array of new images

See Also:

  • array_from_images


11032
11033
11034
11035
11036
11037
11038
11039
11040
11041
11042
11043
11044
11045
11046
11047
11048
11049
11050
11051
11052
11053
11054
11055
11056
11057
11058
11059
11060
11061
11062
11063
11064
11065
11066
11067
11068
11069
11070
11071
11072
11073
11074
11075
11076
11077
11078
11079
11080
11081
11082
11083
11084
11085
# File 'ext/RMagick/rmimage.c', line 11032

VALUE
Image_read_inline(VALUE self ATTRIBUTE_UNUSED, VALUE content)
{
    VALUE info_obj;
    Image *images;
    ImageInfo *info;
    char *image_data;
    long x, image_data_l;
    unsigned char *blob;
    size_t blob_l;
    ExceptionInfo *exception;

    image_data = rm_str2cstr(content, &image_data_l);

    // Search for a comma. If found, we'll set the start of the
    // image data just following the comma. Otherwise we'll assume
    // the image data starts with the first byte.
    for (x = 0; x < image_data_l; x++)
    {
        if (image_data[x] == ',')
        {
            break;
        }
    }
    if (x < image_data_l)
    {
        image_data += x + 1;
    }

    blob = Base64Decode(image_data, &blob_l);
    if (blob_l == 0)
    {
        rb_raise(rb_eArgError, "can't decode image");
    }

    exception = AcquireExceptionInfo();

    // Create a new Info structure for this read. About the
    // only useful attribute that can be set is `format'.
    info_obj = rm_info_new();
    Data_Get_Struct(info_obj, Info, info);

    images = BlobToImage(info, blob, blob_l, exception);
    magick_free((void *)blob);

    rm_check_exception(exception, images, DestroyOnError);

    (void) DestroyExceptionInfo(exception);
    rm_set_user_artifact(images, info);

    RB_GC_GUARD(info_obj);

    return array_from_images(images);
}

Instance Method Details

#<=>(other) ⇒ Object

Compare two images.

Ruby usage:

- @verbatim Image#<=> @endverbatim

Parameters:

  • self

    this image

  • other

    other image

Returns:

  • -1, 0, 1



12651
12652
12653
12654
12655
12656
12657
12658
12659
12660
12661
12662
12663
12664
12665
12666
12667
12668
12669
12670
12671
12672
12673
12674
12675
12676
12677
12678
12679
12680
12681
# File 'ext/RMagick/rmimage.c', line 12651

VALUE
Image_spaceship(VALUE self, VALUE other)
{
    Image *imageA, *imageB;
    const char *sigA, *sigB;
    int res;

    imageA = rm_check_destroyed(self);

    // If the other object isn't a Image object, then they can't be equal.
    if (!rb_obj_is_kind_of(other, Class_Image))
    {
        return Qnil;
    }

    imageB = rm_check_destroyed(other);

    (void) SignatureImage(imageA);
    (void) SignatureImage(imageB);
    sigA = rm_get_property(imageA, "signature");
    sigB = rm_get_property(imageB, "signature");
    if (!sigA || !sigB)
    {
        rb_raise(Class_ImageMagickError, "can't get image signature");
    }

    res = memcmp(sigA, sigB, 64);
    res = res > 0 ? 1 : (res < 0 ? -1 :  0);    // reduce to 1, -1, 0

    return INT2FIX(res);
}

#[](key_arg) ⇒ Object

Return the image property associated with “key”.

Ruby usage:

- @verbatim Image#["key"] @endverbatim
- @verbatim Image#[:key] @endverbatim

Notes:

- Use Image#[]= (aset) to establish more properties or change the value of
  an existing property.

Parameters:

  • self

    this object

  • key_arg

    the key to get

Returns:

  • property value or nil if key doesn’t exist



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
# File 'ext/RMagick/rmimage.c', line 747

VALUE
Image_aref(VALUE self, VALUE key_arg)
{
    Image *image;
    const char *key;
    const char *attr;

    image = rm_check_destroyed(self);

    switch (TYPE(key_arg))
    {
        case T_NIL:
            return Qnil;

        case T_SYMBOL:
            key = rb_id2name((ID)SYM2ID(key_arg));
            break;

        default:
            key = StringValuePtr(key_arg);
            if (*key == '\0')
            {
                return Qnil;
            }
            break;
    }


    if (rm_strcasecmp(key, "EXIF:*") == 0)
    {
        return rm_exif_by_entry(image);
    }
    else if (rm_strcasecmp(key, "EXIF:!") == 0)
    {
        return rm_exif_by_number(image);
    }

    attr = rm_get_property(image, key);
    return attr ? rb_str_new2(attr) : Qnil;
}

#[]=(key_arg, attr_arg) ⇒ Object

Update or add image attribute “key”.

Ruby usage:

- @verbatim Image#["key"] = attr @endverbatim
- @verbatim Image#[:key] = attr @endverbatim

Notes:

- Specify attr=nil to remove the key from the list.
- SetImageProperty normally APPENDS the new value to any existing value.
  Since this usage is tremendously counter-intuitive, this function always
  deletes the existing value before setting the new value.
- There's no use checking the return value since SetImageProperty returns
  "False" for many reasons, some legitimate.

Parameters:

  • self

    this object

  • key_arg

    the key to set

  • attr_arg

    the value to which to set it

Returns:

  • self



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
# File 'ext/RMagick/rmimage.c', line 808

VALUE
Image_aset(VALUE self, VALUE key_arg, VALUE attr_arg)
{
    Image *image;
    const char *key;
    char *attr;
    unsigned int okay;

    image = rm_check_frozen(self);

    attr = attr_arg == Qnil ? NULL : StringValuePtr(attr_arg);

    switch (TYPE(key_arg))
    {
        case T_NIL:
            return self;

        case T_SYMBOL:
            key = rb_id2name((ID)SYM2ID(key_arg));
            break;

        default:
            key = StringValuePtr(key_arg);
            if (*key == '\0')
            {
                return self;
            }
            break;
    }


    // Delete existing value. SetImageProperty returns False if
    // the attribute doesn't exist - we don't care.
    (void) rm_set_property(image, key, NULL);
    // Set new value
    if (attr)
    {
        okay = rm_set_property(image, key, attr);
        if (!okay)
        {
            rb_warning("SetImageProperty failed (probably out of memory)");
        }
    }
    return self;
}

#_dump(depth) ⇒ Object

Implement marshalling.

Ruby usage:

- @verbatim Image#_dump(aDepth) @endverbatim

Notes:

- Uses ImageToBlob - use the MIFF format in the blob since it's the most
  general

Parameters:

  • self

    this object

  • depth

    the depth to which to dump (unused)

Returns:

  • a string representing the dumped image



5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
# File 'ext/RMagick/rmimage.c', line 5448

VALUE
Image__dump(VALUE self, VALUE depth ATTRIBUTE_UNUSED)
{
    Image *image;
    ImageInfo *info;
    void *blob;
    size_t length;
    DumpedImage mi;
    VALUE str;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    info = CloneImageInfo(NULL);
    if (!info)
    {
        rb_raise(rb_eNoMemError, "not enough memory to continue");
    }
    strcpy(info->magick, image->magick);

    exception = AcquireExceptionInfo();
    blob = ImageToBlob(info, image, &length, exception);

    // Free ImageInfo first - error handling may raise an exception
    (void) DestroyImageInfo(info);

    CHECK_EXCEPTION()

    (void) DestroyExceptionInfo(exception);

    if (!blob)
    {
        rb_raise(rb_eNoMemError, "not enough memory to continue");
    }

    // Create a header for the blob: ID and version
    // numbers, followed by the length of the magick
    // string stored as a byte, followed by the
    // magick string itself.
    mi.id = DUMPED_IMAGE_ID;
    mi.mj = DUMPED_IMAGE_MAJOR_VERS;
    mi.mi = DUMPED_IMAGE_MINOR_VERS;
    strcpy(mi.magick, image->magick);
    mi.len = (unsigned char) min((size_t)UCHAR_MAX, strlen(mi.magick));

    // Concatenate the blob onto the header & return the result
    str = rb_str_new((char *)&mi, (long)(mi.len+offsetof(DumpedImage,magick)));
    str = rb_str_buf_cat(str, (char *)blob, (long)length);
    magick_free((void*)blob);

    RB_GC_GUARD(str);

    return str;
}

#adaptive_blur(*args) ⇒ Object

Call AdaptiveBlurImage.

Ruby usage:

- @verbatim Image#adaptive_blur @endverbatim
- @verbatim Image#adaptive_blur(radius) @endverbatim
- @verbatim Image#adaptive_blur(radius, sigma) @endverbatim

Notes:

- Default radius is 0.0
- Default sigma is 1.0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



220
221
222
223
224
# File 'ext/RMagick/rmimage.c', line 220

VALUE
Image_adaptive_blur(int argc, VALUE *argv, VALUE self)
{
    return adaptive_method(argc, argv, self, AdaptiveBlurImage);
}

#adaptive_blur_channel(*args) ⇒ Object

Call AdaptiveBlurImageChannel.

Ruby usage:

- @verbatim Image#adaptive_blur_channel @endverbatim
- @verbatim Image#adaptive_blur_channel(radius) @endverbatim
- @verbatim Image#adaptive_blur_channel(radius, sigma) @endverbatim
- @verbatim Image#adaptive_blur_channel(radius, sigma, channel) @endverbatim
- @verbatim Image#adaptive_blur_channel(radius, sigma, channel, ...) @endverbatim

Notes:

- Default radius is 0.0
- Default sigma is 1.0
- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



248
249
250
251
252
# File 'ext/RMagick/rmimage.c', line 248

VALUE
Image_adaptive_blur_channel(int argc, VALUE *argv, VALUE self)
{
    return adaptive_channel_method(argc, argv, self, AdaptiveBlurImageChannel);
}

#adaptive_resize(*args) ⇒ Object

Call AdaptiveResizeImage.

Ruby usage:

- @verbatim Image#adaptive_resize(scale_val) @endverbatim
- @verbatim Image#adaptive_resize(cols, rows) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



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
# File 'ext/RMagick/rmimage.c', line 267

VALUE
Image_adaptive_resize(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    unsigned long rows, columns;
    double scale_val, drows, dcols;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    switch (argc)
    {
        case 2:
            rows = NUM2ULONG(argv[1]);
            columns = NUM2ULONG(argv[0]);
            break;
        case 1:
            scale_val = NUM2DBL(argv[0]);
            if (scale_val < 0.0)
            {
                rb_raise(rb_eArgError, "invalid scale_val value (%g given)", scale_val);
            }
            drows = scale_val * image->rows + 0.5;
            dcols = scale_val * image->columns + 0.5;
            if (drows > (double)ULONG_MAX || dcols > (double)ULONG_MAX)
            {
                rb_raise(rb_eRangeError, "resized image too big");
            }
            rows = (unsigned long) drows;
            columns = (unsigned long) dcols;
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
            break;
    }

    exception = AcquireExceptionInfo();
    new_image = AdaptiveResizeImage(image, columns, rows, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);
    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#adaptive_sharpen(*args) ⇒ Object

Call AdaptiveSharpenImage.

Ruby usage:

- @verbatim Image#adaptive_sharpen @endverbatim
- @verbatim Image#adaptive_sharpen(radius) @endverbatim
- @verbatim Image#adaptive_sharpen(radius, sigma) @endverbatim

Notes:

- Default radius is 0.0
- Default sigma is 1.0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



332
333
334
335
336
# File 'ext/RMagick/rmimage.c', line 332

VALUE
Image_adaptive_sharpen(int argc, VALUE *argv, VALUE self)
{
    return adaptive_method(argc, argv, self, AdaptiveSharpenImage);
}

#adaptive_sharpen_channel(*args) ⇒ Object

Call AdaptiveSharpenImageChannel.

Ruby usage:

- @verbatim Image#adaptive_sharpen_channel(radius=0.0, sigma=1.0[, channel...]) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



351
352
353
354
355
# File 'ext/RMagick/rmimage.c', line 351

VALUE
Image_adaptive_sharpen_channel(int argc, VALUE *argv, VALUE self)
{
    return adaptive_channel_method(argc, argv, self, AdaptiveSharpenImageChannel);
}

#adaptive_threshold(*args) ⇒ Object

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.

Ruby usage:

- @verbatim Image#adaptive_threshold @endverbatim
- @verbatim Image#adaptive_threshold(width) @endverbatim
- @verbatim Image#adaptive_threshold(width, height) @endverbatim
- @verbatim Image#adaptive_threshold(width, height, offset) @endverbatim

Notes:

- Default width is 3
- Default height is 3
- Default offset is 0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



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
# File 'ext/RMagick/rmimage.c', line 380

VALUE
Image_adaptive_threshold(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    unsigned long width = 3, height = 3;
    long offset = 0;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    switch (argc)
    {
        case 3:
            offset = NUM2LONG(argv[2]);
        case 2:
            height = NUM2ULONG(argv[1]);
        case 1:
            width  = NUM2ULONG(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 3)", argc);
    }

    exception = AcquireExceptionInfo();
    new_image = AdaptiveThresholdImage(image, width, height, offset, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#add_compose_mask(mask) ⇒ Object

Set the image composite mask.

Ruby usage:

- @verbatim Image#add_compose_mask(mask) @endverbatim

Parameters:

  • self

    this object

  • mask

    the composite mask

Returns:

  • self

See Also:

  • Image_mask
  • Image_delete_compose_mask
  • in ImageMagick


429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
# File 'ext/RMagick/rmimage.c', line 429

VALUE
Image_add_compose_mask(VALUE self, VALUE mask)
{
    Image *image, *mask_image = NULL;

    image = rm_check_frozen(self);
    mask_image = rm_check_destroyed(mask);
    if (image->columns != mask_image->columns || image->rows != mask_image->rows)
    {
        rb_raise(rb_eArgError, "mask must be the same size as image");
    }

    // Delete any previously-existing mask image.
    // Store a clone of the new mask image.
    (void) SetImageMask(image, mask_image);
    (void) NegateImage(image->mask, MagickFalse);

    // Since both Set and GetImageMask clone the mask image I don't see any
    // way to negate the mask without referencing it directly. Sigh.

    return self;
}

#add_noise(noise) ⇒ Object

Add random noise to a copy of the image.

Ruby usage:

- @verbatim Image#add_noise(noise_type) @endverbatim

Parameters:

  • self

    this object

  • noise

    the noise

Returns:

  • a new image



463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
# File 'ext/RMagick/rmimage.c', line 463

VALUE
Image_add_noise(VALUE self, VALUE noise)
{
    Image *image, *new_image;
    NoiseType noise_type;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    VALUE_TO_ENUM(noise, noise_type, NoiseType);

    exception = AcquireExceptionInfo();
    new_image = AddNoiseImage(image, noise_type, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#add_noise_channel(*args) ⇒ Object

Add random noise to a copy of the image.

Ruby usage:

- @verbatim Image#add_noise_channel(noise_type) @endverbatim
- @verbatim Image#add_noise_channel(noise_type,channel) @endverbatim
- @verbatim Image#add_noise_channel(noise_type,channel,channel,...) @endverbatim

Notes:

- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



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
# File 'ext/RMagick/rmimage.c', line 501

VALUE
Image_add_noise_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    NoiseType noise_type;
    ExceptionInfo *exception;
    ChannelType channels;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);

    // There must be 1 remaining argument.
    if (argc == 0)
    {
        rb_raise(rb_eArgError, "missing noise type argument");
    }
    else if (argc > 1)
    {
        raise_ChannelType_error(argv[argc-1]);
    }

    VALUE_TO_ENUM(argv[0], noise_type, NoiseType);
    channels &= ~OpacityChannel;

    exception = AcquireExceptionInfo();
    new_image = AddNoiseImageChannel(image, channels, noise_type, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#add_profile(name) ⇒ Object

Add all the profiles in the specified file.

Ruby usage:

- @verbatim Image#add_profile(name) @endverbatim

Parameters:

  • self

    this object

  • name

    the profile filename

Returns:

  • self



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
# File 'ext/RMagick/rmimage.c', line 547

VALUE
Image_add_profile(VALUE self, VALUE name)
{
    // ImageMagick code based on the code for the "-profile" option in mogrify.c
    Image *image, *profile_image;
    ImageInfo *info;
    ExceptionInfo *exception;
    char *profile_name;
    char *profile_filename = NULL;
    long profile_filename_l = 0;
    const StringInfo *profile;

    image = rm_check_frozen(self);

    // ProfileImage issues a warning if something goes wrong.
    profile_filename = rm_str2cstr(name, &profile_filename_l);

    info = CloneImageInfo(NULL);
    if (!info)
    {
        rb_raise(rb_eNoMemError, "not enough memory to continue");
    }
    profile = GetImageProfile(image, "iptc");
    if (profile)
    {
        info->profile = (void *)CloneStringInfo(profile);
    }
    strncpy(info->filename, profile_filename, min((size_t)profile_filename_l, sizeof(info->filename)));
    info->filename[MaxTextExtent-1] = '\0';

    exception = AcquireExceptionInfo();
    profile_image = ReadImage(info, exception);
    (void) DestroyImageInfo(info);
    rm_check_exception(exception, profile_image, DestroyOnError);
    rm_ensure_result(profile_image);

    ResetImageProfileIterator(profile_image);
    profile_name = GetNextImageProfile(profile_image);
    while (profile_name)
    {
        profile = GetImageProfile(profile_image, profile_name);
        if (profile)
        {
            (void) ProfileImage(image, profile_name, GetStringInfoDatum(profile), GetStringInfoLength(profile), MagickFalse);
            if (rm_should_raise_exception(&image->exception, RetainExceptionRetention))
            {
                break;
            }
        }
        profile_name = GetNextImageProfile(profile_image);
    }

    (void) DestroyImage(profile_image);
    (void) DestroyExceptionInfo(exception);
    rm_check_image_exception(image, RetainOnError);

    return self;
}

#affine_transform(affine) ⇒ Object

Transform an image as dictated by the affine matrix argument.

Ruby usage:

- @verbatim Image#affine_transform(affine_matrix) @endverbatim

Parameters:

  • self

    this object

  • affine

    the affine matrix

Returns:

  • a new image



709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
# File 'ext/RMagick/rmimage.c', line 709

VALUE
Image_affine_transform(VALUE self, VALUE affine)
{
    Image *image, *new_image;
    ExceptionInfo *exception;
    AffineMatrix matrix;

    image = rm_check_destroyed(self);

    // Convert Magick::AffineMatrix to AffineMatrix structure.
    Export_AffineMatrix(&matrix, affine);

    exception = AcquireExceptionInfo();
    new_image = AffineTransformImage(image, &matrix, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#alpha(*args) ⇒ Object

Calls SetImageAlphaChannel.

Ruby usage:

- @verbatim Image#alpha(type) @endverbatim

Notes:

- Replaces matte=, alpha=
- Originally there was an alpha attribute getter and setter. These are
  replaced with alpha? and alpha(type). We still define (but don't
  document) alpha=. For backward compatibility, if this method is called
  without an argument, make it act like the old alpha getter and return
  true if the matte channel is active, false otherwise.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • the type (or true/false if called without an argument, see above)



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
# File 'ext/RMagick/rmimage.c', line 627

VALUE
Image_alpha(int argc, VALUE *argv, VALUE self)
{
    Image *image;
    AlphaChannelOption alpha;


    // For backward compatibility, make alpha() act like alpha?
    if (argc == 0)
    {
        return Image_alpha_q(self);
    }
    else if (argc > 1)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
    }


    image = rm_check_frozen(self);
    VALUE_TO_ENUM(argv[0], alpha, AlphaChannelOption);

    (void) SetImageAlphaChannel(image, alpha);
    rm_check_image_exception(image, RetainOnError);
    return argv[0];
}

#alpha?Boolean

Determine whether the image’s alpha channel is activated.

Ruby usage:

- @verbatim Image#alpha? @endverbatim

Notes:

- Replaces Image#matte

Parameters:

  • self

    this object

Returns:

  • (Boolean)

    true if the image’s alpha channel is activated



667
668
669
670
671
672
# File 'ext/RMagick/rmimage.c', line 667

VALUE
Image_alpha_q(VALUE self)
{
    Image *image = rm_check_destroyed(self);
    return GetImageAlphaChannel(image) ? Qtrue : Qfalse;
}

#annotate(draw, width, height, x, y, text, &block) ⇒ Object

Provide an alternate version of Draw#annotate, for folks who want to find it in this class.



777
778
779
780
781
# File 'lib/rmagick_internal.rb', line 777

def annotate(draw, width, height, x, y, text, &block)
  check_destroyed
  draw.annotate(self, width, height, x, y, text, &block)
  self
end

#auto_gamma_channel(*args) ⇒ Object

Get/set the auto Gamma channel

Ruby usage:

- @verbatim Image#auto_gamma_channel @endverbatim
- @verbatim Image#auto_gamma_channel channel @endverbatim
- @verbatim Image#auto_gamma_channel channel, ... @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



941
942
943
944
945
# File 'ext/RMagick/rmimage.c', line 941

VALUE
Image_auto_gamma_channel(int argc, VALUE *argv, VALUE self)
{
    return auto_channel(argc, argv, self, AutoGammaImageChannel);
}

#auto_level_channel(*args) ⇒ Object

Get/set the auto level channel

Ruby usage:

- @verbatim Image#auto_level_channel @endverbatim
- @verbatim Image#auto_level_channel channel @endverbatim
- @verbatim Image#auto_level_channel channel, ... @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



962
963
964
965
966
# File 'ext/RMagick/rmimage.c', line 962

VALUE
Image_auto_level_channel(int argc, VALUE *argv, VALUE self)
{
    return auto_channel(argc, argv, self, AutoLevelImageChannel);
}

#auto_orientObject

Implement mogrify’s -auto_orient option automatically orient image based on EXIF orientation value.

Ruby usage:

- @verbatim Image#auto_orient @endverbatim

Parameters:

  • self

    this object

Returns:

  • a new image

See Also:

  • (in ImageMagick 6.2.8)


1048
1049
1050
1051
1052
1053
# File 'ext/RMagick/rmimage.c', line 1048

VALUE
Image_auto_orient(VALUE self)
{
    (void) rm_check_destroyed(self);
    return auto_orient(False, self);
}

#auto_orient!Object

Implement mogrify’s -auto_orient option automatically orient image based on EXIF orientation value.

Ruby usage:

- @verbatim Image#auto_orient! @endverbatim

Parameters:

  • self

    this object

Returns:

  • nil if the image is already properly oriented, otherwise self



1066
1067
1068
1069
1070
1071
# File 'ext/RMagick/rmimage.c', line 1066

VALUE
Image_auto_orient_bang(VALUE self)
{
    (void) rm_check_frozen(self);
    return auto_orient(True, self);
}

#bilevel_channel(*args) ⇒ Object

Create a bilevel image.

Ruby usage:

- @verbatim Image#bilevel_channel(threshold) @endverbatim
- @verbatim Image#bilevel_channel(threshold, channel) @endverbatim

Notes:

- If no channel is specified AllChannels is used

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
# File 'ext/RMagick/rmimage.c', line 1223

VALUE
Image_bilevel_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    ChannelType channels;
    double threshold;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);

    if (argc > 1)
    {
        raise_ChannelType_error(argv[argc-1]);
    }
    if (argc == 0)
    {
        rb_raise(rb_eArgError, "no threshold specified");
    }

    threshold = NUM2DBL(argv[0]);
    new_image = rm_clone_image(image);

    (void)BilevelImageChannel(new_image, channels, threshold);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#black_threshold(*args) ⇒ Object

Call BlackThresholdImage.

Ruby usage:

- @verbatim Image#black_threshold(red) @endverbatim
- @verbatim Image#black_threshold(red, green) @endverbatim
- @verbatim Image#black_threshold(red, green, blue) @endverbatim
- @verbatim Image#black_threshold(red, green, blue, alpha: alpha) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:

  • threshold_image
  • Image_white_threshold


1327
1328
1329
1330
1331
# File 'ext/RMagick/rmimage.c', line 1327

VALUE
Image_black_threshold(int argc, VALUE *argv, VALUE self)
{
    return threshold_image(argc, argv, self, BlackThresholdImage);
}

#blend(*args) ⇒ Object

Corresponds to the composite -blend operation.

Ruby usage:

- @verbatim Image#blend(overlay, src_percent, dst_percent) @endverbatim
- @verbatim Image#blend(overlay, src_percent, dst_percent, x_offset) @endverbatim
- @verbatim Image#blend(overlay, src_percent, dst_percent, x_offset, y_offset) @endverbatim
- @verbatim Image#dissolve(overlay, src_percent, dst_percent, gravity) @endverbatim
- @verbatim Image#dissolve(overlay, src_percent, dst_percent, gravity, x_offset) @endverbatim
- @verbatim Image#dissolve(overlay, src_percent, dst_percent, gravity, x_offset, y_offset) @endverbatim

Notes:

- Default x_offset is 0
- Default y_offset is 0
- Percent can be a number or a string in the form "NN%"
- The default value for dst_percent is 100%-src_percent

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
# File 'ext/RMagick/rmimage.c', line 1665

VALUE
Image_blend(int argc, VALUE *argv, VALUE self)
{
    VALUE ovly;
    Image *image, *overlay;
    double src_percent, dst_percent;
    long x_offset = 0L, y_offset = 0L;

    image = rm_check_destroyed(self);

    if (argc < 1)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 to 6)", argc);
    }

    ovly = rm_cur_image(argv[0]);
    overlay = rm_check_destroyed(ovly);

    if (argc > 3)
    {
        get_composite_offsets(argc-3, &argv[3], image, overlay, &x_offset, &y_offset);
        // There must be 3 arguments left
        argc = 3;
    }

    switch (argc)
    {
        case 3:
            dst_percent = rm_percentage(argv[2],1.0) * 100.0;
            src_percent = rm_percentage(argv[1],1.0) * 100.0;
            break;
        case 2:
            src_percent = rm_percentage(argv[1],1.0) * 100.0;
            dst_percent = FMAX(100.0 - src_percent, 0);
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 to 6)", argc);
            break;
    }

    RB_GC_GUARD(ovly);

    return special_composite(image, overlay, src_percent, dst_percent
                             , x_offset, y_offset, BlendCompositeOp);

}

#blue_shift(*args) ⇒ Object

Call BlueShiftImage.

Ruby usage:

- @verbatim Image#blue_shift @endverbatim
- @verbatim Image#blue_shift(factor) @endverbatim

Notes:

- Default factor is 1.5

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
# File 'ext/RMagick/rmimage.c', line 1729

VALUE
Image_blue_shift(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    double factor = 1.5;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    switch (argc)
    {
        case 1:
            factor = NUM2DBL(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
            break;
    }


    exception = AcquireExceptionInfo();
    new_image = BlueShiftImage(image, factor, exception);
    CHECK_EXCEPTION();
    DestroyExceptionInfo(exception);

    return rm_image_new(new_image);
}

#blur_channel(*args) ⇒ Object

Call BlurImageChannel.

Ruby usage:

- @verbatim Image#blur_channel @endverbatim
- @verbatim Image#blur_channel(radius) @endverbatim
- @verbatim Image#blur_channel(radius, sigma) @endverbatim
- @verbatim Image#blur_channel(radius, sigma, channel) @endverbatim

Notes:

- Default radius is 0.0
- Default sigma is 1.0
- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
# File 'ext/RMagick/rmimage.c', line 1825

VALUE
Image_blur_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    ExceptionInfo *exception;
    ChannelType channels;
    double radius = 0.0, sigma = 1.0;

    image = rm_check_destroyed(self);

    channels = extract_channels(&argc, argv);

    // There can be 0, 1, or 2 remaining arguments.
    switch (argc)
    {
        case 2:
            sigma = NUM2DBL(argv[1]);
        case 1:
            radius = NUM2DBL(argv[0]);
        case 0:
            break;
        default:
            raise_ChannelType_error(argv[argc-1]);
    }

    exception = AcquireExceptionInfo();
    new_image = BlurImageChannel(image, channels, radius, sigma, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#blur_image(*args) ⇒ Object

Blur the image.

Ruby usage:

- @verbatim Image#blur_image @endverbatim
- @verbatim Image#blur_image(radius) @endverbatim
- @verbatim Image#blur_image(radius, sigma) @endverbatim

Notes:

- Default radius is 0.0
- Default sigma is 1.0
- The "blur" name is used for the attribute

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



1880
1881
1882
1883
1884
# File 'ext/RMagick/rmimage.c', line 1880

VALUE
Image_blur_image(int argc, VALUE *argv, VALUE self)
{
    return effect_image(self, argc, argv, BlurImage);
}

#border(width, height, color) ⇒ Object

Surrounds the image with a border of the specified width, height, and named color.

Ruby usage:

- @verbatim Image#border(width, height, color) @endverbatim

Parameters:

  • self

    this object

  • width

    the width of the border

  • height

    the height of the border

  • color

    the color of the border

Returns:

  • a new image

See Also:



1978
1979
1980
1981
1982
1983
# File 'ext/RMagick/rmimage.c', line 1978

VALUE
Image_border(VALUE self, VALUE width, VALUE height, VALUE color)
{
    (void) rm_check_destroyed(self);
    return border(False, self, width, height, color);
}

#border!(width, height, color) ⇒ Object

Surrounds the image with a border of the specified width, height, and named color.

Ruby usage:

- @verbatim Image#border!(width, height, color) @endverbatim

Parameters:

  • self

    this object

  • width

    the width of the border

  • height

    the height of the border

  • color

    the color of the border

Returns:

  • self

See Also:



1955
1956
1957
1958
1959
1960
# File 'ext/RMagick/rmimage.c', line 1955

VALUE
Image_border_bang(VALUE self, VALUE width, VALUE height, VALUE color)
{
    (void) rm_check_frozen(self);
    return border(True, self, width, height, color);
}

#change_geometry(geom_arg) ⇒ Object

parse geometry string, compute new image geometry.

Ruby usage:

- @verbatim Image#change_geometry(geometry_string) { |cols, rows, image| } @endverbatim

Parameters:

  • self

    this object

  • geom_arg

    the geometry string

Returns:

  • new image geometry



2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
# File 'ext/RMagick/rmimage.c', line 2131

VALUE
Image_change_geometry(VALUE self, VALUE geom_arg)
{
    Image *image;
    RectangleInfo rect;
    VALUE geom_str;
    char *geometry;
    unsigned int flags;
    VALUE ary;

    image = rm_check_destroyed(self);
    geom_str = rm_to_s(geom_arg);
    geometry = StringValuePtr(geom_str);

    memset(&rect, 0, sizeof(rect));

    SetGeometry(image, &rect);
    flags = ParseMetaGeometry(geometry, &rect.x,&rect.y, &rect.width,&rect.height);
    if (flags == NoValue)
    {
        rb_raise(rb_eArgError, "invalid geometry string `%s'", geometry);
    }

    ary = rb_ary_new2(3);
    rb_ary_store(ary, 0, ULONG2NUM(rect.width));
    rb_ary_store(ary, 1, ULONG2NUM(rect.height));
    rb_ary_store(ary, 2, self);

    RB_GC_GUARD(geom_str);
    RB_GC_GUARD(ary);

    return rb_yield(ary);
}

#change_geometry!(geom_arg) ⇒ Object

parse geometry string, compute new image geometry.

Ruby usage:

- @verbatim Image#change_geometry(geometry_string) { |cols, rows, image| } @endverbatim

Parameters:

  • self

    this object

  • geom_arg

    the geometry string

Returns:

  • new image geometry



2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
# File 'ext/RMagick/rmimage.c', line 2131

VALUE
Image_change_geometry(VALUE self, VALUE geom_arg)
{
    Image *image;
    RectangleInfo rect;
    VALUE geom_str;
    char *geometry;
    unsigned int flags;
    VALUE ary;

    image = rm_check_destroyed(self);
    geom_str = rm_to_s(geom_arg);
    geometry = StringValuePtr(geom_str);

    memset(&rect, 0, sizeof(rect));

    SetGeometry(image, &rect);
    flags = ParseMetaGeometry(geometry, &rect.x,&rect.y, &rect.width,&rect.height);
    if (flags == NoValue)
    {
        rb_raise(rb_eArgError, "invalid geometry string `%s'", geometry);
    }

    ary = rb_ary_new2(3);
    rb_ary_store(ary, 0, ULONG2NUM(rect.width));
    rb_ary_store(ary, 1, ULONG2NUM(rect.height));
    rb_ary_store(ary, 2, self);

    RB_GC_GUARD(geom_str);
    RB_GC_GUARD(ary);

    return rb_yield(ary);
}

#changed?Boolean

Return true if any pixel in the image has been altered since the image was constituted.

Ruby usage:

- @verbatim Image#changed? @endverbatim

Parameters:

  • self

    this object

Returns:

  • (Boolean)

    true if altered, false otherwise



2176
2177
2178
2179
2180
2181
2182
# File 'ext/RMagick/rmimage.c', line 2176

VALUE
Image_changed_q(VALUE self)
{
    Image *image = rm_check_destroyed(self);
    VALUE okay = IsTaintImage(image) ? Qtrue : Qfalse;
    return okay;
}

#channel(channel_arg) ⇒ Object

Extract a channel from the image. A channel is a particular color component of each pixel in the image.

Ruby usage:

- @verbatim Image#channel @endverbatim

Parameters:

  • self

    this object

  • channel_arg

    the type of the channel to extract

Returns:

  • the channel of the specified type



2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
# File 'ext/RMagick/rmimage.c', line 2196

VALUE
Image_channel(VALUE self, VALUE channel_arg)
{
    Image *image, *new_image;
    ChannelType channel;

    image = rm_check_destroyed(self);

    VALUE_TO_ENUM(channel_arg, channel, ChannelType);

    new_image = rm_clone_image(image);

    (void) SeparateImageChannel(new_image, channel);

    rm_check_image_exception(new_image, DestroyOnError);
    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#channel_compare(*args) ⇒ Object

Compare one or more channels in two images and returns the specified distortion metric and a comparison image.

Ruby usage:

- @verbatim Image#compare_channel(ref_image, metric) { optional arguments } @endverbatim
- @verbatim Image#compare_channel(ref_image, metric, channel) { optional arguments } @endverbatim
- @verbatim Image#compare_channel(ref_image, metric, channel, ...) { optional arguments } @endverbatim

Notes:

- If no channels are specified, the default is AllChannels. That case is
  the equivalent of the CompareImages method in ImageMagick.
- Originally this method was called channel_compare, but that doesn't match
  the general naming convention that methods which accept multiple optional
  ChannelType arguments have names that end in _channel. So I renamed the
  method to compare_channel but kept channel_compare as an alias.
- The optional arguments are specified thusly:
  - self.highlight_color color
  - self.lowlight-color color
  where color is either a color name or a Pixel.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • an array of [difference_image,distortion]



3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
# File 'ext/RMagick/rmimage.c', line 3238

VALUE
Image_compare_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *r_image, *difference_image;
    double distortion;
    VALUE ary, ref;
    MetricType metric_type;
    ChannelType channels;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    channels = extract_channels(&argc, argv);

    if (argc > 2)
    {
        raise_ChannelType_error(argv[argc-1]);
    }
    if (argc != 2)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or more)", argc);
    }

    rm_get_optional_arguments(self);

    ref = rm_cur_image(argv[0]);
    r_image = rm_check_destroyed(ref);

    VALUE_TO_ENUM(argv[1], metric_type, MetricType);

    exception = AcquireExceptionInfo();
    difference_image = CompareImageChannels(image, r_image, channels, metric_type, &distortion, exception);
    rm_check_exception(exception, difference_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(difference_image);

    ary = rb_ary_new2(2);
    rb_ary_store(ary, 0, rm_image_new(difference_image));
    rb_ary_store(ary, 1, rb_float_new(distortion));

    RB_GC_GUARD(ary);
    RB_GC_GUARD(ref);

    return ary;
}

#channel_depth(*args) ⇒ Object

GetImageChannelDepth.

Ruby usage:

- @verbatim Image#channel_depth @endverbatim
- @verbatim Image#channel_depth(channel_depth) @endverbatim

Notes:

- Default channel_depth is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • the channel depth



2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
# File 'ext/RMagick/rmimage.c', line 2232

VALUE
Image_channel_depth(int argc, VALUE *argv, VALUE self)
{
    Image *image;
    ChannelType channels;
    unsigned long channel_depth;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);

    // Ensure all arguments consumed.
    if (argc > 0)
    {
        raise_ChannelType_error(argv[argc-1]);
    }

    exception = AcquireExceptionInfo();

    channel_depth = GetImageChannelDepth(image, channels, exception);
    CHECK_EXCEPTION()

    (void) DestroyExceptionInfo(exception);

    return ULONG2NUM(channel_depth);
}

#channel_entropy(*args) ⇒ Object

Return an array of the entropy for the channel.

Ruby usage:

- @verbatim Image#channel_entropy @endverbatim
- @verbatim Image#channel_entropy(channel) @endverbatim

Notes:

- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • an array [mean, std. deviation]



2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
# File 'ext/RMagick/rmimage.c', line 2379

VALUE
Image_channel_entropy(int argc, VALUE *argv, VALUE self)
{
#if defined(HAVE_GETIMAGECHANNELENTROPY)
    Image *image;
    ChannelType channels;
    ExceptionInfo *exception;
    double entropy;
    VALUE ary;

    image = rm_check_destroyed(self);

    channels = extract_channels(&argc, argv);

    // Ensure all arguments consumed.
    if (argc > 0)
    {
        raise_ChannelType_error(argv[argc-1]);
    }

    exception = AcquireExceptionInfo();
    (void) GetImageChannelEntropy(image, channels, &entropy, exception);
    CHECK_EXCEPTION()

    (void) DestroyExceptionInfo(exception);

    ary = rb_ary_new2(1);
    rb_ary_store(ary, 0, rb_float_new(entropy));

    RB_GC_GUARD(ary);

    return ary;
#else
    rm_not_implemented();
    return (VALUE) 0;
    argc = argc;
    argv = argv;
    self = self;
#endif
}

#channel_extrema(*args) ⇒ min, max

Return an array [min, max] where ‘min’ and ‘max’ are the minimum and maximum values of all channels.

Ruby usage:

- @verbatim Image#channel_extrema @endverbatim
- @verbatim Image#channel_extrema(channel) @endverbatim

Notes:

- Default channel is AllChannels
- GM's implementation is very different from ImageMagick. This method
  follows the IM API very closely and then shoehorn's the GM API to
  more-or-less fit. Note that IM allows you to specify more than one
  channel argument. GM does not.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • (min, max)

    of the channel



2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
# File 'ext/RMagick/rmimage.c', line 2280

VALUE
Image_channel_extrema(int argc, VALUE *argv, VALUE self)
{
    Image *image;
    ChannelType channels;
    ExceptionInfo *exception;
    size_t min, max;
    VALUE ary;

    image = rm_check_destroyed(self);

    channels = extract_channels(&argc, argv);

    // Ensure all arguments consumed.
    if (argc > 0)
    {
        raise_ChannelType_error(argv[argc-1]);
    }

    exception = AcquireExceptionInfo();
    (void) GetImageChannelExtrema(image, channels, &min, &max, exception);
    CHECK_EXCEPTION()

    (void) DestroyExceptionInfo(exception);

    ary = rb_ary_new2(2);
    rb_ary_store(ary, 0, ULONG2NUM(min));
    rb_ary_store(ary, 1, ULONG2NUM(max));

    RB_GC_GUARD(ary);

    return ary;
}

#channel_mean(*args) ⇒ Object

Return an array of the mean and standard deviation for the channel.

Ruby usage:

- @verbatim Image#channel_mean @endverbatim
- @verbatim Image#channel_mean(channel) @endverbatim

Notes:

- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • an array [mean, std. deviation]



2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
# File 'ext/RMagick/rmimage.c', line 2330

VALUE
Image_channel_mean(int argc, VALUE *argv, VALUE self)
{
    Image *image;
    ChannelType channels;
    ExceptionInfo *exception;
    double mean, stddev;
    VALUE ary;

    image = rm_check_destroyed(self);

    channels = extract_channels(&argc, argv);

    // Ensure all arguments consumed.
    if (argc > 0)
    {
        raise_ChannelType_error(argv[argc-1]);
    }

    exception = AcquireExceptionInfo();
    (void) GetImageChannelMean(image, channels, &mean, &stddev, exception);
    CHECK_EXCEPTION()

    (void) DestroyExceptionInfo(exception);

    ary = rb_ary_new2(2);
    rb_ary_store(ary, 0, rb_float_new(mean));
    rb_ary_store(ary, 1, rb_float_new(stddev));

    RB_GC_GUARD(ary);

    return ary;
}

#charcoal(*args) ⇒ Object

Return a new image that is a copy of the input image with the edges highlighted.

Ruby usage:

- @verbatim Image#charcoal @endverbatim
- @verbatim Image#charcoal(radius) @endverbatim
- @verbatim Image#charcoal(radius, sigma) @endverbatim

Notes:

- Default radius is 0.0
- Default sigma is 1.0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



2439
2440
2441
2442
2443
# File 'ext/RMagick/rmimage.c', line 2439

VALUE
Image_charcoal(int argc, VALUE *argv, VALUE self)
{
    return effect_image(self, argc, argv, CharcoalImage);
}

#check_destroyedObject

If the target image has been destroyed, raise Magick::DestroyedImageError.

Ruby usage:

- @verbatim Image#check_destroyed @endverbatim

Parameters:

  • self

    this object

Returns:

  • nil



2456
2457
2458
2459
2460
2461
# File 'ext/RMagick/rmimage.c', line 2456

VALUE
Image_check_destroyed(VALUE self)
{
    (void) rm_check_destroyed(self);
    return Qnil;
}

#chop(x, y, width, height) ⇒ Object

Remove a region of an image and collapses the image to occupy the removed portion.

Ruby usage:

- @verbatim Image#chop @endverbatim

Parameters:

  • self

    this object

  • x

    x position of start of region

  • y

    y position of start of region

  • width

    width of region

  • height

    height of region

Returns:

  • a new image



2478
2479
2480
2481
2482
2483
# File 'ext/RMagick/rmimage.c', line 2478

VALUE
Image_chop(VALUE self, VALUE x, VALUE y, VALUE width, VALUE height)
{
    (void) rm_check_destroyed(self);
    return xform_image(False, self, x, y, width, height, ChopImage);
}

#cloneObject

Copy an image, along with its frozen and tainted state.

Ruby usage:

- @verbatim Image#clone @endverbatim

Parameters:

  • self

    this object

Returns:

  • a clone of this object



2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
# File 'ext/RMagick/rmimage.c', line 2533

VALUE
Image_clone(VALUE self)
{
    VALUE clone;

    clone = Image_dup(self);
    if (OBJ_FROZEN(self))
    {
        OBJ_FREEZE(clone);
    }

    RB_GC_GUARD(clone);

    return clone;
}

#clut_channel(*args) ⇒ Object

Equivalent to -clut option.

Ruby usage:

- @verbatim Image#clut_channel @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • self



2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
# File 'ext/RMagick/rmimage.c', line 2561

VALUE
Image_clut_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *clut;
    ChannelType channels;
    MagickBooleanType okay;

    image = rm_check_frozen(self);

    // check_destroyed before confirming the arguments
    if (argc >= 1)
    {
        (void) rm_check_destroyed(argv[0]);
        channels = extract_channels(&argc, argv);
        if (argc != 1)
        {
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or more)", argc);
        }
    }
    else
    {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or more)", argc);
    }

    Data_Get_Struct(argv[0], Image, clut);

    okay = ClutImageChannel(image, channels, clut);
    rm_check_image_exception(image, RetainOnError);
    rm_check_image_exception(clut, RetainOnError);
    if (!okay)
    {
        rb_raise(rb_eRuntimeError, "ClutImageChannel failed.");
    }

    return self;
}

#color_fill_to_border(x, y, fill) ⇒ Object

Set all pixels that are neighbors of x,y and are not the border color to the fill color



799
800
801
# File 'lib/rmagick_internal.rb', line 799

def color_fill_to_border(x, y, fill)
  color_flood_fill(border_color, fill, x, y, Magick::FillToBorderMethod)
end

#color_flood_fill(target_color, fill_color, xv, yv, method) ⇒ Object

Change the color value of any pixel that matches target_color and is an immediate neighbor.

Ruby usage:

- @verbatim Image#color_flood_fill(target_color, fill_color, x, y, method) @endverbatim

Notes:

- Use fuzz= to specify the tolerance amount
- Accepts either the FloodfillMethod or the FillToBorderMethod

Parameters:

  • self

    this object

  • target_color

    the color

  • fill_color

    the color to fill

  • xv

    the x position

  • yv

    the y position

  • method

    the method to call

Returns:

  • a new image

See Also:

  • Image_opaque


2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
# File 'ext/RMagick/rmimage.c', line 2840

VALUE
Image_color_flood_fill( VALUE self, VALUE target_color, VALUE fill_color
                        , VALUE xv, VALUE yv, VALUE method)
{
    Image *image, *new_image;
    PixelColor target;
    DrawInfo *draw_info;
    PixelColor fill;
    long x, y;
    int fill_method;
    MagickPixel target_mpp;
    MagickBooleanType invert;

    image = rm_check_destroyed(self);

    // The target and fill args can be either a color name or
    // a Magick::Pixel.
    Color_to_PixelColor(&target, target_color);
    Color_to_PixelColor(&fill, fill_color);

    x = NUM2LONG(xv);
    y = NUM2LONG(yv);
    if ((unsigned long)x > image->columns || (unsigned long)y > image->rows)
    {
        rb_raise(rb_eArgError, "target out of range. %lux%lu given, image is %lux%lu"
                 , x, y, image->columns, image->rows);
    }

    VALUE_TO_ENUM(method, fill_method, PaintMethod);
    if (!(fill_method == FloodfillMethod || fill_method == FillToBorderMethod))
    {
        rb_raise(rb_eArgError, "paint method must be FloodfillMethod or "
                 "FillToBorderMethod (%d given)", fill_method);
    }

    draw_info = CloneDrawInfo(NULL, NULL);
    if (!draw_info)
    {
        rb_raise(rb_eNoMemError, "not enough memory to continue");
    }
    draw_info->fill = fill;

    new_image = rm_clone_image(image);

    rm_init_magickpixel(new_image, &target_mpp);
    if (fill_method == FillToBorderMethod)
    {
        invert = MagickTrue;
        target_mpp.red   = (MagickRealType) image->border_color.red;
        target_mpp.green = (MagickRealType) image->border_color.green;
        target_mpp.blue  = (MagickRealType) image->border_color.blue;
    }
    else
    {
        invert = MagickFalse;
        target_mpp.red   = (MagickRealType) target.red;
        target_mpp.green = (MagickRealType) target.green;
        target_mpp.blue  = (MagickRealType) target.blue;
    }

    (void) FloodfillPaintImage(new_image, DefaultChannels, draw_info, &target_mpp, x, y, invert);

    (void) DestroyDrawInfo(draw_info);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#color_floodfill(x, y, fill) ⇒ Object

Set all pixels that have the same color as the pixel at x,y and are neighbors to the fill color



792
793
794
795
# File 'lib/rmagick_internal.rb', line 792

def color_floodfill(x, y, fill)
  target = pixel_color(x, y)
  color_flood_fill(target, fill, x, y, Magick::FloodfillMethod)
end

#color_histogramObject

Call GetImageHistogram.

Ruby usage:

- @verbatim Image_color_histogram(VALUE self); @endverbatim

Notes:

- returns hash @verbatim {aPixel=>count} @endverbatim

Parameters:

  • self

    this object

Returns:

  • a histogram



2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
# File 'ext/RMagick/rmimage.c', line 2611

VALUE
Image_color_histogram(VALUE self)
{
    Image *image, *dc_copy = NULL;
    VALUE hash, pixel;
    size_t x, colors;
    ColorPacket *histogram;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    // If image not DirectClass make a DirectClass copy.
    if (image->storage_class != DirectClass)
    {
        dc_copy = rm_clone_image(image);
        (void) SetImageStorageClass(dc_copy, DirectClass);
        image = dc_copy;
    }

    exception = AcquireExceptionInfo();
    histogram = GetImageHistogram(image, &colors, exception);

    if (histogram == NULL)
    {
        if (dc_copy)
        {
            (void) DestroyImage(dc_copy);
        }
        rb_raise(rb_eNoMemError, "not enough memory to continue");
    }
    if (rm_should_raise_exception(exception, DestroyExceptionRetention))
    {
        (void) RelinquishMagickMemory(histogram);
        if (dc_copy)
        {
            (void) DestroyImage(dc_copy);
        }

        rm_raise_exception(exception);
    }

    hash = rb_hash_new();
    for (x = 0; x < colors; x++)
    {
        pixel = Pixel_from_PixelColor(&histogram[x].pixel);
        (void) rb_hash_aset(hash, pixel, ULONG2NUM((unsigned long)histogram[x].count));
    }

    /*
        Christy evidently didn't agree with Bob's memory management.
    */
    (void) RelinquishMagickMemory(histogram);

    if (dc_copy)
    {
        // Do not trace destruction
        (void) DestroyImage(dc_copy);
    }

    RB_GC_GUARD(hash);
    RB_GC_GUARD(pixel);

    return hash;
}

#color_point(x, y, fill) ⇒ Object

Set the color at x,y



784
785
786
787
788
# File 'lib/rmagick_internal.rb', line 784

def color_point(x, y, fill)
  f = copy
  f.pixel_color(x, y, fill)
  f
end

#color_reset!(fill) ⇒ Object

Set all pixels to the fill color. Very similar to Image#erase! Accepts either String or Pixel arguments



805
806
807
808
809
810
811
812
813
814
815
816
817
# File 'lib/rmagick_internal.rb', line 805

def color_reset!(fill)
  save = background_color
  # Change the background color _outside_ the begin block
  # so that if this object is frozen the exeception will be
  # raised before we have to handle it explicitly.
  self.background_color = fill
  begin
    erase!
  ensure
    self.background_color = save
  end
  self
end

#colorize(*args) ⇒ Object

Blend the fill color specified by “target” with each pixel in the image. Specify the percentage blend for each r, g, b component.

Ruby usage:

- @verbatim Image#colorize(r, g, b, target) @endverbatim
- @verbatim Image#colorize(r, g, b, matte, target) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
# File 'ext/RMagick/rmimage.c', line 2922

VALUE
Image_colorize(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    double red, green, blue, matte;
    char opacity[50];
    PixelColor target;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    if (argc == 4)
    {
        red   = floor(100*NUM2DBL(argv[0])+0.5);
        green = floor(100*NUM2DBL(argv[1])+0.5);
        blue  = floor(100*NUM2DBL(argv[2])+0.5);
        Color_to_PixelColor(&target, argv[3]);
        sprintf(opacity, "%f/%f/%f", red, green, blue);
    }
    else if (argc == 5)
    {
        red   = floor(100*NUM2DBL(argv[0])+0.5);
        green = floor(100*NUM2DBL(argv[1])+0.5);
        blue  = floor(100*NUM2DBL(argv[2])+0.5);
        matte = floor(100*NUM2DBL(argv[3])+0.5);
        Color_to_PixelColor(&target, argv[4]);
        sprintf(opacity, "%f/%f/%f/%f", red, green, blue, matte);
    }
    else
    {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 4 or 5)", argc);
    }

    exception = AcquireExceptionInfo();
    new_image = ColorizeImage(image, opacity, target, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#colormap(*args) ⇒ Object

Return the color in the colormap at the specified index. If a new color is specified, replaces the color at the index with the new color.

Ruby usage:

- @verbatim Image#colormap(index) @endverbatim
- @verbatim Image#colormap(index, new-color) @endverbatim

Notes:

- The "new-color" argument can be either a color name or a Magick::Pixel.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • the name of the color



2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
# File 'ext/RMagick/rmimage.c', line 2983

VALUE
Image_colormap(int argc, VALUE *argv, VALUE self)
{
    Image *image;
    unsigned long idx;
    PixelColor color, new_color;

    image = rm_check_destroyed(self);

    // We can handle either 1 or 2 arguments. Nothing else.
    if (argc == 0 || argc > 2)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
    }

    idx = NUM2ULONG(argv[0]);
    if (idx > QuantumRange)
    {
        rb_raise(rb_eIndexError, "index out of range");
    }

    // If this is a simple "get" operation, ensure the image has a colormap.
    if (argc == 1)
    {
        if (!image->colormap)
        {
            rb_raise(rb_eIndexError, "image does not contain a colormap");
        }
        // Validate the index

        if (idx > image->colors-1)
        {
            rb_raise(rb_eIndexError, "index out of range");
        }
        return rm_pixelcolor_to_color_name(image, &image->colormap[idx]);
    }

    // This is a "set" operation. Things are different.

    rb_check_frozen(self);

    // Replace with new color? The arg can be either a color name or
    // a Magick::Pixel.
    Color_to_PixelColor(&new_color, argv[1]);

    // Handle no colormap or current colormap too small.
    if (!image->colormap || idx > image->colors-1)
    {
        PixelColor black;
        unsigned long i;

        memset(&black, 0, sizeof(black));

        if (!image->colormap)
        {
            image->colormap = (PixelColor *)magick_safe_malloc((idx+1), sizeof(PixelColor));
            image->colors = 0;
        }
        else
        {
            image->colormap = (PixelColor *)magick_safe_realloc(image->colormap, (idx+1), sizeof(PixelColor));
        }

        for (i = image->colors; i < idx; i++)
        {
            image->colormap[i] = black;
        }
        image->colors = idx+1;
    }

    // Save the current color so we can return it. Set the new color.
    color = image->colormap[idx];
    image->colormap[idx] = new_color;

    return rm_pixelcolor_to_color_name(image, &color);
}

#compare_channel(*args) ⇒ Object

Compare one or more channels in two images and returns the specified distortion metric and a comparison image.

Ruby usage:

- @verbatim Image#compare_channel(ref_image, metric) { optional arguments } @endverbatim
- @verbatim Image#compare_channel(ref_image, metric, channel) { optional arguments } @endverbatim
- @verbatim Image#compare_channel(ref_image, metric, channel, ...) { optional arguments } @endverbatim

Notes:

- If no channels are specified, the default is AllChannels. That case is
  the equivalent of the CompareImages method in ImageMagick.
- Originally this method was called channel_compare, but that doesn't match
  the general naming convention that methods which accept multiple optional
  ChannelType arguments have names that end in _channel. So I renamed the
  method to compare_channel but kept channel_compare as an alias.
- The optional arguments are specified thusly:
  - self.highlight_color color
  - self.lowlight-color color
  where color is either a color name or a Pixel.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • an array of [difference_image,distortion]



3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
# File 'ext/RMagick/rmimage.c', line 3238

VALUE
Image_compare_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *r_image, *difference_image;
    double distortion;
    VALUE ary, ref;
    MetricType metric_type;
    ChannelType channels;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    channels = extract_channels(&argc, argv);

    if (argc > 2)
    {
        raise_ChannelType_error(argv[argc-1]);
    }
    if (argc != 2)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or more)", argc);
    }

    rm_get_optional_arguments(self);

    ref = rm_cur_image(argv[0]);
    r_image = rm_check_destroyed(ref);

    VALUE_TO_ENUM(argv[1], metric_type, MetricType);

    exception = AcquireExceptionInfo();
    difference_image = CompareImageChannels(image, r_image, channels, metric_type, &distortion, exception);
    rm_check_exception(exception, difference_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(difference_image);

    ary = rb_ary_new2(2);
    rb_ary_store(ary, 0, rm_image_new(difference_image));
    rb_ary_store(ary, 1, rb_float_new(distortion));

    RB_GC_GUARD(ary);
    RB_GC_GUARD(ref);

    return ary;
}

#composite(*args) ⇒ Object

Call CompositeImage.

Ruby usage:

- @verbatim Image#composite(image, x_off, y_off, composite_op) @endverbatim
- @verbatim Image#composite(image, gravity, composite_op) @endverbatim
- @verbatim Image#composite(image, gravity, x_off, y_off, composite_op) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:



3528
3529
3530
3531
3532
# File 'ext/RMagick/rmimage.c', line 3528

VALUE
Image_composite(int argc, VALUE *argv, VALUE self)
{
    return composite(False, argc, argv, self, DefaultChannels);
}

#composite!(*args) ⇒ Object

Call CompositeImage.

Ruby usage:

- @verbatim Image#composite!(image, x_off, y_off, composite_op) @endverbatim
- @verbatim Image#composite!(image, gravity, composite_op) @endverbatim
- @verbatim Image#composite!(image, gravity, x_off, y_off, composite_op) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • self

See Also:



3506
3507
3508
3509
3510
# File 'ext/RMagick/rmimage.c', line 3506

VALUE
Image_composite_bang(int argc, VALUE *argv, VALUE self)
{
    return composite(True, argc, argv, self, DefaultChannels);
}

#composite_affine(source, affine_matrix) ⇒ Object

Composite the source over the destination image as dictated by the affine transform.

Ruby usage:

- @verbatim Image#composite_affine(composite, affine_matrix) @endverbatim

Parameters:

  • self

    this object

  • source

    the source image

  • affine_matrix

    affine transform matrix

Returns:

  • a new image



3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
# File 'ext/RMagick/rmimage.c', line 3547

VALUE
Image_composite_affine(VALUE self, VALUE source, VALUE affine_matrix)
{
    Image *image, *composite_image, *new_image;
    AffineMatrix affine;

    image = rm_check_destroyed(self);
    composite_image = rm_check_destroyed(source);

    Export_AffineMatrix(&affine, affine_matrix);
    new_image = rm_clone_image(image);

    (void) DrawAffineImage(new_image, composite_image, &affine);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#composite_channel(*args) ⇒ Object

Call CompositeImageChannel.

Ruby usage:

- @verbatim Image#composite_channel(src_image, geometry, composite_operator) @endverbatim
- @verbatim Image#composite_channel(src_image, geometry, composite_operator, channel) @endverbatim
- @verbatim Image#composite_channel(src_image, geometry, composite_operator, channel, ...) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:



3620
3621
3622
3623
3624
# File 'ext/RMagick/rmimage.c', line 3620

VALUE
Image_composite_channel(int argc, VALUE *argv, VALUE self)
{
    return composite_channel(False, argc, argv, self);
}

#composite_channel!(*args) ⇒ Object

Call CompositeImageChannel.

Ruby usage:

- @verbatim Image#composite_channel!(src_image, geometry, composite_operator) @endverbatim
- @verbatim Image#composite_channel!(src_image, geometry, composite_operator, channel) @endverbatim
- @verbatim Image#composite_channel!(src_image, geometry, composite_operator, channel, ...) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • self

See Also:



3642
3643
3644
3645
3646
# File 'ext/RMagick/rmimage.c', line 3642

VALUE
Image_composite_channel_bang(int argc, VALUE *argv, VALUE self)
{
    return composite_channel(True, argc, argv, self);
}

#composite_mathematics(*args) ⇒ Object

Composite using MathematicsCompositeOp.

Ruby usage:

- @verbatim img.composite_mathematics(comp_img, A, B, C, D, gravity) @endverbatim
- @verbatim img.composite_mathematics(comp_img, A, B, C, D, x_off, y_off) @endverbatim
- @verbatim img.composite_mathematics(comp_img, A, B, C, D, gravity, x_off, y_off) @endverbatim

Notes:

- Default x_off is 0
- Default y_off is 0
- New in ImageMagick 6.5.4-3.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
# File 'ext/RMagick/rmimage.c', line 3667

VALUE
Image_composite_mathematics(int argc, VALUE *argv, VALUE self)
{
    Image *composite_image;
    VALUE args[5];
    signed long x_off = 0L;
    signed long y_off = 0L;
    GravityType gravity = NorthWestGravity;
    char compose_args[200];

    rm_check_destroyed(self);
    if (argc > 0)
    {
        composite_image = rm_check_destroyed(rm_cur_image(argv[0]));
    }

    switch (argc)
    {
        case 8:
            VALUE_TO_ENUM(argv[5], gravity, GravityType);
            x_off = NUM2LONG(argv[6]);
            y_off = NUM2LONG(argv[7]);
            break;
        case 7:
            x_off = NUM2LONG(argv[5]);
            y_off = NUM2LONG(argv[6]);
            break;
        case 6:
            VALUE_TO_ENUM(argv[5], gravity, GravityType);
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (got %d, expected 6 to 8)", argc);
            break;
    }


    (void) sprintf(compose_args, "%-.16g,%-.16g,%-.16g,%-.16g", NUM2DBL(argv[1]), NUM2DBL(argv[2]), NUM2DBL(argv[3]), NUM2DBL(argv[4]));
    SetImageArtifact(composite_image,"compose:args", compose_args);

    // Call composite(False, gravity, x_off, y_off, MathematicsCompositeOp, DefaultChannels)
    args[0] = argv[0];
    args[1] = GravityType_find(gravity);
    args[2] = LONG2FIX(x_off);
    args[3] = LONG2FIX(y_off);
    args[4] = CompositeOperator_find(MathematicsCompositeOp);

    return composite(False, 5, args, self, DefaultChannels);
}

#composite_tiled(*args) ⇒ Object

Emulate the -tile option to the composite command.

Ruby usage:

- @verbatim Image#composite_tiled(src) @endverbatim
- @verbatim Image#composite_tiled(src, composite_op) @endverbatim
- @verbatim Image#composite_tiled(src, composite_op, channel) @endverbatim
- @verbatim Image#composite_tiled(src, composite_op, channel, ...) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:



3817
3818
3819
3820
3821
# File 'ext/RMagick/rmimage.c', line 3817

VALUE
Image_composite_tiled(int argc, VALUE *argv, VALUE self)
{
    return composite_tiled(False, argc, argv, self);
}

#composite_tiled!(*args) ⇒ Object

Emulate the -tile option to the composite command.

Ruby usage:

- @verbatim Image#composite_tiled!(src) @endverbatim
- @verbatim Image#composite_tiled!(src, composite_op) @endverbatim
- @verbatim Image#composite_tiled!(src, composite_op, channel) @endverbatim
- @verbatim Image#composite_tiled!(src, composite_op, channel, ...) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • self

See Also:



3840
3841
3842
3843
3844
# File 'ext/RMagick/rmimage.c', line 3840

VALUE
Image_composite_tiled_bang(int argc, VALUE *argv, VALUE self)
{
    return composite_tiled(True, argc, argv, self);
}

#compress_colormap!Object

call CompressImageColormap.

Ruby usage:

- @verbatim Image#compress_colormap! @endverbatim

Notes:

- API was CompressColormap until 5.4.9

Parameters:

  • self

    this object

Returns:

  • self



3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
# File 'ext/RMagick/rmimage.c', line 3893

VALUE
Image_compress_colormap_bang(VALUE self)
{
    Image *image;
    MagickBooleanType okay;

    image = rm_check_frozen(self);
    okay = CompressImageColormap(image);
    rm_check_image_exception(image, RetainOnError);
    if (!okay)
    {
        rb_warning("CompressImageColormap failed (probably DirectClass image)");
    }

    return self;
}

#contrast(*args) ⇒ Object

Enhance 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.

Ruby usage:

- @verbatim Image#contrast @endverbatim
- @verbatim Image#contrast(sharpen) @endverbatim

Notes:

- Default sharpen is 0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
# File 'ext/RMagick/rmimage.c', line 4078

VALUE
Image_contrast(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    unsigned int sharpen = 0;

    image = rm_check_destroyed(self);
    if (argc > 1)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
    }
    else if (argc == 1)
    {
        sharpen = RTEST(argv[0]);
    }

    new_image = rm_clone_image(image);

    (void) ContrastImage(new_image, sharpen);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#contrast_stretch_channel(*args) ⇒ Object

Call ContrastStretchImageChannel.

Ruby usage:

- @verbatim Image#contrast_stretch_channel(black_point) @endverbatim
- @verbatim Image#contrast_stretch_channel(black_point, white_point) @endverbatim
- @verbatim Image#contrast_stretch_channel(black_point, white_point, channel) @endverbatim
- @verbatim Image#contrast_stretch_channel(black_point, white_point, channel, ...) @endverbatim

Notes:

- Default white_point is pixels-black_point
- Default channel is AllChannels
- Both black_point and white_point can be specified as Floats or as
  percentages, i.e. "10%"

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
# File 'ext/RMagick/rmimage.c', line 4187

VALUE
Image_contrast_stretch_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    ChannelType channels;
    double black_point, white_point;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);
    if (argc > 2)
    {
        raise_ChannelType_error(argv[argc-1]);
    }

    get_black_white_point(image, argc, argv, &black_point, &white_point);

    new_image = rm_clone_image(image);

    (void) ContrastStretchImageChannel(new_image, channels, black_point, white_point);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#convolve(order_arg, kernel_arg) ⇒ Object

Apply a custom convolution kernel to the image.

Ruby usage:

- @verbatim Image#convolve(order, kernel) @endverbatim

Parameters:

  • self

    this object

  • order_arg

    the number of rows and columns in the kernel

  • kernel_arg

    an order**2 array of doubles

Returns:

  • a new image



4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
# File 'ext/RMagick/rmimage.c', line 4301

VALUE
Image_convolve(VALUE self, VALUE order_arg, VALUE kernel_arg)
{
    Image *image, *new_image;
    int order;
    ExceptionInfo *exception;
    double *kernel;
    unsigned int x;

    image = rm_check_destroyed(self);

    order = NUM2INT(order_arg);

    if (order <= 0)
    {
        rb_raise(rb_eArgError, "order must be non-zero and positive");
    }

    kernel_arg = rb_Array(kernel_arg);
    rm_check_ary_len(kernel_arg, (long)(order*order));

    // Convert the kernel array argument to an array of doubles

    kernel = (double *)ALLOC_N(double, order*order);
    for (x = 0; x < order*order; x++)
    {
        VALUE element = rb_ary_entry(kernel_arg, (long)x);
        if (rm_check_num2dbl(element))
        {
            kernel[x] = NUM2DBL(element);
        }
        else
        {
            xfree((void *)kernel);
            rb_raise(rb_eTypeError, "type mismatch: %s given", rb_class2name(CLASS_OF(element)));
        }
    }

    exception = AcquireExceptionInfo();

    new_image = ConvolveImage(image, order, kernel, exception);
    xfree((void *)kernel);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#convolve_channel(*args) ⇒ Object

call ConvolveImageChannel.

Ruby usage:

- @verbatim Image#convolve_channel(order, kernel) @endverbatim
- @verbatim Image#convolve_channel(order, kernel, channel) @endverbatim
- @verbatim Image#convolve_channel(order, kernel, channel, ...) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
# File 'ext/RMagick/rmimage.c', line 4366

VALUE
Image_convolve_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    VALUE ary;
    int order;
    ChannelType channels;
    ExceptionInfo *exception;
    double *kernel;
    unsigned int x;

    image = rm_check_destroyed(self);

    channels = extract_channels(&argc, argv);

    // There are 2 required arguments.
    if (argc > 2)
    {
        raise_ChannelType_error(argv[argc-1]);
    }
    if (argc != 2)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or more)", argc);
    }

    order = NUM2INT(argv[0]);
    if (order <= 0)
    {
        rb_raise(rb_eArgError, "order must be non-zero and positive");
    }

    ary = argv[1];

    rm_check_ary_len(ary, (long)(order*order));

    kernel = ALLOC_N(double, (long)(order*order));

    // Convert the kernel array argument to an array of doubles
    for (x = 0; x < order*order; x++)
    {
        VALUE element = rb_ary_entry(ary, (long)x);
        if (rm_check_num2dbl(element))
        {
            kernel[x] = NUM2DBL(element);
        }
        else
        {
            xfree((void *)kernel);
            rb_raise(rb_eTypeError, "type mismatch: %s given", rb_class2name(CLASS_OF(element)));
        }
    }

    exception = AcquireExceptionInfo();

    new_image = ConvolveImageChannel(image, channels, order, kernel, exception);
    xfree((void *)kernel);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    RB_GC_GUARD(ary);

    return rm_image_new(new_image);
}

#copyObject

Alias for dup.

Ruby usage:

- @verbatim Image#copy @endverbatim

Parameters:

  • self

    this object

Returns:

  • a copy of self

See Also:

  • Image_dup


4445
4446
4447
4448
4449
# File 'ext/RMagick/rmimage.c', line 4445

VALUE
Image_copy(VALUE self)
{
    return rb_funcall(self, rm_ID_dup, 0);
}

#crop(*args) ⇒ Object

Extract a region of the image defined by width, height, x, y.

Ruby usage:

- @verbatim Image#crop(x, y, width, height) @endverbatim
- @verbatim Image#crop(gravity, width, height) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:

  • cropper
  • Image_crop_bang


4491
4492
4493
4494
4495
4496
# File 'ext/RMagick/rmimage.c', line 4491

VALUE
Image_crop(int argc, VALUE *argv, VALUE self)
{
    (void) rm_check_destroyed(self);
    return cropper(False, argc, argv, self);
}

#crop!(*args) ⇒ Object

Extract a region of the image defined by width, height, x, y.

Ruby usage:

- @verbatim Image#crop!(x, y, width, height) @endverbatim
- @verbatim Image#crop!(gravity, width, height) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • self

See Also:

  • cropper
  • Image_crop


4513
4514
4515
4516
4517
4518
# File 'ext/RMagick/rmimage.c', line 4513

VALUE
Image_crop_bang(int argc, VALUE *argv, VALUE self)
{
    (void) rm_check_frozen(self);
    return cropper(True, argc, argv, self);
}

#cur_imageObject

Used by ImageList methods - see ImageList#cur_image



820
821
822
# File 'lib/rmagick_internal.rb', line 820

def cur_image
  self
end

#cycle_colormap(amount) ⇒ Object

Call CycleColormapImage.

Ruby usage:

- @verbatim Image#cycle_colormap @endverbatim

Parameters:

  • self

    this object

  • amount

    amount to cycle the colormap

Returns:

  • a new image



4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
# File 'ext/RMagick/rmimage.c', line 4531

VALUE
Image_cycle_colormap(VALUE self, VALUE amount)
{
    Image *image, *new_image;
    int amt;

    amt = NUM2INT(amount);

    image = rm_check_destroyed(self);
    new_image = rm_clone_image(image);

    (void) CycleColormapImage(new_image, amt);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#decipher(passphrase) ⇒ Object

call DecipherImage.

Ruby usage:

- @verbatim Image#decipher(passphrase) @endverbatim

Parameters:

  • self

    this object

  • passphrase

    the passphrase

Returns:

  • a new deciphered image



4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
# File 'ext/RMagick/rmimage.c', line 4656

VALUE
Image_decipher(VALUE self, VALUE passphrase)
{
    Image *image, *new_image;
    char *pf;
    ExceptionInfo *exception;
    MagickBooleanType okay;

    image = rm_check_destroyed(self);
    pf = StringValuePtr(passphrase);      // ensure passphrase is a string
    exception = AcquireExceptionInfo();

    new_image = rm_clone_image(image);

    okay = DecipherImage(new_image, pf, exception);
    rm_check_exception(exception, new_image, DestroyOnError);
    if (!okay)
    {
        (void) DestroyImage(new_image);
        rb_raise(rb_eRuntimeError, "DecipherImage failed for unknown reason.");
    }

    (void) DestroyExceptionInfo(exception);

    return rm_image_new(new_image);
}

#define(artifact, value) ⇒ Object

Call SetImageArtifact.

Ruby usage:

- @verbatim value = Image#define(artifact, value) @endverbatim

Notes:

- Normally a script should never call this method. Any calls to
  SetImageArtifact will be part of the methods in which they're needed, or
  be called via the OptionalMethodArguments class.
- If value is nil, the artifact will be removed

Parameters:

  • self

    this object

  • artifact

    the artifact to set

  • value

    the value to which to set the artifact

Returns:

  • the value



4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
# File 'ext/RMagick/rmimage.c', line 4701

VALUE
Image_define(VALUE self, VALUE artifact, VALUE value)
{
    Image *image;
    char *key, *val;
    MagickBooleanType status;

    image = rm_check_frozen(self);
    artifact = rb_String(artifact);
    key = StringValuePtr(artifact);

    if (value == Qnil)
    {
        (void) DeleteImageArtifact(image, key);
    }
    else
    {
        value = rb_String(value);
        val = StringValuePtr(value);
        status = SetImageArtifact(image, key, val);
        if (!status)
        {
            rb_raise(rb_eNoMemError, "not enough memory to continue");
        }
    }

    return value;
}

#delete_compose_maskObject

#delete_profile(name) ⇒ Object

Call ProfileImage.

Ruby usage:

- @verbatim Image#delete_profile(name) @endverbatim

Parameters:

  • self

    this object

  • name

    the name of the profile to be deleted

Returns:

  • self



4770
4771
4772
4773
4774
4775
4776
4777
# File 'ext/RMagick/rmimage.c', line 4770

VALUE
Image_delete_profile(VALUE self, VALUE name)
{
    Image *image = rm_check_frozen(self);
    (void) DeleteImageProfile(image, StringValuePtr(name));

    return self;
}

#deskew(*args) ⇒ Object

Implement convert -deskew option.

Ruby usage:

- @verbatim Image#deskew @endverbatim
- @verbatim Image#deskew(threshold) @endverbatim
- @verbatim Image#deskew(threshold, auto-crop-width) @endverbatim

Notes:

- Default threshold is 0.40
- Default auto-crop-width is the auto crop width of the image

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
# File 'ext/RMagick/rmimage.c', line 4830

VALUE
Image_deskew(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    double threshold = 40.0 * QuantumRange / 100.0;
    unsigned long width;
    char auto_crop_width[20];
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    switch (argc)
    {
        case 2:
            width = NUM2ULONG(argv[1]);
            memset(auto_crop_width, 0, sizeof(auto_crop_width));
            sprintf(auto_crop_width, "%ld", width);
            SetImageArtifact(image, "deskew:auto-crop", auto_crop_width);
        case 1:
            threshold = rm_percentage(argv[0],1.0) * QuantumRange;
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
            break;
    }

    exception = AcquireExceptionInfo();
    new_image = DeskewImage(image, threshold, exception);
    CHECK_EXCEPTION()
    rm_ensure_result(new_image);

    (void) DestroyExceptionInfo(exception);

    return rm_image_new(new_image);
}

#despeckleObject

Reduce the speckle noise in an image while preserving the edges of the original image.

Ruby usage:

- @verbatim Image#despeckle @endverbatim

Parameters:

  • self

    this object

Returns:

  • a new image



4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
# File 'ext/RMagick/rmimage.c', line 4878

VALUE
Image_despeckle(VALUE self)
{
    Image *image, *new_image;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    exception = AcquireExceptionInfo();

    new_image = DespeckleImage(image, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#destroy!Object

Free all the memory associated with an image.

Ruby usage:

- @verbatim Image#destroy! @endverbatim

Parameters:

  • self

    this object

Returns:

  • self



4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
# File 'ext/RMagick/rmimage.c', line 4907

VALUE
Image_destroy_bang(VALUE self)
{
    Image *image;

    rb_check_frozen(self);
    Data_Get_Struct(self, Image, image);
    rm_image_destroy(image);
    DATA_PTR(self) = NULL;
    return self;
}

#destroyed?Boolean

Return true if the image has been destroyed, false otherwise.

Ruby usage:

- @verbatim Image#destroyed? @endverbatim

Parameters:

  • self

    this object

Returns:

  • (Boolean)

    true if destroyed, false otherwise



4929
4930
4931
4932
4933
4934
4935
4936
# File 'ext/RMagick/rmimage.c', line 4929

VALUE
Image_destroyed_q(VALUE self)
{
    Image *image;

    Data_Get_Struct(self, Image, image);
    return image ? Qfalse : Qtrue;
}

#difference(other) ⇒ Object

Call the IsImagesEqual function.

Ruby usage:

- @verbatim Image#difference @endverbatim

Notes:

- "other" can be either an Image or an Image

normalized maximum error]

Parameters:

  • self

    this object

  • other

    another Image

Returns:

  • An array with 3 values: [mean error per pixel, normalized mean error,



4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
# File 'ext/RMagick/rmimage.c', line 4953

VALUE
Image_difference(VALUE self, VALUE other)
{
    Image *image;
    Image *image2;
    VALUE mean, nmean, nmax;

    image = rm_check_destroyed(self);
    other = rm_cur_image(other);
    image2 = rm_check_destroyed(other);

    (void) IsImagesEqual(image, image2);
    rm_check_image_exception(image, RetainOnError);

    mean  = rb_float_new(image->error.mean_error_per_pixel);
    nmean = rb_float_new(image->error.normalized_mean_error);
    nmax  = rb_float_new(image->error.normalized_maximum_error);

    RB_GC_GUARD(mean);
    RB_GC_GUARD(nmean);
    RB_GC_GUARD(nmax);

    return rb_ary_new3(3, mean, nmean, nmax);
}

#dispatch(*args) ⇒ Object

Extract pixel data from the image and returns it as an array of pixels. The “x”, “y”, “width” and “height” parameters specify the rectangle to be extracted. The “map” parameter reflects the expected ordering of the pixel array. It can be any combination or order of R = red, G = green, B = blue, A = alpha, C = cyan, Y = yellow, M = magenta, K = black, or I = intensity (for grayscale). If the “float” parameter is specified and true, the pixel data is returned as floating-point numbers in the range [0..1]. By default the pixel data is returned as integers in the range [0..QuantumRange].

Ruby usage:

- @verbatim Image#dispatch(x, y, columns, rows, map) @endverbatim
- @verbatim Image#dispatch(x, y, columns, rows, map, float) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • an Array of pixel data



5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
# File 'ext/RMagick/rmimage.c', line 5078

VALUE
Image_dispatch(int argc, VALUE *argv, VALUE self)
{
    Image *image;
    long x, y;
    unsigned long columns, rows, n, npixels;
    VALUE pixels_ary;
    StorageType stg_type = QuantumPixel;
    char *map;
    long mapL;
    MagickBooleanType okay;
    ExceptionInfo *exception;
    volatile union
    {
        Quantum *i;
        double *f;
        void *v;
    } pixels;

    (void) rm_check_destroyed(self);

    if (argc < 5 || argc > 6)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 5 or 6)", argc);
    }

    x       = NUM2LONG(argv[0]);
    y       = NUM2LONG(argv[1]);
    columns = NUM2ULONG(argv[2]);
    rows    = NUM2ULONG(argv[3]);
    map     = rm_str2cstr(argv[4], &mapL);
    if (argc == 6)
    {
        stg_type = RTEST(argv[5]) ? DoublePixel : QuantumPixel;
    }

    // Compute the size of the pixel array and allocate the memory.
    npixels = columns * rows * mapL;
    pixels.v = stg_type == QuantumPixel ? (void *) ALLOC_N(Quantum, npixels)
               : (void *) ALLOC_N(double, npixels);

    // Create the Ruby array for the pixels. Return this even if ExportImagePixels fails.
    pixels_ary = rb_ary_new();

    Data_Get_Struct(self, Image, image);

    exception = AcquireExceptionInfo();
    okay = ExportImagePixels(image, x, y, columns, rows, map, stg_type, (void *)pixels.v, exception);

    if (!okay)
    {
        goto exit;
    }

    CHECK_EXCEPTION()

    (void) DestroyExceptionInfo(exception);

    // Convert the pixel data to the appropriate Ruby type
    if (stg_type == QuantumPixel)
    {
        for (n = 0; n < npixels; n++)
        {
            (void) rb_ary_push(pixels_ary, QUANTUM2NUM(pixels.i[n]));
        }
    }
    else
    {
        for (n = 0; n < npixels; n++)
        {
            (void) rb_ary_push(pixels_ary, rb_float_new(pixels.f[n]));
        }
    }

    exit:
    xfree((void *)pixels.v);

    RB_GC_GUARD(pixels_ary);

    return pixels_ary;
}

#displaceObject

#displayObject Also known as: __display__

Display the image to an X window screen.

Ruby usage:

- @verbatim Image#display @endverbatim

Parameters:

  • self

    this object

Returns:

  • self



5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
# File 'ext/RMagick/rmimage.c', line 5170

VALUE
Image_display(VALUE self)
{
    Image *image;
    Info *info;
    VALUE info_obj;

    image = rm_check_destroyed(self);

    if (image->rows == 0 || image->columns == 0)
    {
        rb_raise(rb_eArgError, "invalid image geometry (%lux%lu)", image->rows, image->columns);
    }

    info_obj = rm_info_new();
    Data_Get_Struct(info_obj, Info, info);

    (void) DisplayImages(info, image);
    rm_check_image_exception(image, RetainOnError);

    RB_GC_GUARD(info_obj);

    return self;
}

#dissolve(*args) ⇒ Object

Corresponds to the composite_image -dissolve operation.

Ruby usage:

- @verbatim Image#dissolve(overlay, src_percent) @endverbatim
- @verbatim Image#dissolve(overlay, src_percent, dst_percent) @endverbatim
- @verbatim Image#dissolve(overlay, src_percent, dst_percent, x_offset) @endverbatim
- @verbatim Image#dissolve(overlay, src_percent, dst_percent, x_offset, y_offset) @endverbatim
- @verbatim Image#dissolve(overlay, src_percent, dst_percent, gravity) @endverbatim
- @verbatim Image#dissolve(overlay, src_percent, dst_percent, gravity, x_offset) @endverbatim
- @verbatim Image#dissolve(overlay, src_percent, dst_percent, gravity, x_offset, y_offset) @endverbatim

Notes:

- `percent' can be a number or a string in the form "NN%"
- Default dst_percent is -1.0 (tells blend_geometry to leave it out of the
  geometry string)
- Default x_offset is 0
- Default y_offset is 0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:

  • special_composite


5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
# File 'ext/RMagick/rmimage.c', line 5257

VALUE
Image_dissolve(int argc, VALUE *argv, VALUE self)
{
    Image *image, *overlay;
    double src_percent, dst_percent = -1.0;
    long x_offset = 0L, y_offset = 0L;
    VALUE composite_image, ovly;

    image = rm_check_destroyed(self);

    if (argc < 1)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 to 6)", argc);
    }

    ovly = rm_cur_image(argv[0]);
    overlay = rm_check_destroyed(ovly);

    if (argc > 3)
    {
        get_composite_offsets(argc-3, &argv[3], image, overlay, &x_offset, &y_offset);
        // There must be 3 arguments left
        argc = 3;
    }

    switch (argc)
    {
        case 3:
            dst_percent = rm_percentage(argv[2],1.0) * 100.0;
        case 2:
            src_percent = rm_percentage(argv[1],1.0) * 100.0;
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 to 6)", argc);
            break;
    }

    composite_image =  special_composite(image, overlay, src_percent, dst_percent
                                         , x_offset, y_offset, DissolveCompositeOp);

    RB_GC_GUARD(composite_image);
    RB_GC_GUARD(ovly);

    return composite_image;
}

#distort(*args) ⇒ Object

Call DistortImage.

Ruby usage:

- @verbatim Image#distort(type, points) { optional arguments } @endverbatim
- @verbatim Image#distort(type, points, bestfit) { optional arguments } @endverbatim

Notes:

- Default bestfit is false
- Points is an Array of Numeric values
- Optional arguments are:
  - self.define "distort:viewport", WxH+X+Y
  - self.define "distort:scale", N
  - self.verbose true

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
# File 'ext/RMagick/rmimage.c', line 5324

VALUE
Image_distort(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    VALUE pts;
    unsigned long n, npoints;
    DistortMethod distortion_method;
    double *points;
    MagickBooleanType bestfit = MagickFalse;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    rm_get_optional_arguments(self);

    switch (argc)
    {
        case 3:
            bestfit = RTEST(argv[2]);
        case 2:
            // Ensure pts is an array
            pts = rb_Array(argv[1]);
            VALUE_TO_ENUM(argv[0], distortion_method, DistortMethod);
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (expected 2 or 3, got %d)", argc);
            break;
    }

    npoints = RARRAY_LEN(pts);
    points = ALLOC_N(double, npoints);

    for (n = 0; n < npoints; n++)
    {
        VALUE element = rb_ary_entry(pts, n);
        if (rm_check_num2dbl(element))
        {
            points[n] = NUM2DBL(element);
        }
        else
        {
            xfree(points);
            rb_raise(rb_eTypeError, "type mismatch: %s given", rb_class2name(CLASS_OF(element)));
        }
    }

    exception = AcquireExceptionInfo();
    new_image = DistortImage(image, distortion_method, npoints, points, bestfit, exception);
    xfree(points);
    rm_check_exception(exception, new_image, DestroyOnError);
    (void) DestroyExceptionInfo(exception);
    rm_ensure_result(new_image);

    RB_GC_GUARD(pts);

    return rm_image_new(new_image);
}

#distortion_channel(*args) ⇒ Object

Call GetImageChannelDistortion.

Ruby usage:

- @verbatim Image#distortion_channel(reconstructed_image, metric) @endverbatim
- @verbatim Image#distortion_channel(reconstructed_image, metric, channel) @endverbatim
- @verbatim Image#distortion_channel(reconstructed_image, metric, channel, ...) @endverbatim

Notes:

- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • the image channel distortion (Ruby float)



5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
# File 'ext/RMagick/rmimage.c', line 5398

VALUE
Image_distortion_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *reconstruct;
    ChannelType channels;
    ExceptionInfo *exception;
    MetricType metric;
    VALUE rec;
    double distortion;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);
    if (argc > 2)
    {
        raise_ChannelType_error(argv[argc-1]);
    }
    if (argc < 2)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or more)", argc);
    }

    rec = rm_cur_image(argv[0]);
    reconstruct = rm_check_destroyed(rec);
    VALUE_TO_ENUM(argv[1], metric, MetricType);
    exception = AcquireExceptionInfo();
    (void) GetImageChannelDistortion(image, reconstruct, channels, metric, &distortion, exception);
    CHECK_EXCEPTION()

    (void) DestroyExceptionInfo(exception);

    RB_GC_GUARD(rec);

    return rb_float_new(distortion);
}

#dupObject

Construct a new image object and call initialize_copy.

Ruby usage:

- @verbatim Image#dup @endverbatim

Parameters:

  • self

    this object

Returns:

  • a new image

See Also:

  • Image_copy
  • Image_init_copy


5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
# File 'ext/RMagick/rmimage.c', line 5515

VALUE
Image_dup(VALUE self)
{
    VALUE dup;

    (void) rm_check_destroyed(self);
    dup = Data_Wrap_Struct(CLASS_OF(self), NULL, rm_image_destroy, NULL);
    if (rb_obj_tainted(self))
    {
        (void) rb_obj_taint(dup);
    }

    RB_GC_GUARD(dup);

    return rb_funcall(dup, rm_ID_initialize_copy, 1, self);
}

#each_iptc_datasetObject

Iterate over IPTC record number:dataset tags, yield for each non-nil dataset



880
881
882
883
884
885
886
887
888
889
# File 'lib/rmagick_internal.rb', line 880

def each_iptc_dataset
  Magick::IPTC.constants.each do |record|
    rec = Magick::IPTC.const_get(record)
    rec.constants.each do |dataset|
      data_field = get_iptc_dataset(rec.const_get(dataset))
      yield(dataset, data_field) unless data_field.nil?
    end
  end
  nil
end

#each_pixelObject

Thanks to Russell Norris!



825
826
827
828
829
830
# File 'lib/rmagick_internal.rb', line 825

def each_pixel
  get_pixels(0, 0, columns, rows).each_with_index do |p, n|
    yield(p, n % columns, n / columns)
  end
  self
end

#each_profileObject

Iterate over image profiles.

Ruby usage:

- @verbatim Image#each_profile @endverbatim

Notes:

- ImageMagick only

Parameters:

  • self

    this object

Returns:

  • iterator over image profiles



5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
# File 'ext/RMagick/rmimage.c', line 5545

VALUE
Image_each_profile(VALUE self)
{
    Image *image;
    VALUE ary, val;
    char *name;
    const StringInfo *profile;

    image = rm_check_destroyed(self);
    ResetImageProfileIterator(image);

    ary = rb_ary_new2(2);

    name = GetNextImageProfile(image);
    while (name)
    {
        rb_ary_store(ary, 0, rb_str_new2(name));

        profile = GetImageProfile(image, name);
        if (!profile)
        {
            rb_ary_store(ary, 1, Qnil);
        }
        else
        {
            rb_ary_store(ary, 1, rb_str_new((char *)profile->datum, (long)profile->length));
        }
        val = rb_yield(ary);
        name = GetNextImageProfile(image);
    }

    RB_GC_GUARD(ary);
    RB_GC_GUARD(val);

    return val;
}

#edge(*args) ⇒ Object

Find edges in an image. “radius” defines the radius of the convolution filter.

Ruby usage:

- @verbatim Image#edge @endverbatim
- @verbatim Image#edge(radius) @endverbatim

Notes:

- Default radius is 0 (have edge select a suitable radius)

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
# File 'ext/RMagick/rmimage.c', line 5599

VALUE
Image_edge(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    double radius = 0.0;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    switch (argc)
    {
        case 1:
            radius = NUM2DBL(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
            break;
    }

    exception = AcquireExceptionInfo();

    new_image = EdgeImage(image, radius, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#emboss(*args) ⇒ Object

Create a grayscale image with a three-dimensional effect.

Ruby usage:

- @verbatim Image#emboss @endverbatim
- @verbatim Image#emboss(radius) @endverbatim
- @verbatim Image#emboss(radius, sigma) @endverbatim

Notes:

- Default radius is 0.0
- Default sigma is 1.0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:

  • effect_image


5699
5700
5701
5702
5703
# File 'ext/RMagick/rmimage.c', line 5699

VALUE
Image_emboss(int argc, VALUE *argv, VALUE self)
{
    return effect_image(self, argc, argv, EmbossImage);
}

#encipher(passphrase) ⇒ Object

Call EncipherImage.

Ruby usage:

- @verbatim Image#encipher(passphrase) @endverbatim

Parameters:

  • self

    this object

  • passphrase

    the passphrase with which to encipher

Returns:

  • a new image



5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
# File 'ext/RMagick/rmimage.c', line 5716

VALUE
Image_encipher(VALUE self, VALUE passphrase)
{
    Image *image, *new_image;
    char *pf;
    ExceptionInfo *exception;
    MagickBooleanType okay;

    image = rm_check_destroyed(self);
    pf = StringValuePtr(passphrase);      // ensure passphrase is a string
    exception = AcquireExceptionInfo();

    new_image = rm_clone_image(image);

    okay = EncipherImage(new_image, pf, exception);
    rm_check_exception(exception, new_image, DestroyOnError);
    if (!okay)
    {
        (void) DestroyImage(new_image);
        rb_raise(rb_eRuntimeError, "EncipherImage failed for unknown reason.");
    }

    DestroyExceptionInfo(exception);

    return rm_image_new(new_image);
}

#enhanceObject

Apply a digital filter that improves the quality of a noisy image.

Ruby usage:

- @verbatim Image#enhance @endverbatim

Parameters:

  • self

    this object

Returns:

  • a new image



5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
# File 'ext/RMagick/rmimage.c', line 5789

VALUE
Image_enhance(VALUE self)
{
    Image *image, *new_image;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    exception = AcquireExceptionInfo();

    new_image = EnhanceImage(image, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#equalizeObject

Apply a histogram equalization to the image.

Ruby usage:

- @verbatim Image#equalize @endverbatim

Parameters:

  • self

    this object

Returns:

  • a new image



5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
# File 'ext/RMagick/rmimage.c', line 5818

VALUE
Image_equalize(VALUE self)
{
    Image *image, *new_image;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    exception = AcquireExceptionInfo();
    new_image = rm_clone_image(image);

    (void) EqualizeImage(new_image);
    rm_check_image_exception(new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    return rm_image_new(new_image);
}

#equalize_channel(*args) ⇒ Object

Call EqualizeImageChannel.

Ruby usage:

- @verbatim Image#equalize_channel @endverbatim
- @verbatim Image#equalize_channel(channel) @endverbatim
- @verbatim Image#equalize_channel(channel, ...) @endverbatim

Notes:

- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
# File 'ext/RMagick/rmimage.c', line 5853

VALUE
Image_equalize_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    ExceptionInfo *exception;
    ChannelType channels;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);
    if (argc > 0)
    {
        raise_ChannelType_error(argv[argc-1]);
    }

    new_image = rm_clone_image(image);

    exception = AcquireExceptionInfo();

    (void) EqualizeImageChannel(new_image, channels);

    rm_check_image_exception(new_image, DestroyOnError);
    (void) DestroyExceptionInfo(exception);

    return rm_image_new(new_image);
}

#erase!Object

Reset the image to the background color.

Ruby usage:

- @verbatim Image#erase! @endverbatim

Notes:

- One of the very few Image methods that do not return a new image.

Parameters:

  • self

    this object

Returns:

  • self



5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
# File 'ext/RMagick/rmimage.c', line 5892

VALUE
Image_erase_bang(VALUE self)
{
    Image *image;

    image = rm_check_frozen(self);

    (void) SetImageBackgroundColor(image);
    rm_check_image_exception(image, RetainOnError);

    return self;
}

#excerpt(x, y, width, height) ⇒ Object

Lightweight crop.

Ruby usage:

- @verbatim Image#excerpt(x, y, width, height) @endverbatim

Parameters:

  • self

    this object

  • x

    the x position for the start of the rectangle

  • y

    the y position for the start of the rectangle

  • width

    the width of the rectancle

  • height

    the height of the rectangle

Returns:

  • self if bang, otherwise a new image

See Also:

  • #excerpt
  • Image_excerpt_bang
  • Image_crop
  • Image_crop_bang


5976
5977
5978
5979
5980
5981
# File 'ext/RMagick/rmimage.c', line 5976

VALUE
Image_excerpt(VALUE self, VALUE x, VALUE y, VALUE width, VALUE height)
{
    (void) rm_check_destroyed(self);
    return excerpt(False, self, x, y, width, height);
}

#excerpt!(x, y, width, height) ⇒ Object

Lightweight crop.

Ruby usage:

- @verbatim Image#excerpt!(x, y, width, height) @endverbatim

Parameters:

  • self

    this object

  • x

    the x position for the start of the rectangle

  • y

    the y position for the start of the rectangle

  • width

    the width of the rectancle

  • height

    the height of the rectangle

Returns:

  • self

See Also:

  • #excerpt
  • Image_excerpt
  • Image_crop
  • Image_crop_bang


6001
6002
6003
6004
6005
6006
# File 'ext/RMagick/rmimage.c', line 6001

VALUE
Image_excerpt_bang(VALUE self, VALUE x, VALUE y, VALUE width, VALUE height)
{
    (void) rm_check_frozen(self);
    return excerpt(True, self, x, y, width, height);
}

#export_pixels(*args) ⇒ Object

Extract image pixels in the form of an array.

Ruby usage:

- @verbatim Image#export_pixels @endverbatim
- @verbatim Image#export_pixels(x) @endverbatim
- @verbatim Image#export_pixels(x, y) @endverbatim
- @verbatim Image#export_pixels(x, y, cols) @endverbatim
- @verbatim Image#export_pixels(x, y, cols, rows) @endverbatim
- @verbatim Image#export_pixels(x, y, cols, rows, map) @endverbatim

Notes:

- Default x is 0
- Default y is 0
- Default cols is self.columns
- Default rows is self.rows
- Default map is "RGB"

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • array of pixels



6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
# File 'ext/RMagick/rmimage.c', line 6032

VALUE
Image_export_pixels(int argc, VALUE *argv, VALUE self)
{
    Image *image;
    long x_off = 0L, y_off = 0L;
    unsigned long cols, rows;
    long n, npixels;
    unsigned int okay;
    const char *map = "RGB";
    Quantum *pixels;
    VALUE ary;
    ExceptionInfo *exception;


    image = rm_check_destroyed(self);
    cols = image->columns;
    rows = image->rows;

    switch (argc)
    {
        case 5:
            map   = StringValuePtr(argv[4]);
        case 4:
            rows  = NUM2ULONG(argv[3]);
        case 3:
            cols  = NUM2ULONG(argv[2]);
        case 2:
            y_off = NUM2LONG(argv[1]);
        case 1:
            x_off = NUM2LONG(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 5)", argc);
            break;
    }

    if (   x_off < 0 || (unsigned long)x_off > image->columns
           || y_off < 0 || (unsigned long)y_off > image->rows
           || cols == 0 || rows == 0)
    {
        rb_raise(rb_eArgError, "invalid extract geometry");
    }


    npixels = (long)(cols * rows * strlen(map));
    pixels = ALLOC_N(Quantum, npixels);
    if (!pixels)    // app recovered from exception
    {
        return rb_ary_new2(0L);
    }

    exception = AcquireExceptionInfo();

    okay = ExportImagePixels(image, x_off, y_off, cols, rows, map, QuantumPixel, (void *)pixels, exception);
    if (!okay)
    {
        xfree((void *)pixels);
        CHECK_EXCEPTION()

        // Should never get here...
        rm_magick_error("ExportImagePixels failed with no explanation.");
    }

    (void) DestroyExceptionInfo(exception);

    ary = rb_ary_new2(npixels);
    for (n = 0; n < npixels; n++)
    {
        (void) rb_ary_push(ary, QUANTUM2NUM(pixels[n]));
    }

    xfree((void *)pixels);

    RB_GC_GUARD(ary);

    return ary;
}

#export_pixels_to_str(*args) ⇒ Object

Extract image pixels to a Ruby string.

Ruby usage:

- @verbatim Image#export_pixels_to_str @endverbatim
- @verbatim Image#export_pixels_to_str(x) @endverbatim
- @verbatim Image#export_pixels_to_str(x, y) @endverbatim
- @verbatim Image#export_pixels_to_str(x, y, cols) @endverbatim
- @verbatim Image#export_pixels_to_str(x, y, cols, rows) @endverbatim
- @verbatim Image#export_pixels_to_str(x, y, cols, rows, map) @endverbatim
- @verbatim Image#export_pixels_to_str(x, y, cols, rows, map, type) @endverbatim

Notes:

- Default x is 0
- Default y is 0
- Default cols is self.columns
- Default rows is self.rows
- Default map is "RGB"
- Default type is Magick::CharPixel

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • pixels as a string



6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
# File 'ext/RMagick/rmimage.c', line 6208

VALUE
Image_export_pixels_to_str(int argc, VALUE *argv, VALUE self)
{
    Image *image;
    long x_off = 0L, y_off = 0L;
    unsigned long cols, rows;
    unsigned long npixels;
    size_t sz;
    unsigned int okay;
    const char *map = "RGB";
    StorageType type = CharPixel;
    VALUE string;
    char *str;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    cols = image->columns;
    rows = image->rows;

    switch (argc)
    {
        case 6:
            VALUE_TO_ENUM(argv[5], type, StorageType);
        case 5:
            map   = StringValuePtr(argv[4]);
        case 4:
            rows  = NUM2ULONG(argv[3]);
        case 3:
            cols  = NUM2ULONG(argv[2]);
        case 2:
            y_off = NUM2LONG(argv[1]);
        case 1:
            x_off = NUM2LONG(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 6)", argc);
            break;
    }

    if (   x_off < 0 || (unsigned long)x_off > image->columns
           || y_off < 0 || (unsigned long)y_off > image->rows
           || cols == 0 || rows == 0)
    {
        rb_raise(rb_eArgError, "invalid extract geometry");
    }


    npixels = cols * rows * strlen(map);
    switch (type)
    {
        case CharPixel:
            sz = sizeof(unsigned char);
            break;
        case ShortPixel:
            sz = sizeof(unsigned short);
            break;
        case DoublePixel:
            sz = sizeof(double);
            break;
        case FloatPixel:
            sz = sizeof(float);
            break;
        case IntegerPixel:
            sz = sizeof(unsigned int);
            break;
        case LongPixel:
            sz = sizeof(unsigned long);
            break;
        case QuantumPixel:
            sz = sizeof(Quantum);
            break;
        case UndefinedPixel:
        default:
            rb_raise(rb_eArgError, "undefined storage type");
            break;
    }

    // Allocate a string long enough to hold the exported pixel data.
    // Get a pointer to the buffer.
    string = rb_str_new2("");
    (void) rb_str_resize(string, (long)(sz * npixels));
    str = StringValuePtr(string);

    exception = AcquireExceptionInfo();

    okay = ExportImagePixels(image, x_off, y_off, cols, rows, map, type, (void *)str, exception);
    if (!okay)
    {
        // Let GC have the string buffer.
        (void) rb_str_resize(string, 0);
        CHECK_EXCEPTION()

        // Should never get here...
        rm_magick_error("ExportImagePixels failed with no explanation.");
    }

    (void) DestroyExceptionInfo(exception);

    RB_GC_GUARD(string);

    return string;
}

#extent(*args) ⇒ Object

Call ExtentImage.

Ruby usage:

- @verbatim Image#extent(width, height) @endverbatim
- @verbatim Image#extent(width, height, x) @endverbatim
- @verbatim Image#extent(width, height, x, y) @endverbatim

Notes:

- Default x is 0
- Default y is 0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
# File 'ext/RMagick/rmimage.c', line 6129

VALUE
Image_extent(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    RectangleInfo geometry;
    long height, width;
    ExceptionInfo *exception;

    (void) rm_check_destroyed(self);

    if (argc < 2 || argc > 4)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (expected 2 to 4, got %d)", argc);
    }

    geometry.y = geometry.x = 0L;
    switch (argc)
    {
        case 4:
            geometry.y = NUM2LONG(argv[3]);
        case 3:
            geometry.x = NUM2LONG(argv[2]);
        default:
            geometry.height = height = NUM2LONG(argv[1]);
            geometry.width = width = NUM2LONG(argv[0]);
            break;
    }

    // Use the signed versions of these two values to test for < 0
    if (height <= 0L || width <= 0L)
    {
        if (geometry.x == 0 && geometry.y == 0)
        {
            rb_raise(rb_eArgError, "invalid extent geometry %ldx%ld", width, height);
        }
        else
        {
            rb_raise(rb_eArgError, "invalid extent geometry %ldx%ld+%ld+%ld"
                     , width, height, geometry.x, geometry.y);
        }
    }


    Data_Get_Struct(self, Image, image);
    exception = AcquireExceptionInfo();

    new_image = ExtentImage(image, &geometry, exception);
    rm_check_exception(exception, new_image, DestroyOnError);
    (void) DestroyExceptionInfo(exception);
    rm_ensure_result(new_image);
    return rm_image_new(new_image);
}

#find_similar_region(*args) ⇒ Object

Search for a region in the image that is “similar” to the target image.

Ruby usage:

- @verbatim Image#find_similar_region(target) @endverbatim
- @verbatim Image#find_similar_region(target, x) @endverbatim
- @verbatim Image#find_similar_region(target, x, y) @endverbatim

Notes:

- Default x is 0
- Default y is 0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • the region



6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
# File 'ext/RMagick/rmimage.c', line 6430

VALUE
Image_find_similar_region(int argc, VALUE *argv, VALUE self)
{
    Image *image, *target;
    VALUE region, targ;
    ssize_t x = 0L, y = 0L;
    ExceptionInfo *exception;
    unsigned int okay;

    image = rm_check_destroyed(self);

    switch (argc)
    {
        case 3:
            y = NUM2LONG(argv[2]);
        case 2:
            x = NUM2LONG(argv[1]);
        case 1:
            targ = rm_cur_image(argv[0]);
            target = rm_check_destroyed(targ);
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 3)", argc);
            break;
    }

    exception = AcquireExceptionInfo();
    okay = IsImageSimilar(image, target, &x, &y, exception);
    CHECK_EXCEPTION();
    (void) DestroyExceptionInfo(exception);

    if (!okay)
    {
        return Qnil;
    }

    region = rb_ary_new2(2);
    rb_ary_store(region, 0L, LONG2NUM(x));
    rb_ary_store(region, 1L, LONG2NUM(y));

    RB_GC_GUARD(region);
    RB_GC_GUARD(targ);

    return region;
}

#flipObject

Create a vertical mirror image by reflecting the pixels around the central x-axis.

Ruby usage:

- @verbatim Image#flip @endverbatim

Parameters:

  • self

    this object

Returns:

  • a new image

See Also:

  • flipflop
  • Image_flip_bang
  • Image_flop
  • Image_flop_bang


6532
6533
6534
6535
6536
6537
# File 'ext/RMagick/rmimage.c', line 6532

VALUE
Image_flip(VALUE self)
{
    (void) rm_check_destroyed(self);
    return flipflop(False, self, FlipImage);
}

#flip!Object

Create a vertical mirror image by reflecting the pixels around the central x-axis.

Ruby usage:

- @verbatim Image#flip! @endverbatim

Parameters:

  • self

    this object

Returns:

  • self

See Also:

  • flipflop
  • Image_flip
  • Image_flop
  • Image_flop_bang


6554
6555
6556
6557
6558
6559
# File 'ext/RMagick/rmimage.c', line 6554

VALUE
Image_flip_bang(VALUE self)
{
    (void) rm_check_frozen(self);
    return flipflop(True, self, FlipImage);
}

#flopObject

Create a horizonal mirror image by reflecting the pixels around the central y-axis.

Ruby usage:

- @verbatim Image#flop @endverbatim

Parameters:

  • self

    this object

Returns:

  • a new image

See Also:

  • flipflop
  • Image_flop_bang
  • Image_flip
  • Image_flip_bang


6576
6577
6578
6579
6580
6581
# File 'ext/RMagick/rmimage.c', line 6576

VALUE
Image_flop(VALUE self)
{
    (void) rm_check_destroyed(self);
    return flipflop(False, self, FlopImage);
}

#flop!Object

Create a horizonal mirror image by reflecting the pixels around the central y-axis.

Ruby usage:

- @verbatim Image#flop! @endverbatim

Parameters:

  • self

    this object

Returns:

  • self

See Also:

  • flipflop
  • Image_flop
  • Image_flip
  • Image_flip_bang


6598
6599
6600
6601
6602
6603
# File 'ext/RMagick/rmimage.c', line 6598

VALUE
Image_flop_bang(VALUE self)
{
    (void) rm_check_frozen(self);
    return flipflop(True, self, FlopImage);
}

#frame(*args) ⇒ Object

Add a simulated three-dimensional border around the image. “Width” and “height” specify the width and height of the frame. The “x” and “y” arguments position the image within the frame. If the image is supposed to be centered in the frame, x and y should be 1/2 the width and height of the frame. (I.e., if the frame is 50 pixels high and 50 pixels wide, x and y should both be 25). “Inner_bevel” and “outer_bevel” indicate the width of the inner and outer shadows of the frame. They should be much smaller than the frame and cannot be > 1/2 the frame width or height of the image.

Ruby usage:

- @verbatim Image#frame @endverbatim
- @verbatim Image#frame(width) @endverbatim
- @verbatim Image#frame(width, height) @endverbatim
- @verbatim Image#frame(width, height, x) @endverbatim
- @verbatim Image#frame(width, height, x, y) @endverbatim
- @verbatim Image#frame(width, height, x, y, inner_bevel) @endverbatim
- @verbatim Image#frame(width, height, x, y, inner_bevel, outer_bevel) @endverbatim
- @verbatim Image#frame(width, height, x, y, inner_bevel, outer_bevel, color) @endverbatim

Notes:

- The defaults are the same as they are in Magick++
- Default width is image-columns+25*2
- Default height is image-rows+25*2
- Default x is 25
- Default y is 25
- Default inner is 6
- Default outer is 6
- Default color is image matte_color (which defaults to "#bdbdbd", whatever
  self.matte_color was set to when the image was created, or whatever
  image.matte_color is currently set to)

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image.



6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
# File 'ext/RMagick/rmimage.c', line 6715

VALUE
Image_frame(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    ExceptionInfo *exception;
    FrameInfo frame_info;

    image = rm_check_destroyed(self);

    frame_info.width = image->columns + 50;
    frame_info.height = image->rows + 50;
    frame_info.x = 25;
    frame_info.y = 25;
    frame_info.inner_bevel = 6;
    frame_info.outer_bevel = 6;

    switch (argc)
    {
        case 7:
            Color_to_PixelColor(&image->matte_color, argv[6]);
        case 6:
            frame_info.outer_bevel = NUM2LONG(argv[5]);
        case 5:
            frame_info.inner_bevel = NUM2LONG(argv[4]);
        case 4:
            frame_info.y = NUM2LONG(argv[3]);
        case 3:
            frame_info.x = NUM2LONG(argv[2]);
        case 2:
            frame_info.height = image->rows + 2*NUM2LONG(argv[1]);
        case 1:
            frame_info.width = image->columns + 2*NUM2LONG(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 7)", argc);
            break;
    }

    exception = AcquireExceptionInfo();
    new_image = FrameImage(image, &frame_info, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#function_channel(*args) ⇒ Object

Set the function on a channel.

Ruby usage:

 - @verbatim Image#function_channel(function, args) @endverbatim
 - @verbatim Image#function_channel(function, args, channel) @endverbatim
 - @verbatim Image#function_channel(function, args, channel, ...) @endverbatim

Notes:
  - Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
# File 'ext/RMagick/rmimage.c', line 6823

VALUE
Image_function_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    MagickFunction function;
    unsigned long n, nparms;
    double *parms;
    ChannelType channels;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);

    // The number of parameters depends on the function.
    if (argc == 0)
    {
        rb_raise(rb_eArgError, "no function specified");
    }

    VALUE_TO_ENUM(argv[0], function, MagickFunction);
    argc -= 1;
    argv += 1;

    switch (function)
    {
        case PolynomialFunction:
            if (argc == 0)
            {
                rb_raise(rb_eArgError, "PolynomialFunction requires at least one argument.");
            }
            break;
        case SinusoidFunction:
        case ArcsinFunction:
        case ArctanFunction:
           if (argc < 1 || argc > 4)
           {
               rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 4)", argc);
           }
           break;
        default:
            rb_raise(rb_eArgError, "undefined function");
            break;
    }

    nparms = argc;
    parms = ALLOC_N(double, nparms);

    for (n = 0; n < nparms; n++)
    {
        VALUE element = argv[n];
        if (rm_check_num2dbl(element))
        {
            parms[n] = NUM2DBL(element);
        }
        else
        {
            xfree(parms);
            rb_raise(rb_eTypeError, "type mismatch: %s given", rb_class2name(CLASS_OF(element)));
        }
    }

    exception = AcquireExceptionInfo();
    new_image = rm_clone_image(image);
    (void) FunctionImageChannel(new_image, channels, function, nparms, parms, exception);
    (void) xfree(parms);
    rm_check_exception(exception, new_image, DestroyOnError);
    DestroyExceptionInfo(exception);

    return rm_image_new(new_image);
}

#fx(*args) ⇒ Object

Apply fx on the image.

Ruby usage:

- @verbatim Image#fx(expression) @endverbatim
- @verbatim Image#fx(expression, channel) @endverbatim
- @verbatim Image#fx(expression, channel, ...) @endverbatim

Notes:

- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
# File 'ext/RMagick/rmimage.c', line 6945

VALUE
Image_fx(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    char *expression;
    ChannelType channels;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);

    // There must be exactly 1 remaining argument.
    if (argc == 0)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (0 for 1 or more)");
    }
    else if (argc > 1)
    {
        raise_ChannelType_error(argv[argc-1]);
    }

    expression = StringValuePtr(argv[0]);

    exception = AcquireExceptionInfo();
    new_image = FxImageChannel(image, channels, expression, exception);
    rm_check_exception(exception, new_image, DestroyOnError);
    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#gamma_channelObject

#gamma_correct(*args) ⇒ Object

gamma-correct an image.

Ruby usage:

- @verbatim Image#gamma_correct(red_gamma) @endverbatim
- @verbatim Image#gamma_correct(red_gamma, green_gamma) @endverbatim
- @verbatim Image#gamma_correct(red_gamma, green_gamma, blue_gamma) @endverbatim

Notes:

- Default green_gamma is red_gamma
- Default blue_gamma is green_gamma
- For backward compatibility accept a 4th argument but ignore it.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
# File 'ext/RMagick/rmimage.c', line 7046

VALUE
Image_gamma_correct(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    double red_gamma, green_gamma, blue_gamma;

    image = rm_check_destroyed(self);
    switch (argc)
    {
        case 1:
            red_gamma   = NUM2DBL(argv[0]);
            green_gamma = blue_gamma = red_gamma;
            break;
        case 2:
            red_gamma   = NUM2DBL(argv[0]);
            green_gamma = NUM2DBL(argv[1]);
            blue_gamma  = green_gamma;
            break;
        case 3:
        case 4:
            red_gamma     = NUM2DBL(argv[0]);
            green_gamma   = NUM2DBL(argv[1]);
            blue_gamma    = NUM2DBL(argv[2]);
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 3)", argc);
            break;
    }

    new_image = rm_clone_image(image);

    if ((red_gamma == green_gamma) && (green_gamma == blue_gamma))
    {
        (void) GammaImageChannel(new_image, (ChannelType) (RedChannel | GreenChannel | BlueChannel), red_gamma);
    }
    else
    {
        (void) GammaImageChannel(new_image, RedChannel, red_gamma);
        (void) GammaImageChannel(new_image, GreenChannel, green_gamma);
        (void) GammaImageChannel(new_image, BlueChannel, blue_gamma);
    }

    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#gaussian_blur(*args) ⇒ Object

Blur the image.

Ruby usage:

- @verbatim Image#gaussian_blur @endverbatim
- @verbatim Image#gaussian_blur(radius) @endverbatim
- @verbatim Image#gaussian_blur(radius, sigma) @endverbatim

Notes:

- Default radius is 0.0
- Default sigma is 1.0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:

  • effect_image


7112
7113
7114
7115
7116
# File 'ext/RMagick/rmimage.c', line 7112

VALUE
Image_gaussian_blur(int argc, VALUE *argv, VALUE self)
{
    return effect_image(self, argc, argv, GaussianBlurImage);
}

#gaussian_blur_channel(*args) ⇒ Object

Blur the image on a channel. Ruby usage:

- @verbatim Image#gaussian_blur_channel @endverbatim
- @verbatim Image#gaussian_blur_channel(radius) @endverbatim
- @verbatim Image#gaussian_blur_channel(radius, sigma) @endverbatim
- @verbatim Image#gaussian_blur_channel(radius, sigma, channel) @endverbatim
- @verbatim Image#gaussian_blur_channel(radius, sigma, channel, ...) @endverbatim

Notes:

- Default radius is 0.0
- Default sigma is 1.0
- Default channel is AllChannels
- New in IM 6.0.0


7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
# File 'ext/RMagick/rmimage.c', line 7136

VALUE
Image_gaussian_blur_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    ChannelType channels;
    ExceptionInfo *exception;
    double radius = 0.0, sigma = 1.0;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);

    // There can be 0, 1, or 2 remaining arguments.
    switch (argc)
    {
        case 2:
            sigma = NUM2DBL(argv[1]);
            /* Fall thru */
        case 1:
            radius = NUM2DBL(argv[0]);
            /* Fall thru */
        case 0:
            break;
        default:
            raise_ChannelType_error(argv[argc-1]);
    }

    exception = AcquireExceptionInfo();
    new_image = GaussianBlurImageChannel(image, channels, radius, sigma, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    return rm_image_new(new_image);
}

#get_exif_by_entry(*entry) ⇒ Object

Retrieve EXIF data by entry or all. If one or more entry names specified, return the values associated with the entries. If no entries specified, return all entries and values. The return value is an array of [name,value] arrays.



836
837
838
839
840
841
842
843
844
845
846
847
848
849
# File 'lib/rmagick_internal.rb', line 836

def get_exif_by_entry(*entry)
  ary = []
  if entry.length.zero?
    exif_data = self['EXIF:*']
    exif_data.split("\n").each { |exif| ary.push(exif.split('=')) } if exif_data
  else
    get_exif_by_entry # ensure properties is populated with exif data
    entry.each do |name|
      rval = self["EXIF:#{name}"]
      ary.push([name, rval])
    end
  end
  ary
end

#get_exif_by_number(*tag) ⇒ Object

Retrieve EXIF data by tag number or all tag/value pairs. The return value is a hash.



852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
# File 'lib/rmagick_internal.rb', line 852

def get_exif_by_number(*tag)
  hash = {}
  if tag.length.zero?
    exif_data = self['EXIF:!']
    if exif_data
      exif_data.split("\n").each do |exif|
        tag, value = exif.split('=')
        tag = tag[1, 4].hex
        hash[tag] = value
      end
    end
  else
    get_exif_by_number # ensure properties is populated with exif data
    tag.each do |num|
      rval = self[format('#%04X', num.to_i)]
      hash[num] = rval == 'unknown' ? nil : rval
    end
  end
  hash
end

#get_iptc_dataset(ds) ⇒ Object

Retrieve IPTC information by record number:dataset tag constant defined in Magick::IPTC, above.



875
876
877
# File 'lib/rmagick_internal.rb', line 875

def get_iptc_dataset(ds)
  self['IPTC:' + ds]
end

#get_pixels(x_arg, y_arg, cols_arg, rows_arg) ⇒ Object

Call AcquireImagePixels.

Ruby usage:

- @verbatim Image#get_pixels(x, y, columns. rows) @endverbatim

Notes:

- This is the complement of store_pixels. Notice that the return value is
  an array object even when only one pixel is returned. store_pixels calls
  GetImagePixels, then SyncImage

rectangle defined by the geometry parameters.

Parameters:

  • self

    this object

  • x_arg

    x position of start of region

  • y_arg

    y position of start of region

  • cols_arg

    width of region

  • rows_arg

    height of region

Returns:

  • An array of Magick::Pixel objects corresponding to the pixels in the

See Also:

  • Image_store_pixels


7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
# File 'ext/RMagick/rmimage.c', line 7245

VALUE
Image_get_pixels(VALUE self, VALUE x_arg, VALUE y_arg, VALUE cols_arg, VALUE rows_arg)
{
    Image *image;
    ExceptionInfo *exception;
    long x, y;
    unsigned long columns, rows;
    long size, n;
    VALUE pixel_ary;
    const PixelPacket *pixels;

    image = rm_check_destroyed(self);
    x       = NUM2LONG(x_arg);
    y       = NUM2LONG(y_arg);
    columns = NUM2ULONG(cols_arg);
    rows    = NUM2ULONG(rows_arg);

    if ((x+columns) > image->columns || (y+rows) > image->rows)
    {
        rb_raise(rb_eRangeError, "geometry (%lux%lu%+ld%+ld) exceeds image bounds"
                 , columns, rows, x, y);
    }

    // Cast AcquireImagePixels to get rid of the const qualifier. We're not going
    // to change the pixels but I don't want to make "pixels" const.
    exception = AcquireExceptionInfo();
    pixels = GetVirtualPixels(image, x, y, columns, rows, exception);
    CHECK_EXCEPTION()

    (void) DestroyExceptionInfo(exception);

    // If the function failed, return a 0-length array.
    if (!pixels)
    {
        return rb_ary_new();
    }

    // Allocate an array big enough to contain the PixelPackets.
    size = (long)(columns * rows);
    pixel_ary = rb_ary_new2(size);

    // Convert the PixelPackets to Magick::Pixel objects
    for (n = 0; n < size; n++)
    {
        rb_ary_store(pixel_ary, n, Pixel_from_PixelPacket(&pixels[n]));
    }

    return pixel_ary;
}

#gray?Boolean

Return true if all the pixels in the image have the same red, green, and blue intensities.

Ruby usage:

- @verbatim Image#gray? @endverbatim

Parameters:

  • self

    this object

Returns:

  • (Boolean)

    true if image is gray, false otherwise

See Also:

  • has_attribute


7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
# File 'ext/RMagick/rmimage.c', line 7334

VALUE
Image_gray_q(VALUE self)
{
#if defined(HAVE_SETIMAGEGRAY)
    return has_attribute(self, (MagickBooleanType (*)(const Image *, ExceptionInfo *))SetImageGray);
#else
#if defined(IMAGEMAGICK_GREATER_THAN_EQUAL_6_8_9)
    return has_attribute(self, IsGrayImage);
#else
    // For ImageMagick 6.7
    Image *image;
    ColorspaceType colorspace;
    VALUE ret;

    image = rm_check_destroyed(self);
    colorspace = image->colorspace;
    if (image->colorspace == sRGBColorspace || image->colorspace == TransparentColorspace) {
        // Workaround
        //   If image colorspace has non-RGBColorspace, IsGrayImage() always return false.
        image->colorspace = RGBColorspace;
    }

    ret = has_attribute(self, IsGrayImage);
    image->colorspace = colorspace;
    return ret;
#endif
#endif
}

#grey?Boolean

Return true if all the pixels in the image have the same red, green, and blue intensities.

Ruby usage:

- @verbatim Image#gray? @endverbatim

Parameters:

  • self

    this object

Returns:

  • (Boolean)

    true if image is gray, false otherwise

See Also:

  • has_attribute


7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
# File 'ext/RMagick/rmimage.c', line 7334

VALUE
Image_gray_q(VALUE self)
{
#if defined(HAVE_SETIMAGEGRAY)
    return has_attribute(self, (MagickBooleanType (*)(const Image *, ExceptionInfo *))SetImageGray);
#else
#if defined(IMAGEMAGICK_GREATER_THAN_EQUAL_6_8_9)
    return has_attribute(self, IsGrayImage);
#else
    // For ImageMagick 6.7
    Image *image;
    ColorspaceType colorspace;
    VALUE ret;

    image = rm_check_destroyed(self);
    colorspace = image->colorspace;
    if (image->colorspace == sRGBColorspace || image->colorspace == TransparentColorspace) {
        // Workaround
        //   If image colorspace has non-RGBColorspace, IsGrayImage() always return false.
        image->colorspace = RGBColorspace;
    }

    ret = has_attribute(self, IsGrayImage);
    image->colorspace = colorspace;
    return ret;
#endif
#endif
}

#histogram?Boolean

Return true if has 1024 unique colors or less.

Ruby usage:

- @verbatim Image#histogram? @endverbatim

Parameters:

  • self

    this object

Returns:

  • (Boolean)

    true if image has <=1024 unique colors

See Also:

  • has_attribute


7374
7375
7376
7377
7378
# File 'ext/RMagick/rmimage.c', line 7374

VALUE
Image_histogram_q(VALUE self)
{
    return has_attribute(self, IsHistogramImage);
}

#implode(*args) ⇒ Object

Implode the image by the specified percentage.

Ruby usage:

- @verbatim Image#implode @endverbatim
- @verbatim Image#implode(amount) @endverbatim

Notes:

- Default amount is 0.50

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
# File 'ext/RMagick/rmimage.c', line 7396

VALUE
Image_implode(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    double amount = 0.50;
    ExceptionInfo *exception;

    switch (argc)
    {
        case 1:
            amount = NUM2DBL(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
    }

    image = rm_check_destroyed(self);
    exception = AcquireExceptionInfo();

    new_image = ImplodeImage(image, amount, exception);
    rm_check_exception(exception, new_image, DestroyOnError);
    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#import_pixels(*args) ⇒ Object

Store image pixel data from an array.

Ruby usage:

- @verbatim Image#import_pixels @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • self

See Also:

  • Image_export_pixels


7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
# File 'ext/RMagick/rmimage.c', line 7438

VALUE
Image_import_pixels(int argc, VALUE *argv, VALUE self)
{
    Image *image;
    long x_off, y_off;
    unsigned long cols, rows;
    unsigned long n, npixels;
    long buffer_l;
    char *map;
    VALUE pixel_arg, pixel_ary;
    StorageType stg_type = CharPixel;
    size_t type_sz, map_l;
    Quantum *pixels = NULL;
    double *fpixels = NULL;
    void *buffer;
    unsigned int okay;

    image = rm_check_frozen(self);

    switch (argc)
    {
        case 7:
            VALUE_TO_ENUM(argv[6], stg_type, StorageType);
        case 6:
            x_off = NUM2LONG(argv[0]);
            y_off = NUM2LONG(argv[1]);
            cols = NUM2ULONG(argv[2]);
            rows = NUM2ULONG(argv[3]);
            map = StringValuePtr(argv[4]);
            pixel_arg = argv[5];
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 6 or 7)", argc);
            break;
    }

    if (x_off < 0 || y_off < 0 || cols <= 0 || rows <= 0)
    {
        rb_raise(rb_eArgError, "invalid import geometry");
    }

    map_l = strlen(map);
    npixels = cols * rows * map_l;

    // Assume that any object that responds to :to_str is a string buffer containing
    // binary pixel data.
    if (rb_respond_to(pixel_arg, rb_intern("to_str")))
    {
        buffer = (void *)rm_str2cstr(pixel_arg, &buffer_l);
        switch (stg_type)
        {
            case CharPixel:
                type_sz = 1;
                break;
            case ShortPixel:
                type_sz = sizeof(unsigned short);
                break;
            case IntegerPixel:
                type_sz = sizeof(unsigned int);
                break;
            case LongPixel:
                type_sz = sizeof(unsigned long);
                break;
            case DoublePixel:
                type_sz = sizeof(double);
                break;
            case FloatPixel:
                type_sz = sizeof(float);
                break;
            case QuantumPixel:
                type_sz = sizeof(Quantum);
                break;
            default:
                rb_raise(rb_eArgError, "unsupported storage type %s", StorageType_name(stg_type));
                break;
        }

        if (buffer_l % type_sz != 0)
        {
            rb_raise(rb_eArgError, "pixel buffer must be an exact multiple of the storage type size");
        }
        if ((buffer_l / type_sz) % map_l != 0)
        {
            rb_raise(rb_eArgError, "pixel buffer must contain an exact multiple of the map length");
        }
        if ((unsigned long)(buffer_l / type_sz) < npixels)
        {
            rb_raise(rb_eArgError, "pixel buffer too small (need %lu channel values, got %ld)"
                     , npixels, buffer_l/type_sz);
        }
    }
    // Otherwise convert the argument to an array and convert the array elements
    // to binary pixel data.
    else
    {
        // rb_Array converts an object that is not an array to an array if possible,
        // and raises TypeError if it can't. It usually is possible.
        pixel_ary = rb_Array(pixel_arg);

        if (RARRAY_LEN(pixel_ary) % map_l != 0)
        {
            rb_raise(rb_eArgError, "pixel array must contain an exact multiple of the map length");
        }
        if ((unsigned long)RARRAY_LEN(pixel_ary) < npixels)
        {
            rb_raise(rb_eArgError, "pixel array too small (need %lu elements, got %ld)"
                     , npixels, RARRAY_LEN(pixel_ary));
        }

        if (stg_type == DoublePixel || stg_type == FloatPixel)
        {
            fpixels = ALLOC_N(double, npixels);
            for (n = 0; n < npixels; n++)
            {
                VALUE element = rb_ary_entry(pixel_ary, n);
                if (rm_check_num2dbl(element))
                {
                    fpixels[n] = NUM2DBL(element);
                }
                else
                {
                    xfree(fpixels);
                    rb_raise(rb_eTypeError, "type mismatch: %s given", rb_class2name(CLASS_OF(element)));
                }
            }
            buffer = (void *) fpixels;
            stg_type = DoublePixel;
        }
        else
        {
            pixels = ALLOC_N(Quantum, npixels);
            for (n = 0; n < npixels; n++)
            {
                VALUE element = rb_ary_entry(pixel_ary, n);
                if (rm_check_num2dbl(element))
                {
                    pixels[n] = NUM2DBL(element);
                }
                else
                {
                    xfree(pixels);
                    rb_raise(rb_eTypeError, "type mismatch: %s given", rb_class2name(CLASS_OF(element)));
                }
            }
            buffer = (void *) pixels;
            stg_type = QuantumPixel;
        }
    }


    okay = ImportImagePixels(image, x_off, y_off, cols, rows, map, stg_type, buffer);

    // Free pixel array before checking for errors.
    if (pixels)
    {
        xfree((void *)pixels);
    }
    if (fpixels)
    {
        xfree((void *)fpixels);
    }

    if (!okay)
    {
        rm_check_image_exception(image, RetainOnError);
        // Shouldn't get here...
        rm_magick_error("ImportImagePixels failed with no explanation.");
    }

    RB_GC_GUARD(pixel_arg);
    RB_GC_GUARD(pixel_ary);

    return self;
}

#initialize_copy(orig) ⇒ Object

Initialize copy, clone, dup.

Ruby usage:

- @verbatim Image#initialize_copy @endverbatim

Parameters:

  • copy

    the destination image

  • orig

    the source image

Returns:

  • copy

See Also:

  • Image_copy
  • Image_clone
  • Image_dup


4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
# File 'ext/RMagick/rmimage.c', line 4464

VALUE
Image_init_copy(VALUE copy, VALUE orig)
{
    Image *image, *new_image;

    image = rm_check_destroyed(orig);
    new_image = rm_clone_image(image);
    UPDATE_DATA_PTR(copy, new_image);

    return copy;
}

#inspectObject

Override Object#inspect - return a string description of the image.

Ruby usage:

- @verbatim Image#inspect @endverbatim

Notes:

- This is essentially the IdentifyImage except the description is built in
  a char buffer instead of being written to a file.

Parameters:

  • self

    this object

Returns:

  • the string

See Also:

  • build_inspect_string


7770
7771
7772
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
# File 'ext/RMagick/rmimage.c', line 7770

VALUE
Image_inspect(VALUE self)
{
    Image *image;
    char buffer[MaxTextExtent];          // image description buffer

    Data_Get_Struct(self, Image, image);
    if (!image)
    {
        return rb_str_new2("#<Magick::Image: (destroyed)>");
    }
    build_inspect_string(image, buffer, sizeof(buffer));
    return rb_str_new2(buffer);
}

#level(black_point = 0.0, white_point = nil, gamma = nil) ⇒ Object

(Thanks to Al Evans for the suggestion.)



904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
# File 'lib/rmagick_internal.rb', line 904

def level(black_point = 0.0, white_point = nil, gamma = nil)
  black_point = Float(black_point)

  white_point ||= Magick::QuantumRange - black_point
  white_point = Float(white_point)

  gamma_arg = gamma
  gamma ||= 1.0
  gamma = Float(gamma)

  if gamma.abs > 10.0 || white_point.abs <= 10.0 || white_point.abs < gamma.abs
    gamma, white_point = white_point, gamma
    white_point = Magick::QuantumRange - black_point unless gamma_arg
  end

  level2(black_point, white_point, gamma)
end

#level2Object

#level_channel(*args) ⇒ Object

Similar to Image#level but applies to a single channel only.

Ruby usage:

- @verbatim Image#level_channel(aChannelType) @endverbatim
- @verbatim Image#level_channel(aChannelType, black) @endverbatim
- @verbatim Image#level_channel(aChannelType, black, white) @endverbatim
- @verbatim Image#level_channel(aChannelType, black, white, gamma) @endverbatim

Notes:

- Default black is 0.0
- Default white is QuantumRange
- Default gamma is 1.0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:

  • Image_level2


7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
# File 'ext/RMagick/rmimage.c', line 7961

VALUE
Image_level_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    double black_point = 0.0, gamma_val = 1.0, white_point = (double)QuantumRange;
    ChannelType channel;

    image = rm_check_destroyed(self);
    switch (argc)
    {
        case 1:             // take all the defaults
            break;
        case 2:
            black_point = NUM2DBL(argv[1]);
            white_point = QuantumRange - black_point;
            break;
        case 3:
            black_point = NUM2DBL(argv[1]);
            white_point = NUM2DBL(argv[2]);
            break;
        case 4:
            black_point = NUM2DBL(argv[1]);
            white_point = NUM2DBL(argv[2]);
            gamma_val   = NUM2DBL(argv[3]);
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 4)", argc);
            break;
    }

    VALUE_TO_ENUM(argv[0], channel, ChannelType);

    new_image = rm_clone_image(image);

    (void) LevelImageChannel(new_image, channel, black_point, white_point, gamma_val);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#level_colors(*args) ⇒ Object

Implement +level_colors blank_color,white_color.

Ruby usage:

- @verbatim Image#level_colors @endverbatim
- @verbatim Image#level_colors(black_color) @endverbatim
- @verbatim Image#level_colors(black_color, white_color) @endverbatim
- @verbatim Image#level_colors(black_color, white_color, invert) @endverbatim
- @verbatim Image#level_colors(black_color, white_color, invert, channel) @endverbatim
- @verbatim Image#level_colors(black_color, white_color, invert, channel, ...) @endverbatim

Notes:

- Default black_color is "black"
- Default white_color is "white"
- Default invert is true
- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



8024
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
# File 'ext/RMagick/rmimage.c', line 8024

VALUE
Image_level_colors(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    MagickPixel black_color, white_color;
    ChannelType channels;
    MagickBooleanType invert = MagickTrue;
    MagickBooleanType status;

    image = rm_check_destroyed(self);

    channels = extract_channels(&argc, argv);

    rm_init_magickpixel(image, &white_color);
    rm_init_magickpixel(image, &black_color);

    switch (argc)
    {
        case 3:
            invert = RTEST(argv[2]);

        case 2:
            Color_to_MagickPixel(image, &white_color, argv[1]);
            Color_to_MagickPixel(image, &black_color, argv[0]);
            break;

        case 1:
            rm_set_magickpixel(&white_color, "white");
            Color_to_MagickPixel(image, &black_color, argv[0]);
            break;

        case 0:
            rm_set_magickpixel(&white_color, "white");
            rm_set_magickpixel(&black_color, "black");
            break;

        default:
            raise_ChannelType_error(argv[argc-1]);
            break;
    }

    new_image = rm_clone_image(image);

    status = LevelColorsImageChannel(new_image, channels, &black_color, &white_color, invert);
    rm_check_image_exception(new_image, DestroyOnError);
    if (!status)
    {
        rb_raise(rb_eRuntimeError, "LevelImageColors failed for unknown reason.");
    }

    return rm_image_new(new_image);
}

#levelize_channel(*args) ⇒ Object

Levelize on a channel.

Ruby usage:

- @verbatim Image#levelize_channel(black_point) @endverbatim
- @verbatim Image#levelize_channel(black_point, white_point) @endverbatim
- @verbatim Image#levelize_channel(black_point, white_point, gamma) @endverbatim
- @verbatim Image#levelize_channel(black_point, white_point, gamma, channel) @endverbatim
- @verbatim Image#levelize_channel(black_point, white_point, gamma, channel, ...) @endverbatim

Notes:

- Default white_point is QuantumRange
- Default gamma is 1.0
- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



8099
8100
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
# File 'ext/RMagick/rmimage.c', line 8099

VALUE
Image_levelize_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    ChannelType channels;
    double black_point, white_point;
    double gamma = 1.0;
    MagickBooleanType status;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);
    if (argc > 3)
    {
        raise_ChannelType_error(argv[argc-1]);
    }

    switch (argc)
    {
        case 3:
            gamma = NUM2DBL(argv[2]);
        case 2:
            white_point = NUM2DBL(argv[1]);
            black_point = NUM2DBL(argv[0]);
            break;
        case 1:
            black_point = NUM2DBL(argv[0]);
            white_point = QuantumRange - black_point;
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or more)", argc);
            break;
    }

    new_image = rm_clone_image(image);
    status = LevelizeImageChannel(new_image, channels, black_point, white_point, gamma);
    rm_check_image_exception(new_image, DestroyOnError);

    if (!status)
    {
        rb_raise(rb_eRuntimeError, "LevelizeImageChannel failed for unknown reason.");
    }
    return rm_image_new(new_image);
}

#linear_stretch(*args) ⇒ Object

Call LinearStretchImage.

Ruby usage:

- @verbatim Image_linear_stretch(black_point) @endverbatim
- @verbatim Image_linear_stretch(black_point , white_point) @endverbatim

Notes:

- Default white_point is pixels-black_point

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:

  • Image_contrast_stretch_channel.
  • get_black_white_point


8161
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175
# File 'ext/RMagick/rmimage.c', line 8161

VALUE
Image_linear_stretch(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    double black_point, white_point;

    image = rm_check_destroyed(self);
    get_black_white_point(image, argc, argv, &black_point, &white_point);
    new_image = rm_clone_image(image);

    (void) LinearStretchImage(new_image, black_point, white_point);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#liquid_rescale(*args) ⇒ Object

Call the LiquidRescaleImage API.

Ruby usage:

- @verbatim Image#liquid_rescale(columns, rows) @endverbatim
- @verbatim Image#liquid_rescale(columns, rows, delta_x) @endverbatim
- @verbatim Image#liquid_rescale(columns, rows, delta_x, rigidity) @endverbatim

Notes:

- Default delta_x is 0.0
- Default rigidity is 0.0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



8195
8196
8197
8198
8199
8200
8201
8202
8203
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
# File 'ext/RMagick/rmimage.c', line 8195

VALUE
Image_liquid_rescale(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    unsigned long cols, rows;
    double delta_x = 0.0;
    double rigidity = 0.0;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    switch (argc)
    {
        case 4:
            rigidity = NUM2DBL(argv[3]);
        case 3:
            delta_x = NUM2DBL(argv[2]);
        case 2:
            rows = NUM2ULONG(argv[1]);
            cols = NUM2ULONG(argv[0]);
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 to 4)", argc);
            break;
    }

    exception = AcquireExceptionInfo();
    new_image = LiquidRescaleImage(image, cols, rows, delta_x, rigidity, exception);
    rm_check_exception(exception, new_image, DestroyOnError);
    DestroyExceptionInfo(exception);
    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#magnifyObject

Scale an image proportionally to twice its size.

Ruby usage:

- @verbatim Image#magnify @endverbatim

Parameters:

  • self

    this object

Returns:

  • a new image

See Also:



8360
8361
8362
8363
8364
8365
# File 'ext/RMagick/rmimage.c', line 8360

VALUE
Image_magnify(VALUE self)
{
    (void) rm_check_destroyed(self);
    return magnify(False, self, MagnifyImage);
}

#magnify!Object

Scale an image proportionally to twice its size.

Ruby usage:

- @verbatim Image#magnify! @endverbatim

Parameters:

  • self

    this object

Returns:

  • self

See Also:



8379
8380
8381
8382
8383
8384
# File 'ext/RMagick/rmimage.c', line 8379

VALUE
Image_magnify_bang(VALUE self)
{
    (void) rm_check_frozen(self);
    return magnify(True, self, MagnifyImage);
}

#map(*args) ⇒ Object

Call MapImage.

Ruby usage:

- @verbatim Image#map(map_image) @endverbatim
- @verbatim Image#map(map_image, dither) @endverbatim

Notes:

- Default dither is false

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
8435
8436
8437
8438
8439
8440
8441
# File 'ext/RMagick/rmimage.c', line 8402

VALUE
Image_map(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    Image *map;
    VALUE map_obj, map_arg;
    unsigned int dither = MagickFalse;

    QuantizeInfo quantize_info;
    rb_warning("Image#map is deprecated. Use Image#remap instead");

    image = rm_check_destroyed(self);

    switch (argc)
    {
        case 2:
            dither = RTEST(argv[1]);
        case 1:
            map_arg = argv[0];
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
            break;
    }

    map_obj = rm_cur_image(map_arg);
    map = rm_check_destroyed(map_obj);

    new_image = rm_clone_image(image);

    GetQuantizeInfo(&quantize_info);
    quantize_info.dither=dither;
    (void) RemapImage(&quantize_info, new_image, map);
    rm_check_image_exception(new_image, DestroyOnError);

    RB_GC_GUARD(map_obj);
    RB_GC_GUARD(map_arg);

    return rm_image_new(new_image);
}

#marshal_dumpimg.filename, img.to_blob

Support Marshal.dump >= 1.8.

Ruby usage:

- @verbatim Image#marshal_dump @endverbatim

Parameters:

  • self

    this object

Returns:



8453
8454
8455
8456
8457
8458
8459
8460
8461
8462
8463
8464
8465
8466
8467
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478
8479
8480
8481
8482
8483
8484
8485
8486
# File 'ext/RMagick/rmimage.c', line 8453

VALUE
Image_marshal_dump(VALUE self)
{
    Image *image;
    Info *info;
    unsigned char *blob;
    size_t length;
    VALUE ary;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    info = CloneImageInfo(NULL);
    if (!info)
    {
        rb_raise(rb_eNoMemError, "not enough memory to initialize Info object");
    }

    ary = rb_ary_new2(2);
    rb_ary_store(ary, 0, rb_str_new2(image->filename));

    exception = AcquireExceptionInfo();
    blob = ImageToBlob(info, image, &length, exception);

    // Destroy info before raising an exception
    DestroyImageInfo(info);
    CHECK_EXCEPTION()
    (void) DestroyExceptionInfo(exception);

    rb_ary_store(ary, 1, rb_str_new((char *)blob, (long)length));
    magick_free((void*)blob);

    return ary;
}

#marshal_load(ary) ⇒ Object

Support Marshal.load >= 1.8.

Ruby usage:

- @verbatim Image#marshal_load @endverbatim

Parameters:

  • self

    this object

  • ary

    the array returned from marshal_dump

Returns:

  • self



8499
8500
8501
8502
8503
8504
8505
8506
8507
8508
8509
8510
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520
8521
8522
8523
8524
8525
8526
8527
8528
8529
8530
8531
# File 'ext/RMagick/rmimage.c', line 8499

VALUE
Image_marshal_load(VALUE self, VALUE ary)
{
    VALUE blob, filename;
    Info *info;
    Image *image;
    ExceptionInfo *exception;

    info = CloneImageInfo(NULL);
    if (!info)
    {
        rb_raise(rb_eNoMemError, "not enough memory to initialize Info object");
    }

    filename = rb_ary_shift(ary);
    blob = rb_ary_shift(ary);

    exception = AcquireExceptionInfo();
    if (filename != Qnil)
    {
        strcpy(info->filename, RSTRING_PTR(filename));
    }
    image = BlobToImage(info, RSTRING_PTR(blob), RSTRING_LEN(blob), exception);

    // Destroy info before raising an exception
    DestroyImageInfo(info);
    CHECK_EXCEPTION();
    (void) DestroyExceptionInfo(exception);

    UPDATE_DATA_PTR(self, image);

    return self;
}

#mask(*args) ⇒ Object

Associate a clip mask with the image.

Ruby usage:

- @verbatim Image#mask @endverbatim
- @verbatim Image#mask(mask-image) @endverbatim

Notes:

- Omit the argument to get a copy of the current clip mask.
- Pass "nil" for the mask-image to remove the current clip mask.
- If the clip mask is not the same size as the target image, resizes the
  clip mask to match the target.
- Distinguish from Image#clip_mask=

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • copy of the current clip-mask or nil

See Also:

  • get_image_mask


8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715
# File 'ext/RMagick/rmimage.c', line 8694

VALUE
Image_mask(int argc, VALUE *argv, VALUE self)
{
    VALUE mask;
    Image *image;

    image = rm_check_destroyed(self);
    if (argc == 0)
    {
        return get_image_mask(image);
    }
    if (argc > 1)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (expected 0 or 1, got %d)", argc);
    }

    rb_check_frozen(self);
    mask = argv[0];

    // Always return a copy of the mask!
    return set_image_mask(image, mask);
}

#matte_fill_to_border(x, y) ⇒ Object

Make transparent any neighbor pixel that is not the border color.



955
956
957
958
959
# File 'lib/rmagick_internal.rb', line 955

def matte_fill_to_border(x, y)
  f = copy
  f.alpha(OpaqueAlphaChannel) unless f.alpha?
  f.matte_flood_fill(border_color, x, y, FillToBorderMethod, alpha: TransparentAlpha)
end

#matte_flood_fill(*args) ⇒ Object

Call MatteFloodFillImage.

Ruby usage:

- @verbatim Image#matte_flood_fill(color x, y, method_obj, alpha: alpha) @endverbatim

Parameters:

  • self

    this object

  • color

    the color

  • alpha

    the alpha

  • x_obj

    x position

  • y_obj

    y position

  • method_obj

    which method to call: FloodfillMethod or FillToBorderMethod

Returns:

  • a new image



8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
8846
8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
8861
8862
8863
8864
8865
8866
8867
8868
8869
8870
8871
8872
8873
8874
8875
8876
8877
8878
8879
8880
8881
8882
8883
8884
8885
8886
8887
8888
8889
8890
8891
8892
8893
8894
8895
8896
8897
8898
8899
8900
8901
# File 'ext/RMagick/rmimage.c', line 8823

VALUE
Image_matte_flood_fill(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    PixelColor target;
    Quantum alpha;
    long x, y;
    PaintMethod method;
    DrawInfo *draw_info;
    MagickPixel target_mpp;
    MagickBooleanType invert;
    int start_index;

    image = rm_check_destroyed(self);

    if (argc != 5)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 5)", argc);
    }

    if (TYPE(argv[4]) == T_HASH)
    {
        alpha = get_alpha_from_hash(argv[4]);
        start_index = 1;
    }
    else
    {
        alpha = get_alpha_from_opacity(argv[1]);
        start_index = 2;
    }

    Color_to_PixelColor(&target, argv[0]);
    VALUE_TO_ENUM(argv[start_index + 2], method, PaintMethod);
    if (!(method == FloodfillMethod || method == FillToBorderMethod))
    {
        rb_raise(rb_eArgError, "paint method_obj must be FloodfillMethod or "
                 "FillToBorderMethod (%d given)", method);
    }
    x = NUM2LONG(argv[start_index]);
    y = NUM2LONG(argv[start_index + 1]);
    if ((unsigned long)x > image->columns || (unsigned long)y > image->rows)
    {
        rb_raise(rb_eArgError, "target out of range. %ldx%ld given, image is %lux%lu"
                 , x, y, image->columns, image->rows);
    }


    new_image = rm_clone_image(image);

    // FloodfillPaintImage looks for the opacity in the DrawInfo.fill field.
    draw_info = CloneDrawInfo(NULL, NULL);
    if (!draw_info)
    {
        rb_raise(rb_eNoMemError, "not enough memory to continue");
    }
    draw_info->fill.opacity = QuantumRange - alpha;

    if (method == FillToBorderMethod)
    {
        invert = MagickTrue;
        target_mpp.red   = (MagickRealType) image->border_color.red;
        target_mpp.green = (MagickRealType) image->border_color.green;
        target_mpp.blue  = (MagickRealType) image->border_color.blue;
    }
    else
    {
        invert = MagickFalse;
        target_mpp.red   = (MagickRealType) target.red;
        target_mpp.green = (MagickRealType) target.green;
        target_mpp.blue  = (MagickRealType) target.blue;
    }

    (void) FloodfillPaintImage(new_image, OpacityChannel, draw_info, &target_mpp, x, y, invert);
    (void) DestroyDrawInfo(draw_info);

    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#matte_floodfill(x, y) ⇒ Object

Make transparent any pixel that matches the color of the pixel at (x,y) and is a neighbor.



947
948
949
950
951
952
# File 'lib/rmagick_internal.rb', line 947

def matte_floodfill(x, y)
  f = copy
  f.alpha(OpaqueAlphaChannel) unless f.alpha?
  target = f.pixel_color(x, y)
  f.matte_flood_fill(target, x, y, FloodfillMethod, alpha: TransparentAlpha)
end

#matte_point(x, y) ⇒ Object

Make the pixel at (x,y) transparent.



927
928
929
930
931
932
933
934
# File 'lib/rmagick_internal.rb', line 927

def matte_point(x, y)
  f = copy
  f.alpha(OpaqueAlphaChannel) unless f.alpha?
  pixel = f.pixel_color(x, y)
  pixel.alpha = TransparentAlpha
  f.pixel_color(x, y, pixel)
  f
end

#matte_replace(x, y) ⇒ Object

Make transparent all pixels that are the same color as the pixel at (x, y).



938
939
940
941
942
943
# File 'lib/rmagick_internal.rb', line 938

def matte_replace(x, y)
  f = copy
  f.alpha(OpaqueAlphaChannel) unless f.alpha?
  target = f.pixel_color(x, y)
  f.transparent(target)
end

#matte_reset!Object

Make all pixels transparent.



962
963
964
965
# File 'lib/rmagick_internal.rb', line 962

def matte_reset!
  alpha(TransparentAlphaChannel)
  self
end

#median_filter(*args) ⇒ Object

Apply 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.

Ruby usage:

- @verbatim Image#median_filter @endverbatim
- @verbatim Image#median_filter(radius) @endverbatim

Notes:

- Default radius is 0.0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



8921
8922
8923
8924
8925
8926
8927
8928
8929
8930
8931
8932
8933
8934
8935
8936
8937
8938
8939
8940
8941
8942
8943
8944
8945
8946
8947
8948
8949
# File 'ext/RMagick/rmimage.c', line 8921

VALUE
Image_median_filter(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    double radius = 0.0;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    switch (argc)
    {
        case 1:
            radius = NUM2DBL(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
            break;
    }

    exception = AcquireExceptionInfo();
    new_image = StatisticImage(image, MedianStatistic, (size_t)radius, (size_t)radius, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#minifyObject

Scale an image proportionally to half its size.

Ruby usage:

- @verbatim Image#minify @endverbatim

Returns:

  • minify: a new image 1/2x the size of the input image

  • minify!: self, 1/2x

  • a new image

See Also:

  • Image_minify_bang


9009
9010
9011
9012
9013
9014
# File 'ext/RMagick/rmimage.c', line 9009

VALUE
Image_minify(VALUE self)
{
    (void) rm_check_destroyed(self);
    return magnify(False, self, MinifyImage);
}

#minify!Object

Scale an image proportionally to half its size.

Ruby usage:

- @verbatim Image#minify! @endverbatim

Parameters:

  • self

    this object

Returns:

  • self

See Also:

  • Image_minify


9027
9028
9029
9030
9031
9032
# File 'ext/RMagick/rmimage.c', line 9027

VALUE
Image_minify_bang(VALUE self)
{
    (void) rm_check_frozen(self);
    return magnify(True, self, MinifyImage);
}

#modulate(*args) ⇒ Object

Control the brightness, saturation, and hue of an image.

Ruby usage:

- @verbatim Image#modulate @endverbatim
- @verbatim Image#modulate(brightness) @endverbatim
- @verbatim Image#modulate(brightness, saturation) @endverbatim
- @verbatim Image#modulate(brightness, saturation, hue) @endverbatim

Notes:

- Default brightness is 100.0
- Default saturation is 100.0
- Default hue is 100.0
- all three arguments are optional and default to 100%

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068
9069
9070
9071
9072
9073
9074
9075
9076
9077
9078
9079
9080
9081
9082
9083
9084
9085
9086
9087
9088
9089
9090
9091
9092
9093
# File 'ext/RMagick/rmimage.c', line 9055

VALUE
Image_modulate(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    double pct_brightness = 100.0,
    pct_saturation = 100.0,
    pct_hue        = 100.0;
    char modulate[100];

    image = rm_check_destroyed(self);
    switch (argc)
    {
        case 3:
            pct_hue        = 100*NUM2DBL(argv[2]);
        case 2:
            pct_saturation = 100*NUM2DBL(argv[1]);
        case 1:
            pct_brightness = 100*NUM2DBL(argv[0]);
            break;
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 3)", argc);
            break;
    }

    if (pct_brightness <= 0.0)
    {
        rb_raise(rb_eArgError, "brightness is %g%%, must be positive", pct_brightness);
    }
    sprintf(modulate, "%f%%,%f%%,%f%%", pct_brightness, pct_saturation, pct_hue);

    new_image = rm_clone_image(image);

    (void) ModulateImage(new_image, modulate);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#monochrome?Boolean

Return true if all the pixels in the image have the same red, green, and blue intensities and the intensity is either 0 or QuantumRange.

Ruby usage:

- @verbatim Image#monochrome? @endverbatim

Parameters:

  • self

    this object

Returns:

  • (Boolean)

    true if monochrome, false otherwise



9139
9140
9141
9142
9143
# File 'ext/RMagick/rmimage.c', line 9139

VALUE
Image_monochrome_q(VALUE self)
{
    return has_attribute(self, IsMonochromeImage);
}

#morphology(method_v, iterations, kernel_v) ⇒ Object

Apply a user supplied kernel to the image according to the given mophology method.

Ruby Usage:
  - @verbatim Image#morphology(method, iterations, kernel) @endverbatim

@param self this object
@param method is one of morphology methods defined by Magick::MorphologyMethod
@param iterations apply the operation this many times (or no change).
                  A value of -1 means loop until no change found.
                  How this is applied may depend on the morphology method.
                  Typically this is a value of 1.
@param kernel morphology kernel to apply


4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
# File 'ext/RMagick/rmimage.c', line 4225

VALUE
Image_morphology(VALUE self, VALUE method_v, VALUE iterations, VALUE kernel_v)
{
    static VALUE default_channels_const = 0;

    if(!default_channels_const)
    {
        default_channels_const = rb_const_get(Module_Magick, rb_intern("DefaultChannels"));
    }

    return Image_morphology_channel(self, default_channels_const, method_v, iterations, kernel_v);
}

#morphology_channel(channel_v, method_v, iterations, kernel_v) ⇒ Object

Apply a user supplied kernel to the image channel according to the given mophology method.

Ruby Usage:
  - @verbatim Image#morphology_channel(channel, method, iterations, kernel) @endverbatim

@param self this object
@param channel is a channel type defined by Magick::ChannelType
@param method is one of morphology methods defined by Magick::MorphologyMethod
@param iterations apply the operation this many times (or no change).
                  A value of -1 means loop until no change found.
                  How this is applied may depend on the morphology method.
                  Typically this is a value of 1.
@param kernel morphology kernel to apply


4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
# File 'ext/RMagick/rmimage.c', line 4253

VALUE
Image_morphology_channel(VALUE self, VALUE channel_v, VALUE method_v, VALUE iterations, VALUE kernel_v)
{
    Image *image, *new_image;
    ExceptionInfo *exception;
    MorphologyMethod method;
    ChannelType channel;
    KernelInfo *kernel;

    image = rm_check_destroyed(self);

    VALUE_TO_ENUM(method_v, method, MorphologyMethod);
    VALUE_TO_ENUM(channel_v, channel, ChannelType);
    Check_Type(iterations, T_FIXNUM);

    if (TYPE(kernel_v) == T_STRING)
    {
        kernel_v = rb_class_new_instance(1, &kernel_v, Class_KernelInfo);
    }

    if (!rb_obj_is_kind_of(kernel_v, Class_KernelInfo))
    {
        rb_raise(rb_eArgError, "expected String or Magick::KernelInfo");
    }

    Data_Get_Struct(kernel_v, KernelInfo, kernel);

    exception = AcquireExceptionInfo();

    new_image = MorphologyImageChannel(image, channel, method, NUM2LONG(iterations), kernel, exception);
    rm_check_exception(exception, new_image, DestroyOnError);
    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);
    return rm_image_new(new_image);
}

#motion_blur(*args) ⇒ Object

Simulate motion blur. 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 motion_blur selects a suitable radius for you. Angle gives the angle of the blurring motion.

Ruby usage:

- @verbatim Image#motion_blur @endverbatim
- @verbatim Image#motion_blur(radius) @endverbatim
- @verbatim Image#motion_blur(radius, sigma) @endverbatim
- @verbatim Image#motion_blur(radius, sigma, angle) @endverbatim

Notes:

- Default radius is 0.0
- Default sigma is 1.0
- Default angle is 0.0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



9237
9238
9239
9240
9241
9242
# File 'ext/RMagick/rmimage.c', line 9237

VALUE
Image_motion_blur(int argc, VALUE *argv, VALUE self)
{
    (void) rm_check_destroyed(self);
    return motion_blur(argc, argv, self, MotionBlurImage);
}

#negate(*args) ⇒ Object

Negate the colors in the reference image. The grayscale option means that only grayscale values within the image are negated.

Ruby usage:

- @verbatim Image#negate @endverbatim
- @verbatim Image#negate(grayscale) @endverbatim

Notes:

- Default grayscale is false.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



9261
9262
9263
9264
9265
9266
9267
9268
9269
9270
9271
9272
9273
9274
9275
9276
9277
9278
9279
9280
9281
9282
9283
# File 'ext/RMagick/rmimage.c', line 9261

VALUE
Image_negate(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    unsigned int grayscale = MagickFalse;

    image = rm_check_destroyed(self);
    if (argc == 1)
    {
        grayscale = RTEST(argv[0]);
    }
    else if (argc > 1)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
    }

    new_image = rm_clone_image(image);

    (void) NegateImage(new_image, grayscale);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#negate_channel(*args) ⇒ Object

Negate the colors on a particular channel. The grayscale option means that only grayscale values within the image are negated.

Ruby usage:

- @verbatim Image#negate_channel(grayscale=false, channel=AllChannels) @endverbatim

Ruby usage:

- @verbatim Image#negate_channel @endverbatim
- @verbatim Image#negate_channel(grayscale) @endverbatim
- @verbatim Image#negate_channel(grayscale, channel) @endverbatim
- @verbatim Image#negate_channel(grayscale, channel, ...) @endverbatim

Notes:

- Default grayscale is false.
- Default channel is AllChannels.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



9308
9309
9310
9311
9312
9313
9314
9315
9316
9317
9318
9319
9320
9321
9322
9323
9324
9325
9326
9327
9328
9329
9330
9331
9332
9333
9334
9335
9336
# File 'ext/RMagick/rmimage.c', line 9308

VALUE
Image_negate_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    ChannelType channels;
    unsigned int grayscale = MagickFalse;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);

    // There can be at most 1 remaining argument.
    if (argc > 1)
    {
        raise_ChannelType_error(argv[argc-1]);
    }
    else if (argc == 1)
    {
        grayscale = RTEST(argv[0]);
    }

    Data_Get_Struct(self, Image, image);

    new_image = rm_clone_image(image);

    (void) NegateImageChannel(new_image, channels, grayscale);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#normalizeObject

Enhance the contrast of a color image by adjusting the pixels color to span the entire range of colors available.

Ruby usage:

- @verbatim Image#normalize @endverbatim

Parameters:

  • self

    this object

Returns:

  • a new image



9474
9475
9476
9477
9478
9479
9480
9481
9482
9483
9484
9485
9486
# File 'ext/RMagick/rmimage.c', line 9474

VALUE
Image_normalize(VALUE self)
{
    Image *image, *new_image;

    image = rm_check_destroyed(self);
    new_image = rm_clone_image(image);

    (void) NormalizeImage(new_image);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#normalize_channel(*args) ⇒ Object

Call NormalizeImageChannel.

Ruby usage:

- @verbatim Image#normalize_channel @endverbatim
- @verbatim Image#normalize_channel(channel) @endverbatim

Notes:

- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



9504
9505
9506
9507
9508
9509
9510
9511
9512
9513
9514
9515
9516
9517
9518
9519
9520
9521
9522
9523
9524
# File 'ext/RMagick/rmimage.c', line 9504

VALUE
Image_normalize_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    ChannelType channels;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);
    // Ensure all arguments consumed.
    if (argc > 0)
    {
        raise_ChannelType_error(argv[argc-1]);
    }

    new_image = rm_clone_image(image);

    (void) NormalizeImageChannel(new_image, channels);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#oil_paintObject

#opaque(target, fill) ⇒ Object

Change any pixel that matches target with the color defined by fill.

Ruby usage:

- @verbatim Image#opaque(target-color-name, fill-color-name) @endverbatim
- @verbatim Image#opaque(target-pixel, fill-pixel) @endverbatim

Notes:

- By default a pixel must match the specified target color exactly.
- Use Image_fuzz_eq to set the amount of tolerance acceptable to consider
  two colors as the same.

Parameters:

  • self

    this object

  • target

    either the color name or the pixel

  • fill

    the color for filling

See Also:

  • Image_fuzz_eq


9645
9646
9647
9648
9649
9650
9651
9652
9653
9654
9655
9656
9657
9658
9659
9660
9661
9662
9663
9664
9665
9666
9667
9668
9669
9670
9671
9672
# File 'ext/RMagick/rmimage.c', line 9645

VALUE
Image_opaque(VALUE self, VALUE target, VALUE fill)
{
    Image *image, *new_image;
    MagickPixel target_pp;
    MagickPixel fill_pp;
    MagickBooleanType okay;

    image = rm_check_destroyed(self);

    // Allow color name or Pixel
    Color_to_MagickPixel(image, &target_pp, target);
    Color_to_MagickPixel(image, &fill_pp, fill);

    new_image = rm_clone_image(image);

    okay = OpaquePaintImageChannel(new_image, DefaultChannels, &target_pp, &fill_pp, MagickFalse);
    rm_check_image_exception(new_image, DestroyOnError);

    if (!okay)
    {
        // Force exception
        DestroyImage(new_image);
        rm_ensure_result(NULL);
    }

    return rm_image_new(new_image);
}

#opaque?Boolean

Return true if any of the pixels in the image have an opacity value other than opaque ( 0 ).

Ruby usage:

- @verbatim Image#opaque? @endverbatim

Parameters:

  • self

    this object

Returns:

  • (Boolean)

    true if opaque, false otherwise



9765
9766
9767
9768
9769
# File 'ext/RMagick/rmimage.c', line 9765

VALUE
Image_opaque_q(VALUE self)
{
    return has_attribute(self, IsOpaqueImage);
}

#opaque_channel(*args) ⇒ Object

Improved Image#opaque available in ImageMagick 6.3.7-10.

Ruby usage:

- @verbatim Image#opaque_channel @endverbatim
- @verbatim opaque_channel(target, fill) @endverbatim
- @verbatim opaque_channel(target, fill, invert) @endverbatim
- @verbatim opaque_channel(target, fill, invert, fuzz) @endverbatim
- @verbatim opaque_channel(target, fill, invert, fuzz, channel) @endverbatim
- @verbatim opaque_channel(target, fill, invert, fuzz, channel, ...) @endverbatim

Notes:

- Default invert is false
- Default fuzz is the image's fuzz (see Image_fuzz_eq)
- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



9696
9697
9698
9699
9700
9701
9702
9703
9704
9705
9706
9707
9708
9709
9710
9711
9712
9713
9714
9715
9716
9717
9718
9719
9720
9721
9722
9723
9724
9725
9726
9727
9728
9729
9730
9731
9732
9733
9734
9735
9736
9737
9738
9739
9740
9741
9742
9743
9744
9745
9746
9747
9748
9749
9750
9751
9752
# File 'ext/RMagick/rmimage.c', line 9696

VALUE
Image_opaque_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    MagickPixel target_pp, fill_pp;
    ChannelType channels;
    double keep, fuzz;
    MagickBooleanType okay, invert = MagickFalse;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);
    if (argc > 4)
    {
        raise_ChannelType_error(argv[argc-1]);
    }

    // Default fuzz value is image's fuzz attribute.
    fuzz = image->fuzz;

    switch (argc)
    {
        case 4:
            fuzz = NUM2DBL(argv[3]);
            if (fuzz < 0.0)
            {
                rb_raise(rb_eArgError, "fuzz must be >= 0.0 (%g given)", fuzz);
            }
        case 3:
            invert = RTEST(argv[2]);
        case 2:
            // Allow color name or Pixel
            Color_to_MagickPixel(image, &fill_pp, argv[1]);
            Color_to_MagickPixel(image, &target_pp, argv[0]);
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (got %d, expected 2 or more)", argc);
            break;
    }

    new_image = rm_clone_image(image);
    keep = new_image->fuzz;
    new_image->fuzz = fuzz;

    okay = OpaquePaintImageChannel(new_image, channels, &target_pp, &fill_pp, invert);

    new_image->fuzz = keep;
    rm_check_image_exception(new_image, DestroyOnError);

    if (!okay)
    {
        // Force exception
        DestroyImage(new_image);
        rm_ensure_result(NULL);
    }

    return rm_image_new(new_image);
}

#ordered_dither(*args) ⇒ Object

Perform ordered dither on image.

Ruby usage:

- @verbatim Image#ordered_dither @endverbatim
- @verbatim Image#ordered_dither(threshold_map) @endverbatim

Notes:

- Default threshold_map is '2x2'
- Order of threshold_map must be 2, 3, or 4.
- If using ImageMagick >= 6.3.0, order can be any of the threshold strings
  listed by "convert -list Thresholds"
- Does not call OrderedDitherImages anymore. Sometime after ImageMagick
  6.0.0 it quit working. Uses the same routines as ImageMagick and
  GraphicsMagick for their "ordered-dither" option.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



9793
9794
9795
9796
9797
9798
9799
9800
9801
9802
9803
9804
9805
9806
9807
9808
9809
9810
9811
9812
9813
9814
9815
9816
9817
9818
9819
9820
9821
9822
9823
9824
9825
9826
9827
9828
9829
9830
9831
9832
9833
9834
9835
9836
9837
9838
9839
9840
9841
# File 'ext/RMagick/rmimage.c', line 9793

VALUE
Image_ordered_dither(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    int order;
    const char *threshold_map = "2x2";
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    if (argc > 1)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
    }
    if (argc == 1)
    {
        if (TYPE(argv[0]) == T_STRING)
        {
            threshold_map = StringValuePtr(argv[0]);
        }
        else
        {
            order = NUM2INT(argv[0]);
            if (order == 3)
            {
                threshold_map = "3x3";
            }
            else if (order == 4)
            {
                threshold_map = "4x4";
            }
            else if (order != 2)
            {
                rb_raise(rb_eArgError, "order must be 2, 3, or 4 (%d given)", order);
            }
        }
    }

    new_image = rm_clone_image(image);

    exception = AcquireExceptionInfo();

    (void) OrderedPosterizeImage(new_image, threshold_map, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    return rm_image_new(new_image);
}

#paint_transparent(*args) ⇒ Object

Improved version of Image#transparent available in ImageMagick 6.3.7-10.

Ruby usage:

- @verbatim Image#paint_transparent(target) @endverbatim
- @verbatim Image#paint_transparent(target, alpha: alpha) @endverbatim
- @verbatim Image#paint_transparent(target, invert, alpha: alpha) @endverbatim
- @verbatim Image#paint_transparent(target, invert, fuzz, alpha: alpha) @endverbatim

Notes:

- Default alpha is TransparentAlpha
- Default invert is false
- Default fuzz is the image's fuzz (see Image_fuzz_eq)

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



9935
9936
9937
9938
9939
9940
9941
9942
9943
9944
9945
9946
9947
9948
9949
9950
9951
9952
9953
9954
9955
9956
9957
9958
9959
9960
9961
9962
9963
9964
9965
9966
9967
9968
9969
9970
9971
9972
9973
9974
9975
9976
9977
9978
9979
9980
9981
9982
9983
9984
9985
9986
9987
9988
9989
9990
9991
9992
9993
9994
9995
9996
9997
9998
9999
10000
10001
10002
10003
10004
10005
10006
# File 'ext/RMagick/rmimage.c', line 9935

VALUE
Image_paint_transparent(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    MagickPixel color;
    Quantum alpha = TransparentAlpha;
    double keep, fuzz;
    MagickBooleanType okay, invert;

    image = rm_check_destroyed(self);

    // Default fuzz value is image's fuzz attribute.
    fuzz = image->fuzz;
    invert = MagickFalse;

    switch (argc)
    {
        case 4:
            if (TYPE(argv[argc - 1]) == T_HASH)
            {
                fuzz = NUM2DBL(argv[2]);
            }
            else
            {
                fuzz = NUM2DBL(argv[3]);
            }
        case 3:
            if (TYPE(argv[argc - 1]) == T_HASH)
            {
                invert = RTEST(argv[1]);
            }
            else
            {
                invert = RTEST(argv[2]);
            }
        case 2:
            if (TYPE(argv[argc - 1]) == T_HASH)
            {
                alpha = get_alpha_from_hash(argv[argc - 1]);
            }
            else
            {
                alpha = get_alpha_from_opacity(argv[1]);
            }
        case 1:
            Color_to_MagickPixel(image, &color, argv[0]);
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 4)", argc);
            break;
    }

    new_image = rm_clone_image(image);

    // Use fuzz value from caller
    keep = new_image->fuzz;
    new_image->fuzz = fuzz;

    okay = TransparentPaintImage(new_image, (const MagickPixel *)&color, QuantumRange - alpha, invert);
    new_image->fuzz = keep;

    // Is it possible for TransparentPaintImage to silently fail?
    rm_check_image_exception(new_image, DestroyOnError);
    if (!okay)
    {
        // Force exception
        DestroyImage(new_image);
        rm_ensure_result(NULL);
    }

    return rm_image_new(new_image);
}

#palette?Boolean

Return true if the image is PseudoClass and has 256 unique colors or less.

Ruby usage:

- @verbatim Image#palette? @endverbatim

Parameters:

  • self

    this object

Returns:

  • (Boolean)

    true if palette, otherwise false



10018
10019
10020
10021
10022
# File 'ext/RMagick/rmimage.c', line 10018

VALUE
Image_palette_q(VALUE self)
{
    return has_attribute(self, IsPaletteImage);
}

#pixel_color(*args) ⇒ Object

Get/set the color of the pixel at x,y.

Ruby usage:

- @verbatim Image#pixel_color(x, y) @endverbatim
- @verbatim Image#pixel_color(x, y, color) @endverbatim

Notes:

- Without color, does a get. With color, does a set.
- "color", if present, may be either a color name or a Magick::Pixel.
- Based on Magick++'s Magick::pixelColor methods

return value is the old color.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • Magick::Pixel for pixel x,y. If called to set a new color, the



10062
10063
10064
10065
10066
10067
10068
10069
10070
10071
10072
10073
10074
10075
10076
10077
10078
10079
10080
10081
10082
10083
10084
10085
10086
10087
10088
10089
10090
10091
10092
10093
10094
10095
10096
10097
10098
10099
10100
10101
10102
10103
10104
10105
10106
10107
10108
10109
10110
10111
10112
10113
10114
10115
10116
10117
10118
10119
10120
10121
10122
10123
10124
10125
10126
10127
10128
10129
10130
10131
10132
10133
10134
10135
10136
10137
10138
10139
10140
10141
10142
10143
10144
10145
10146
10147
10148
10149
10150
10151
10152
10153
10154
10155
10156
# File 'ext/RMagick/rmimage.c', line 10062

VALUE
Image_pixel_color(int argc, VALUE *argv, VALUE self)
{
    Image *image;
    PixelColor new_color;
    PixelPacket old_color;
    ExceptionInfo *exception;
    long x, y;
    unsigned int set = False;
    MagickBooleanType okay;
    PixelPacket *pixel;

    memset(&old_color, 0, sizeof(old_color));

    image = rm_check_destroyed(self);

    switch (argc)
    {
        case 3:
            rb_check_frozen(self);
            set = True;
            // Replace with new color? The arg can be either a color name or
            // a Magick::Pixel.
            Color_to_PixelColor(&new_color, argv[2]);
        case 2:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or 3)", argc);
            break;
    }

    x = NUM2LONG(argv[0]);
    y = NUM2LONG(argv[1]);

    // Get the color of a pixel
    if (!set)
    {
        exception = AcquireExceptionInfo();
        old_color = *GetVirtualPixels(image, x, y, 1, 1, exception);
        CHECK_EXCEPTION()

        (void) DestroyExceptionInfo(exception);

        // PseudoClass
        if (image->storage_class == PseudoClass)
        {
            IndexPacket *indexes = GetAuthenticIndexQueue(image);
            old_color = image->colormap[(unsigned long)*indexes];
        }
        if (!image->matte)
        {
            old_color.opacity = OpaqueOpacity;
        }
        return Pixel_from_PixelPacket(&old_color);
    }

    // ImageMagick segfaults if the pixel location is out of bounds.
    // Do what IM does and return the background color.
    if (x < 0 || y < 0 || (unsigned long)x >= image->columns || (unsigned long)y >= image->rows)
    {
        return Pixel_from_PixelColor(&image->background_color);
    }

    if (image->storage_class == PseudoClass)
    {
        okay = SetImageStorageClass(image, DirectClass);
        rm_check_image_exception(image, RetainOnError);
        if (!okay)
        {
            rb_raise(Class_ImageMagickError, "SetImageStorageClass failed. Can't set pixel color.");
        }
    }

    exception = AcquireExceptionInfo();

    pixel = GetAuthenticPixels(image, x, y, 1, 1, exception);
    CHECK_EXCEPTION()

    if (pixel)
    {
        old_color = *pixel;
        if (!image->matte)
        {
            old_color.opacity = OpaqueOpacity;
        }
        *pixel = new_color;

        SyncAuthenticPixels(image, exception);
        CHECK_EXCEPTION()
    }

    (void) DestroyExceptionInfo(exception);

    return Pixel_from_PixelPacket(&old_color);
}

#polaroid(*args) ⇒ Object

Call PolaroidImage.

Ruby usage:

- @verbatim Image#polaroid { optional parms } @endverbatim
- @verbatim Image#polaroid(angle) { optional parms } @endverbatim

Notes:

- Default angle is -5
- Accepts an options block to get Draw attributes for drawing the label.
  Specify self.border_color to set a non-default border color.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



10216
10217
10218
10219
10220
10221
10222
10223
10224
10225
10226
10227
10228
10229
10230
10231
10232
10233
10234
10235
10236
10237
10238
10239
10240
10241
10242
10243
10244
10245
10246
10247
10248
10249
10250
10251
10252
10253
10254
10255
10256
10257
# File 'ext/RMagick/rmimage.c', line 10216

VALUE
Image_polaroid(int argc, VALUE *argv, VALUE self)
{
    Image *image, *clone, *new_image;
    VALUE options;
    double angle = -5.0;
    Draw *draw;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    switch (argc)
    {
        case 1:
            angle = NUM2DBL(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
            break;
    }

    options = rm_polaroid_new();
    Data_Get_Struct(options, Draw, draw);

    clone = rm_clone_image(image);
    clone->background_color = draw->shadow_color;
    clone->border_color = draw->info->border_color;

    exception = AcquireExceptionInfo();
    new_image = PolaroidImage(clone, draw->info, angle, exception);
    rm_check_exception(exception, clone, DestroyOnError);

    (void) DestroyImage(clone);
    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    RB_GC_GUARD(options);

    return rm_image_new(new_image);
}

#posterize(*args) ⇒ Object

Call PosterizeImage.

Ruby usage:

- @verbatim Image#posterize(levels=4, dither=false) @endverbatim

Notes:

- Default levels is 4
- Default dither is false

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



10275
10276
10277
10278
10279
10280
10281
10282
10283
10284
10285
10286
10287
10288
10289
10290
10291
10292
10293
10294
10295
10296
10297
10298
10299
10300
10301
10302
10303
# File 'ext/RMagick/rmimage.c', line 10275

VALUE
Image_posterize(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    MagickBooleanType dither = MagickFalse;
    unsigned long levels = 4;

    image = rm_check_destroyed(self);
    switch (argc)
    {
        case 2:
            dither = (MagickBooleanType) RTEST(argv[1]);
            /* fall through */
        case 1:
            levels = NUM2ULONG(argv[0]);
            /* fall through */
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 2)", argc);
    }

    new_image = rm_clone_image(image);

    (void) PosterizeImage(new_image, levels, dither);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#preview(preview) ⇒ Object

Call PreviewImage.

Ruby usage:

- @verbatim Image#preview(preview) @endverbatim

Parameters:

  • self

    this object

  • preview

    the preview

Returns:

  • a new image



10316
10317
10318
10319
10320
10321
10322
10323
10324
10325
10326
10327
10328
10329
10330
10331
10332
10333
10334
10335
# File 'ext/RMagick/rmimage.c', line 10316

VALUE
Image_preview(VALUE self, VALUE preview)
{
    Image *image, *new_image;
    PreviewType preview_type;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    VALUE_TO_ENUM(preview, preview_type, PreviewType);

    exception = AcquireExceptionInfo();
    new_image = PreviewImage(image, preview_type, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#profile!(name, profile) ⇒ Object

Set the image profile. If “profile” is nil, deletes the profile. Otherwise “profile” must be a string containing the specified profile.

Ruby usage:

- @verbatim Image#profile!(name, profile) @endverbatim

Parameters:

  • self

    this object

  • name

    the profile name

  • profile

    the profile

Returns:

  • self



10350
10351
10352
10353
10354
10355
10356
10357
10358
10359
10360
10361
10362
10363
# File 'ext/RMagick/rmimage.c', line 10350

VALUE
Image_profile_bang(VALUE self, VALUE name, VALUE profile)
{

    if (profile == Qnil)
    {
        return Image_delete_profile(self, name);
    }
    else
    {
        return set_profile(self, StringValuePtr(name), profile);
    }

}

#propertiesObject

Traverse the attributes and yield to the block. If no block, return a hash of all the attribute keys & values.

Ruby usage:

- @verbatim Image#properties [{ |k,v| block }] @endverbatim

Notes:

- I use the word "properties" to distinguish between these "user-added"
  attribute strings and Image object attributes.

Parameters:

  • self

    this object

Returns:

  • self if block, else hash of attribute keys and values.



12139
12140
12141
12142
12143
12144
12145
12146
12147
12148
12149
12150
12151
12152
12153
12154
12155
12156
12157
12158
12159
12160
12161
12162
12163
12164
12165
12166
12167
12168
12169
12170
12171
12172
12173
12174
12175
12176
12177
12178
12179
12180
12181
12182
12183
12184
12185
12186
12187
12188
# File 'ext/RMagick/rmimage.c', line 12139

VALUE
Image_properties(VALUE self)
{
    Image *image;
    VALUE attr_hash, ary;
    const char *property, *value;

    image = rm_check_destroyed(self);

    if (rb_block_given_p())
    {
        ary = rb_ary_new2(2);

        ResetImagePropertyIterator(image);
        property = GetNextImageProperty(image);
        while (property)
        {
            value = GetImageProperty(image, property);
            (void) rb_ary_store(ary, 0, rb_str_new2(property));
            (void) rb_ary_store(ary, 1, rb_str_new2(value));
            (void) rb_yield(ary);
            property = GetNextImageProperty(image);
        }
        rm_check_image_exception(image, RetainOnError);

        RB_GC_GUARD(ary);

        return self;
    }

    // otherwise return properties hash
    else
    {
        attr_hash = rb_hash_new();
        ResetImagePropertyIterator(image);
        property = GetNextImageProperty(image);
        while (property)
        {
            value = GetImageProperty(image, property);
            (void) rb_hash_aset(attr_hash, rb_str_new2(property), rb_str_new2(value));
            property = GetNextImageProperty(image);
        }
        rm_check_image_exception(image, RetainOnError);

        RB_GC_GUARD(attr_hash);

        return attr_hash;
    }

}

#quantize(*args) ⇒ Object

Call QuantizeImage.

Ruby usage:

- @verbatim Image#quantize @endverbatim
- @verbatim Image#quantize(number_colors) @endverbatim
- @verbatim Image#quantize(number_colors, colorspace) @endverbatim
- @verbatim Image#quantize(number_colors, colorspace, dither) @endverbatim
- @verbatim Image#quantize(number_colors, colorspace, dither, tree_depth) @endverbatim
- @verbatim Image#quantize(number_colors, colorspace, dither, tree_depth, measure_error) @endverbatim

Notes:

- Default number_colors is 256
- Default colorspace is Magick::RGBColorspace
- Default dither is true
- Default tree_depth is 0
- Default measure_error is false

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



10595
10596
10597
10598
10599
10600
10601
10602
10603
10604
10605
10606
10607
10608
10609
10610
10611
10612
10613
10614
10615
10616
10617
10618
10619
10620
10621
10622
10623
10624
10625
10626
10627
10628
10629
10630
10631
10632
10633
10634
10635
10636
10637
# File 'ext/RMagick/rmimage.c', line 10595

VALUE
Image_quantize(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    QuantizeInfo quantize_info;

    image = rm_check_destroyed(self);
    GetQuantizeInfo(&quantize_info);

    switch (argc)
    {
        case 5:
            quantize_info.measure_error = (MagickBooleanType) RTEST(argv[4]);
        case 4:
            quantize_info.tree_depth = NUM2UINT(argv[3]);
        case 3:
            if (rb_obj_is_kind_of(argv[2], Class_DitherMethod))
            {
                VALUE_TO_ENUM(argv[2], quantize_info.dither_method, DitherMethod);
                quantize_info.dither = quantize_info.dither_method != NoDitherMethod;
            }
            else
            {
                quantize_info.dither = (MagickBooleanType) RTEST(argv[2]);
            }
        case 2:
            VALUE_TO_ENUM(argv[1], quantize_info.colorspace, ColorspaceType);
        case 1:
            quantize_info.number_colors = NUM2UINT(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 5)", argc);
            break;
    }

    new_image = rm_clone_image(image);

    (void) QuantizeImage(&quantize_info, new_image);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#quantum_operator(*args) ⇒ Object

This method is an adapter method that calls the EvaluateImageChannel method.

Ruby usage:

- @verbatim Image#quantum_operator(operator, rvalue) @endverbatim
- @verbatim Image#quantum_operator(operator, rvalue, channel) @endverbatim
- @verbatim Image#quantum_operator(operator, rvalue, channel, ...) @endverbatim

Notes:

- Historically this method used QuantumOperatorRegionImage in
  GraphicsMagick. By necessity this method implements the "lowest common
  denominator" of the two implementations.
- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • self



10424
10425
10426
10427
10428
10429
10430
10431
10432
10433
10434
10435
10436
10437
10438
10439
10440
10441
10442
10443
10444
10445
10446
10447
10448
10449
10450
10451
10452
10453
10454
10455
10456
10457
10458
10459
10460
10461
10462
10463
10464
10465
10466
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478
10479
10480
10481
10482
10483
10484
10485
10486
10487
10488
10489
10490
10491
10492
10493
10494
10495
10496
10497
10498
10499
10500
10501
10502
10503
10504
10505
10506
10507
10508
10509
10510
10511
10512
10513
10514
10515
10516
10517
10518
10519
10520
10521
10522
10523
10524
10525
10526
10527
10528
10529
10530
10531
10532
10533
10534
10535
10536
10537
10538
10539
10540
10541
10542
10543
10544
10545
10546
10547
10548
10549
10550
10551
10552
10553
10554
10555
10556
10557
10558
10559
10560
10561
10562
10563
10564
10565
10566
10567
10568
10569
# File 'ext/RMagick/rmimage.c', line 10424

VALUE
Image_quantum_operator(int argc, VALUE *argv, VALUE self)
{
    Image *image;
    QuantumExpressionOperator operator;
    MagickEvaluateOperator qop;
    double rvalue;
    ChannelType channel;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    // The default channel is AllChannels
    channel = AllChannels;

    /*
        If there are 3 arguments, argument 2 is a ChannelType argument.
        Arguments 1 and 0 are required and are the rvalue and operator,
        respectively.
    */
    switch (argc)
    {
        case 3:
            VALUE_TO_ENUM(argv[2], channel, ChannelType);
            /* Fall through */
        case 2:
            rvalue = NUM2DBL(argv[1]);
            VALUE_TO_ENUM(argv[0], operator, QuantumExpressionOperator);
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or 3)", argc);
            break;
    }

    // Map QuantumExpressionOperator to MagickEvaluateOperator
    switch (operator)
    {
        default:
        case UndefinedQuantumOperator:
            qop = UndefinedEvaluateOperator;
            break;
        case AddQuantumOperator:
            qop = AddEvaluateOperator;
            break;
        case AndQuantumOperator:
            qop = AndEvaluateOperator;
            break;
        case DivideQuantumOperator:
            qop = DivideEvaluateOperator;
            break;
        case LShiftQuantumOperator:
            qop = LeftShiftEvaluateOperator;
            break;
        case MaxQuantumOperator:
            qop = MaxEvaluateOperator;
            break;
        case MinQuantumOperator:
            qop = MinEvaluateOperator;
            break;
        case MultiplyQuantumOperator:
            qop = MultiplyEvaluateOperator;
            break;
        case OrQuantumOperator:
            qop = OrEvaluateOperator;
            break;
        case RShiftQuantumOperator:
            qop = RightShiftEvaluateOperator;
            break;
        case SubtractQuantumOperator:
            qop = SubtractEvaluateOperator;
            break;
        case XorQuantumOperator:
            qop = XorEvaluateOperator;
            break;
        case PowQuantumOperator:
            qop = PowEvaluateOperator;
            break;
        case LogQuantumOperator:
            qop = LogEvaluateOperator;
            break;
        case ThresholdQuantumOperator:
            qop = ThresholdEvaluateOperator;
            break;
        case ThresholdBlackQuantumOperator:
            qop = ThresholdBlackEvaluateOperator;
            break;
        case ThresholdWhiteQuantumOperator:
            qop = ThresholdWhiteEvaluateOperator;
            break;
        case GaussianNoiseQuantumOperator:
            qop = GaussianNoiseEvaluateOperator;
            break;
        case ImpulseNoiseQuantumOperator:
            qop = ImpulseNoiseEvaluateOperator;
            break;
        case LaplacianNoiseQuantumOperator:
            qop = LaplacianNoiseEvaluateOperator;
            break;
        case MultiplicativeNoiseQuantumOperator:
            qop = MultiplicativeNoiseEvaluateOperator;
            break;
        case PoissonNoiseQuantumOperator:
            qop = PoissonNoiseEvaluateOperator;
            break;
        case UniformNoiseQuantumOperator:
            qop = UniformNoiseEvaluateOperator;
            break;
        case CosineQuantumOperator:
            qop = CosineEvaluateOperator;
            break;
        case SineQuantumOperator:
            qop = SineEvaluateOperator;
            break;
        case AddModulusQuantumOperator:
            qop = AddModulusEvaluateOperator;
            break;
        case MeanQuantumOperator:
            qop = MeanEvaluateOperator;
            break;
        case AbsQuantumOperator:
            qop = AbsEvaluateOperator;
            break;
        case ExponentialQuantumOperator:
            qop = ExponentialEvaluateOperator;
            break;
        case MedianQuantumOperator:
            qop = MedianEvaluateOperator;
            break;
        case SumQuantumOperator:
            qop = SumEvaluateOperator;
            break;
#if defined(IMAGEMAGICK_GREATER_THAN_EQUAL_6_8_9)
        case RootMeanSquareQuantumOperator:
            qop = RootMeanSquareEvaluateOperator;
            break;
#endif
    }

    exception = AcquireExceptionInfo();
    (void) EvaluateImageChannel(image, channel, qop, rvalue, exception);
    CHECK_EXCEPTION()

    (void) DestroyExceptionInfo(exception);

    return self;
}

#radial_blur(angle_obj) ⇒ Object

Call RadialBlurImage.

Ruby usage:

- @verbatim Image#radial_blur(angle) @endverbatim

Parameters:

  • self

    this object

  • angle

    the angle (in degrees)

Returns:

  • a new image



10650
10651
10652
10653
10654
10655
10656
10657
10658
10659
10660
10661
10662
10663
10664
10665
10666
10667
10668
10669
10670
10671
10672
# File 'ext/RMagick/rmimage.c', line 10650

VALUE
Image_radial_blur(VALUE self, VALUE angle_obj)
{
    Image *image, *new_image;
    ExceptionInfo *exception;
    double angle = NUM2DBL(angle_obj);

    image = rm_check_destroyed(self);
    exception = AcquireExceptionInfo();

#if defined(IMAGEMAGICK_GREATER_THAN_EQUAL_6_8_9)
    new_image = RotationalBlurImage(image, angle, exception);
#else
    new_image = RadialBlurImage(image, angle, exception);
#endif
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#radial_blur_channel(*args) ⇒ Object

Call RadialBlurImageChannel.

Ruby usage:

- @verbatim Image#radial_blur_channel(angle) @endverbatim
- @verbatim Image#radial_blur_channel(angle, channel) @endverbatim
- @verbatim Image#radial_blur_channel(angle, channel, ...) @endverbatim

Notes:

- Default channel is AllChannels
- Angle is in degrees

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



10692
10693
10694
10695
10696
10697
10698
10699
10700
10701
10702
10703
10704
10705
10706
10707
10708
10709
10710
10711
10712
10713
10714
10715
10716
10717
10718
10719
10720
10721
10722
10723
10724
10725
10726
# File 'ext/RMagick/rmimage.c', line 10692

VALUE
Image_radial_blur_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    ExceptionInfo *exception;
    ChannelType channels;
    double angle;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);

    // There must be 1 remaining argument.
    if (argc == 0)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (0 for 1 or more)");
    }
    else if (argc > 1)
    {
        raise_ChannelType_error(argv[argc-1]);
    }

    angle = NUM2DBL(argv[0]);
    exception = AcquireExceptionInfo();

#if defined(IMAGEMAGICK_GREATER_THAN_EQUAL_6_8_9)
    new_image = RotationalBlurImageChannel(image, channels, angle, exception);
#else
    new_image = RadialBlurImageChannel(image, channels, angle, exception);
#endif
    rm_check_exception(exception, new_image, DestroyOnError);
    (void) DestroyExceptionInfo(exception);
    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#raise(*args) ⇒ Object

Create a simulated three-dimensional button-like effect by lightening and darkening the edges of the image. The “width” and “height” arguments define the width of the vertical and horizontal edge of the effect. If “raised” is true, creates a raised effect, otherwise a lowered effect.

Ruby usage:

- @verbatim Image#raise @endverbatim
- @verbatim Image#raise(width) @endverbatim
- @verbatim Image#raise(width, height) @endverbatim
- @verbatim Image#raise(width, height, raised) @endverbatim

Notes:

- Default width is 6
- Default height is 6
- Default raised is true

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



10809
10810
10811
10812
10813
10814
10815
10816
10817
10818
10819
10820
10821
10822
10823
10824
10825
10826
10827
10828
10829
10830
10831
10832
10833
10834
10835
10836
10837
10838
10839
10840
10841
10842
# File 'ext/RMagick/rmimage.c', line 10809

VALUE
Image_raise(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    RectangleInfo rect;
    int raised = MagickTrue;      // default

    memset(&rect, 0, sizeof(rect));
    rect.width = 6;         // default
    rect.height = 6;        // default

    image = rm_check_destroyed(self);
    switch (argc)
    {
        case 3:
            raised = RTEST(argv[2]);
        case 2:
            rect.height = NUM2ULONG(argv[1]);
        case 1:
            rect.width = NUM2ULONG(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 3)", argc);
            break;
    }

    new_image = rm_clone_image(image);

    (void) RaiseImage(new_image, &rect, raised);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#random_threshold_channel(*args) ⇒ Object

Call RandomThresholdImageChannel.

Ruby usage:

- @verbatim Image#random_threshold_channel(geometry_str) @endverbatim
- @verbatim Image#random_threshold_channel(geometry_str, channel) @endverbatim
- @verbatim Image#random_threshold_channel(geometry_str, channel, ...) @endverbatim

Notes:

- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



10745
10746
10747
10748
10749
10750
10751
10752
10753
10754
10755
10756
10757
10758
10759
10760
10761
10762
10763
10764
10765
10766
10767
10768
10769
10770
10771
10772
10773
10774
10775
10776
10777
10778
10779
10780
10781
10782
10783
10784
# File 'ext/RMagick/rmimage.c', line 10745

VALUE
Image_random_threshold_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    ChannelType channels;
    char *thresholds;
    VALUE geom_str;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    channels = extract_channels(&argc, argv);

    // There must be 1 remaining argument.
    if (argc == 0)
    {
        rb_raise(rb_eArgError, "missing threshold argument");
    }
    else if (argc > 1)
    {
        raise_ChannelType_error(argv[argc-1]);
    }

    // Accept any argument that has a to_s method.
    geom_str = rm_to_s(argv[0]);
    thresholds = StringValuePtr(geom_str);

    new_image = rm_clone_image(image);

    exception = AcquireExceptionInfo();

    (void) RandomThresholdImageChannel(new_image, channels, thresholds, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    RB_GC_GUARD(geom_str);

    return rm_image_new(new_image);
}

#recolor(color_matrix) ⇒ Object

Call RecolorImage.

Ruby usage:

- @verbatim Image#recolor(matrix) @endverbatim

Parameters:

  • self

    this object

  • color_matrix

    the matrix

Returns:

  • a new image



10960
10961
10962
10963
10964
10965
10966
10967
10968
10969
10970
10971
10972
10973
10974
10975
10976
10977
10978
10979
10980
10981
10982
10983
10984
10985
10986
10987
10988
10989
10990
10991
10992
10993
10994
10995
10996
10997
10998
10999
11000
11001
11002
11003
11004
11005
11006
11007
11008
11009
11010
11011
11012
11013
# File 'ext/RMagick/rmimage.c', line 10960

VALUE
Image_recolor(VALUE self, VALUE color_matrix)
{
    Image *image, *new_image;
    unsigned long order;
    long x, len;
    double *matrix;
    ExceptionInfo *exception;
    KernelInfo *kernel_info;

    image = rm_check_destroyed(self);
    color_matrix = rm_check_ary_type(color_matrix);

    // Allocate color matrix from Ruby's memory
    len = RARRAY_LEN(color_matrix);
    matrix = ALLOC_N(double, len);

    for (x = 0; x < len; x++)
    {
        VALUE element = rb_ary_entry(color_matrix, x);
        if (rm_check_num2dbl(element))
        {
            matrix[x] = NUM2DBL(element);
        }
        else
        {
            xfree(matrix);
            rb_raise(rb_eTypeError, "type mismatch: %s given", rb_class2name(CLASS_OF(element)));
        }
    }

    order = (unsigned long)sqrt((double)(len + 1.0));

    kernel_info = AcquireKernelInfo(NULL);
    if (kernel_info == (KernelInfo *) NULL)
    {
        xfree((void *) matrix);
        return Qnil;
    }
    kernel_info->width = order;
    kernel_info->height = order;
    kernel_info->values = (double *) matrix;

    exception = AcquireExceptionInfo();
    new_image = ColorMatrixImage(image, kernel_info, exception);
    kernel_info->values = (double *) NULL;
    (void) DestroyKernelInfo(kernel_info);
    xfree((void *) matrix);

    rm_check_exception(exception, new_image, DestroyOnError);
    (void) DestroyExceptionInfo(exception);

    return rm_image_new(new_image);
}

#reduce_noise(radius) ⇒ Object

Smooth the contours of an image while still preserving edge information.

Ruby usage:

- @verbatim Image#reduce_noise(radius) @endverbatim

Parameters:

  • self

    this object

  • radius

    the radius

Returns:

  • a new image



11129
11130
11131
11132
11133
11134
11135
11136
11137
11138
11139
11140
11141
11142
11143
11144
11145
# File 'ext/RMagick/rmimage.c', line 11129

VALUE
Image_reduce_noise(VALUE self, VALUE radius)
{
    Image *image, *new_image;
    ExceptionInfo *exception;
    size_t radius_size = NUM2SIZET(radius);

    image = rm_check_destroyed(self);

    exception = AcquireExceptionInfo();
    new_image = StatisticImage(image, NonpeakStatistic, radius_size, radius_size, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    return rm_image_new(new_image);
}

#remap(*args) ⇒ Object Also known as: affinity

Call RemapImage.

Ruby usage:

- @verbatim Image#remap(remap_image) @endverbatim
- @verbatim Image#remap(remap_image, dither_method) @endverbatim

Notes:

- Default dither_method is RiemersmaDitherMethod

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • self



11163
11164
11165
11166
11167
11168
11169
11170
11171
11172
11173
11174
11175
11176
11177
11178
11179
11180
11181
11182
11183
11184
11185
11186
11187
11188
11189
11190
11191
11192
11193
11194
11195
11196
# File 'ext/RMagick/rmimage.c', line 11163

VALUE
Image_remap(int argc, VALUE *argv, VALUE self)
{
    Image *image, *remap_image;
    QuantizeInfo quantize_info;

    image = rm_check_frozen(self);
    if (argc > 0)
    {
        VALUE t = rm_cur_image(argv[0]);
        remap_image = rm_check_destroyed(t);
        RB_GC_GUARD(t);
    }

    GetQuantizeInfo(&quantize_info);

    switch (argc)
    {
        case 2:
            VALUE_TO_ENUM(argv[1], quantize_info.dither_method, DitherMethod);
            quantize_info.dither = MagickTrue;
            break;
        case 1:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
            break;
    }

    (void) RemapImage(&quantize_info, image, remap_image);
    rm_check_image_exception(image, RetainOnError);

    return self;
}

#resample(*args) ⇒ Object

Resample image to specified horizontal resolution, vertical resolution, filter and blur factor.

Ruby usage:

- @verbatim Image#resample @endverbatim
- @verbatim Image#resample(resolution) @endverbatim
- @verbatim Image#resample(x_resolution, y_resolution) @endverbatim
- @verbatim Image#resample(x_resolution, y_resolution, filter) @endverbatim
- @verbatim Image#resample(x_resolution, y_resolution, filter, blur) @endverbatim

Notes:

- Default filter is image->filter
- Default blur is image->blur

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:



11343
11344
11345
11346
11347
11348
# File 'ext/RMagick/rmimage.c', line 11343

VALUE
Image_resample(int argc, VALUE *argv, VALUE self)
{
    (void) rm_check_destroyed(self);
    return resample(False, argc, argv, self);
}

#resample!(*args) ⇒ Object

Resample image to specified horizontal resolution, vertical resolution, filter and blur factor.

Ruby usage:

- @verbatim Image#resample @endverbatim
- @verbatim Image#resample(resolution) @endverbatim
- @verbatim Image#resample(x_resolution, y_resolution) @endverbatim
- @verbatim Image#resample(x_resolution, y_resolution, filter) @endverbatim
- @verbatim Image#resample(x_resolution, y_resolution, filter, blur) @endverbatim

Notes:

- Default filter is image->filter
- Default blur is image->blur

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:



11373
11374
11375
11376
11377
11378
# File 'ext/RMagick/rmimage.c', line 11373

VALUE
Image_resample_bang(int argc, VALUE *argv, VALUE self)
{
    (void) rm_check_frozen(self);
    return resample(True, argc, argv, self);
}

#resize(*args) ⇒ Object

Scale an image to the desired dimensions using the specified filter and blur factor.

Ruby usage:

- @verbatim Image#resize(scale) @endverbatim
- @verbatim Image#resize(cols, rows) @endverbatim
- @verbatim Image#resize(cols, rows, filter) @endverbatim
- @verbatim Image#resize(cols, rows, filter, blur) @endverbatim

Notes:

- Default filter is image->filter
- Default blur is image->blur

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:



11486
11487
11488
11489
11490
11491
# File 'ext/RMagick/rmimage.c', line 11486

VALUE
Image_resize(int argc, VALUE *argv, VALUE self)
{
    (void) rm_check_destroyed(self);
    return resize(False, argc, argv, self);
}

#resize!(*args) ⇒ Object

Scale an image to the desired dimensions using the specified filter and blur factor.

Ruby usage:

- @verbatim Image#resize!(scale) @endverbatim
- @verbatim Image#resize!(cols, rows) @endverbatim
- @verbatim Image#resize!(cols, rows, filter) @endverbatim
- @verbatim Image#resize!(cols, rows, filter, blur) @endverbatim

Notes:

- Default filter is image->filter
- Default blur is image->blur

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • self

See Also:



11515
11516
11517
11518
11519
11520
# File 'ext/RMagick/rmimage.c', line 11515

VALUE
Image_resize_bang(int argc, VALUE *argv, VALUE self)
{
    (void) rm_check_frozen(self);
    return resize(True, argc, argv, self);
}

#resize_to_fill(ncols, nrows = nil, gravity = CenterGravity) ⇒ Object Also known as: crop_resized

Force an image to exact dimensions without changing the aspect ratio. Resize and crop if necessary. (Thanks to Jerett Taylor!)



969
970
971
# File 'lib/rmagick_internal.rb', line 969

def resize_to_fill(ncols, nrows = nil, gravity = CenterGravity)
  copy.resize_to_fill!(ncols, nrows, gravity)
end

#resize_to_fill!(ncols, nrows = nil, gravity = CenterGravity) ⇒ Object Also known as: crop_resized!



973
974
975
976
977
978
979
980
981
# File 'lib/rmagick_internal.rb', line 973

def resize_to_fill!(ncols, nrows = nil, gravity = CenterGravity)
  nrows ||= ncols
  if ncols != columns || nrows != rows
    scale = [ncols / columns.to_f, nrows / rows.to_f].max
    resize!(scale * columns + 0.5, scale * rows + 0.5)
  end
  crop!(gravity, ncols, nrows, true) if ncols != columns || nrows != rows
  self
end

#resize_to_fit(cols, rows = nil) ⇒ Object

Convenience method to resize retaining the aspect ratio. (Thanks to Robert Manni!)



989
990
991
992
993
994
# File 'lib/rmagick_internal.rb', line 989

def resize_to_fit(cols, rows = nil)
  rows ||= cols
  change_geometry(Geometry.new(cols, rows)) do |ncols, nrows|
    resize(ncols, nrows)
  end
end

#resize_to_fit!(cols, rows = nil) ⇒ Object



996
997
998
999
1000
1001
# File 'lib/rmagick_internal.rb', line 996

def resize_to_fit!(cols, rows = nil)
  rows ||= cols
  change_geometry(Geometry.new(cols, rows)) do |ncols, nrows|
    resize!(ncols, nrows)
  end
end

#roll(x_offset, y_offset) ⇒ Object

Offset an image as defined by x_offset and y_offset.

Ruby usage:

- @verbatim Image#roll(x_offset, y_offset) @endverbatim

Parameters:

  • self

    this object

  • x_offset

    the x offset

  • y_offset

    the y offset

Returns:

  • a new image



11534
11535
11536
11537
11538
11539
11540
11541
11542
11543
11544
11545
11546
11547
11548
11549
11550
11551
11552
11553
# File 'ext/RMagick/rmimage.c', line 11534

VALUE
Image_roll(VALUE self, VALUE x_offset, VALUE y_offset)
{
    Image *image, *new_image;
    ExceptionInfo *exception;
    ssize_t x = NUM2LONG(x_offset);
    ssize_t y = NUM2LONG(y_offset);

    image = rm_check_destroyed(self);

    exception = AcquireExceptionInfo();
    new_image = RollImage(image, x, y, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#rotate(*args) ⇒ Object

Rotate the image.

Ruby usage:

- @verbatim Image#rotate(degrees) @endverbatim
- @verbatim Image#rotate(degrees, '<') @endverbatim
- @verbatim Image#rotate(degrees, '>') @endverbatim

Notes:

- If the 2nd argument is '<' rotate only if width < height. If the 2nd
  argument is '>' rotate only if width > height.
- Default is to always rotate

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:



11643
11644
11645
11646
11647
11648
# File 'ext/RMagick/rmimage.c', line 11643

VALUE
Image_rotate(int argc, VALUE *argv, VALUE self)
{
    (void) rm_check_destroyed(self);
    return rotate(False, argc, argv, self);
}

#rotate!(*args) ⇒ Object

Rotate the image.

Ruby usage:

- @verbatim Image#rotate!(degrees) @endverbatim
- @verbatim Image#rotate!(degrees, '<') @endverbatim
- @verbatim Image#rotate!(degrees, '>') @endverbatim

Notes:

- If the 2nd argument is '<' rotate only if width < height. If the 2nd
  argument is '>' rotate only if width > height.
- Default is to always rotate

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • self

See Also:



11671
11672
11673
11674
11675
11676
# File 'ext/RMagick/rmimage.c', line 11671

VALUE
Image_rotate_bang(int argc, VALUE *argv, VALUE self)
{
    (void) rm_check_frozen(self);
    return rotate(True, argc, argv, self);
}

#sampleObject

#sample!(*args) ⇒ Object

Scale an image to the desired dimensions with pixel sampling.

Ruby usage:

- @verbatim Image#sample!(scale) @endverbatim
- @verbatim Image#sample!(cols, rows) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • self

See Also:



11727
11728
11729
11730
11731
11732
# File 'ext/RMagick/rmimage.c', line 11727

VALUE
Image_sample_bang(int argc, VALUE *argv, VALUE self)
{
    (void) rm_check_frozen(self);
    return scale(True, argc, argv, self, SampleImage);
}

#scale(*args) ⇒ Object

Change the size of an image to the given dimensions.

Ruby usage:

- @verbatim Image#scale(scale) @endverbatim
- @verbatim Image#scale(cols, rows) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:



11749
11750
11751
11752
11753
11754
# File 'ext/RMagick/rmimage.c', line 11749

VALUE
Image_scale(int argc, VALUE *argv, VALUE self)
{
    (void) rm_check_destroyed(self);
    return scale(False, argc, argv, self, ScaleImage);
}

#scale!(*args) ⇒ Object

Change the size of an image to the given dimensions.

Ruby usage:

- @verbatim Image#scale!(scale) @endverbatim
- @verbatim Image#scale!(cols, rows) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • self

See Also:



11771
11772
11773
11774
11775
11776
# File 'ext/RMagick/rmimage.c', line 11771

VALUE
Image_scale_bang(int argc, VALUE *argv, VALUE self)
{
    (void) rm_check_frozen(self);
    return scale(True, argc, argv, self, ScaleImage);
}

#segment(*args) ⇒ Object

Call SegmentImage.

Ruby usage:

- @verbatim Image#segment @endverbatim
- @verbatim Image#segment(colorspace) @endverbatim
- @verbatim Image#segment(colorspace,cluster_threshold) @endverbatim
- @verbatim Image#segment(colorspace,cluster_threshold,smoothing_threshold) @endverbatim
- @verbatim Image#segment(colorspace,cluster_threshold,smoothing_threshold,verbose) @endverbatim

Notes:

- Default colorspace is RGBColorspace
- Default cluster_threshold is 1.0
- Default smoothing_threshold is 1.5
- Default verbose is false
- The default values are the same as Magick++

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



12061
12062
12063
12064
12065
12066
12067
12068
12069
12070
12071
12072
12073
12074
12075
12076
12077
12078
12079
12080
12081
12082
12083
12084
12085
12086
12087
12088
12089
12090
12091
12092
12093
12094
12095
# File 'ext/RMagick/rmimage.c', line 12061

VALUE
Image_segment(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    int colorspace              = RGBColorspace;    // These are the Magick++ defaults
    unsigned int verbose        = MagickFalse;
    double cluster_threshold    = 1.0;
    double smoothing_threshold  = 1.5;

    image = rm_check_destroyed(self);
    switch (argc)
    {
        case 4:
            verbose = RTEST(argv[3]);
        case 3:
            smoothing_threshold = NUM2DBL(argv[2]);
        case 2:
            cluster_threshold = NUM2DBL(argv[1]);
        case 1:
            VALUE_TO_ENUM(argv[0], colorspace, ColorspaceType);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 4)", argc);
            break;
    }

    new_image = rm_clone_image(image);

    (void) SegmentImage(new_image, colorspace, verbose, cluster_threshold, smoothing_threshold);
    rm_check_image_exception(new_image, DestroyOnError);
    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#selective_blur_channelObject

#separate(*args) ⇒ Object

Call SeparateImages.

Ruby usage:

- @verbatim separate @endverbatim
- @verbatim separate(channel) @endverbatim
- @verbatim separate(channel, ...) @endverbatim

Notes:

- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new ImageList



11967
11968
11969
11970
11971
11972
11973
11974
11975
11976
11977
11978
11979
11980
11981
11982
11983
11984
11985
11986
11987
11988
11989
11990
# File 'ext/RMagick/rmimage.c', line 11967

VALUE
Image_separate(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_images;
    ChannelType channels = 0;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);

    // All arguments are ChannelType enums
    if (argc > 0)
    {
        raise_ChannelType_error(argv[argc-1]);
    }

    exception = AcquireExceptionInfo();
    new_images = SeparateImages(image, channels, exception);
    rm_check_exception(exception, new_images, DestroyOnError);
    DestroyExceptionInfo(exception);
    rm_ensure_result(new_images);

    return rm_imagelist_from_images(new_images);
}

#sepiatone(*args) ⇒ Object

Call SepiaToneImage.

Ruby usage:

- @verbatim Image#sepiatone @endverbatim
- @verbatim Image#sepiatone(threshold) @endverbatim

Notes:

- Default threshold is QuantumRange

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



12008
12009
12010
12011
12012
12013
12014
12015
12016
12017
12018
12019
12020
12021
12022
12023
12024
12025
12026
12027
12028
12029
12030
12031
12032
12033
12034
12035
12036
# File 'ext/RMagick/rmimage.c', line 12008

VALUE
Image_sepiatone(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    double threshold = (double) QuantumRange;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    switch (argc)
    {
        case 1:
            threshold = NUM2DBL(argv[0]);
            break;
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
    }

    exception = AcquireExceptionInfo();
    new_image = SepiaToneImage(image, threshold, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);
    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#set_channel_depth(channel_arg, depth) ⇒ Object

Call SetImageChannelDepth.

Ruby usage:

- @verbatim Image#set_channel_depth(channel, depth) @endverbatim

Parameters:

  • self

    this object

  • channel_arg

    the channel

  • depth

    the depth

Returns:

  • self



11932
11933
11934
11935
11936
11937
11938
11939
11940
11941
11942
11943
11944
11945
11946
11947
11948
# File 'ext/RMagick/rmimage.c', line 11932

VALUE
Image_set_channel_depth(VALUE self, VALUE channel_arg, VALUE depth)
{
    Image *image;
    ChannelType channel;
    unsigned long channel_depth;

    image = rm_check_frozen(self);

    VALUE_TO_ENUM(channel_arg, channel, ChannelType);
    channel_depth = NUM2ULONG(depth);

    (void) SetImageChannelDepth(image, channel, channel_depth);
    rm_check_image_exception(image, RetainOnError);

    return self;
}

#shade(*args) ⇒ Object

Shine a distant light on an image to create a three-dimensional effect. You control the positioning of the light with azimuth and elevation; azimuth is measured in degrees off the x axis and elevation is measured in pixels above the Z axis.

Ruby usage:

- @verbatim Image#shade @endverbatim
- @verbatim Image#shade(shading) @endverbatim
- @verbatim Image#shade(shading, azimuth) @endverbatim
- @verbatim Image#shade(shading, azimuth, elevation) @endverbatim

Notes:

- Default shading is false
- Default azimuth is 30
- Default elevation is 30

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



12213
12214
12215
12216
12217
12218
12219
12220
12221
12222
12223
12224
12225
12226
12227
12228
12229
12230
12231
12232
12233
12234
12235
12236
12237
12238
12239
12240
12241
12242
12243
12244
12245
# File 'ext/RMagick/rmimage.c', line 12213

VALUE
Image_shade(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    double azimuth = 30.0, elevation = 30.0;
    unsigned int shading=MagickFalse;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    switch (argc)
    {
        case 3:
            elevation = NUM2DBL(argv[2]);
        case 2:
            azimuth = NUM2DBL(argv[1]);
        case 1:
            shading = RTEST(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 3)", argc);
            break;
    }

    exception = AcquireExceptionInfo();
    new_image = ShadeImage(image, shading, azimuth, elevation, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);
    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#shadow(*args) ⇒ Object

Call ShadowImage. X- and y-offsets are the pixel offset. Alpha is either a number between 0 and 1 or a string “NN%”. Sigma is the std. dev. of the Gaussian, in pixels.

Ruby usage:

- @verbatim Image#shadow @endverbatim
- @verbatim Image#shadow(x_offset) @endverbatim
- @verbatim Image#shadow(x_offset, y_offset) @endverbatim
- @verbatim Image#shadow(x_offset, y_offset, sigma) @endverbatim
- @verbatim Image#shadow(x_offset, y_offset, sigma, alpha) @endverbatim

Notes:

- Default x_offset is 4
- Default y_offset is 4
- Default sigma is 4.0
- Default alpha is 1.0
- The defaults are taken from the mogrify.c source, except for alpha,
  which has no default.
- Introduced in ImageMagick 6.1.7

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



12274
12275
12276
12277
12278
12279
12280
12281
12282
12283
12284
12285
12286
12287
12288
12289
12290
12291
12292
12293
12294
12295
12296
12297
12298
12299
12300
12301
12302
12303
12304
12305
12306
12307
12308
12309
12310
12311
12312
12313
12314
12315
12316
12317
# File 'ext/RMagick/rmimage.c', line 12274

VALUE
Image_shadow(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    double alpha = 100.0;
    double sigma = 4.0;
    long x_offset = 4L;
    long y_offset = 4L;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    switch (argc)
    {
        case 4:
            alpha = rm_percentage(argv[3],1.0);   // Clamp to 1.0 < x <= 100.0
            if (fabs(alpha) < 0.01)
            {
                rb_warning("shadow will be transparent - alpha %g very small", alpha);
            }
            alpha = FMIN(alpha, 1.0);
            alpha = FMAX(alpha, 0.01);
            alpha *= 100.0;
        case 3:
            sigma = NUM2DBL(argv[2]);
        case 2:
            y_offset = NUM2LONG(argv[1]);
        case 1:
            x_offset = NUM2LONG(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 4)", argc);
            break;
    }

    exception = AcquireExceptionInfo();
    new_image = ShadowImage(image, alpha, sigma, x_offset, y_offset, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);
    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#sharpen(*args) ⇒ Object

Sharpen an image.

Ruby usage:

- @verbatim Image#sharpen @endverbatim
- @verbatim Image#sharpen(radius) @endverbatim
- @verbatim Image#sharpen(radius, sigma) @endverbatim

Notes:

- Default radius is 0.0
- Default sigma is 1.0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:

  • effect_image


12338
12339
12340
12341
12342
# File 'ext/RMagick/rmimage.c', line 12338

VALUE
Image_sharpen(int argc, VALUE *argv, VALUE self)
{
    return effect_image(self, argc, argv, SharpenImage);
}

#sharpen_channel(*args) ⇒ Object

Sharpen image on a channel.

Ruby usage:

- @verbatim Image#sharpen_channel @endverbatim
- @verbatim Image#sharpen_channel(radius) @endverbatim
- @verbatim Image#sharpen_channel(radius, sigma) @endverbatim
- @verbatim Image#sharpen_channel(radius, sigma, channel) @endverbatim
- @verbatim Image#sharpen_channel(radius, sigma, channel, ...) @endverbatim

Notes:

- Default radius is 0.0
- Default sigma is 1.0
- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



12365
12366
12367
12368
12369
12370
12371
12372
12373
12374
12375
12376
12377
12378
12379
12380
12381
12382
12383
12384
12385
12386
12387
12388
12389
12390
12391
12392
12393
12394
12395
12396
12397
12398
# File 'ext/RMagick/rmimage.c', line 12365

VALUE
Image_sharpen_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    ChannelType channels;
    ExceptionInfo *exception;
    double radius = 0.0, sigma = 1.0;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);

    // There must be 0, 1, or 2 remaining arguments.
    switch (argc)
    {
        case 2:
            sigma = NUM2DBL(argv[1]);
            /* Fall thru */
        case 1:
            radius = NUM2DBL(argv[0]);
            /* Fall thru */
        case 0:
            break;
        default:
            raise_ChannelType_error(argv[argc-1]);
    }

    exception = AcquireExceptionInfo();
    new_image = SharpenImageChannel(image, channels, radius, sigma, exception);

    rm_check_exception(exception, new_image, DestroyOnError);
    (void) DestroyExceptionInfo(exception);

    return rm_image_new(new_image);
}

#shave(width, height) ⇒ Object

Shave pixels from the image edges, leaving a rectangle of the specified width & height in the center.

Ruby usage:

- @verbatim Image#shave(width, height) @endverbatim

Parameters:

  • self

    this object

  • width

    the width to leave

  • height

    the hight to leave

Returns:

  • a new image

See Also:

  • xform_image
  • Image_shave_bang


12415
12416
12417
12418
12419
12420
# File 'ext/RMagick/rmimage.c', line 12415

VALUE
Image_shave(VALUE self, VALUE width, VALUE height)
{
    (void) rm_check_destroyed(self);
    return xform_image(False, self, INT2FIX(0), INT2FIX(0), width, height, ShaveImage);
}

#shave!(width, height) ⇒ Object

Shave pixels from the image edges, leaving a rectangle of the specified width & height in the center.

Ruby usage:

- @verbatim Image#shave!(width, height) @endverbatim

Parameters:

  • self

    this object

  • width

    the width to leave

  • height

    the hight to leave

Returns:

  • self

See Also:

  • xform_image
  • Image_shave


12437
12438
12439
12440
12441
12442
# File 'ext/RMagick/rmimage.c', line 12437

VALUE
Image_shave_bang(VALUE self, VALUE width, VALUE height)
{
    (void) rm_check_frozen(self);
    return xform_image(True, self, INT2FIX(0), INT2FIX(0), width, height, ShaveImage);
}

#shear(x_shear, y_shear) ⇒ Object

Call ShearImage.

Ruby usage:

- @verbatim Image#shear(x_shear, y_shear) @endverbatim

Parameters:

  • self

    this object

  • x_shear

    the x shear (in degrees)

  • y_shear

    the y shear (in degrees)

Returns:

  • a new image



12456
12457
12458
12459
12460
12461
12462
12463
12464
12465
12466
12467
12468
12469
12470
12471
12472
12473
12474
# File 'ext/RMagick/rmimage.c', line 12456

VALUE
Image_shear(VALUE self, VALUE x_shear, VALUE y_shear)
{
    Image *image, *new_image;
    ExceptionInfo *exception;
    double x = NUM2DBL(x_shear);
    double y = NUM2DBL(y_shear);

    image = rm_check_destroyed(self);

    exception = AcquireExceptionInfo();
    new_image = ShearImage(image, x, y, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);
    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#sigmoidal_contrast_channel(*args) ⇒ Object

Call SigmoidalContrastImageChannel.

Ruby usage:

- @verbatim Image#sigmoidal_contrast_channel @endverbatim
- @verbatim Image#sigmoidal_contrast_channel(contrast) @endverbatim
- @verbatim Image#sigmoidal_contrast_channel(contrast, midpoint) @endverbatim
- @verbatim Image#sigmoidal_contrast_channel(contrast, midpoint, sharpen) @endverbatim
- @verbatim Image#sigmoidal_contrast_channel(contrast, midpoint, sharpen, channel) @endverbatim
- @verbatim Image#sigmoidal_contrast_channel(contrast, midpoint, sharpen, channel, ...) @endverbatim

Notes:

- Default contrast is 3.0
- Default midpoint is 50.0
- Default sharpen is false
- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



12499
12500
12501
12502
12503
12504
12505
12506
12507
12508
12509
12510
12511
12512
12513
12514
12515
12516
12517
12518
12519
12520
12521
12522
12523
12524
12525
12526
12527
12528
12529
12530
12531
12532
# File 'ext/RMagick/rmimage.c', line 12499

VALUE
Image_sigmoidal_contrast_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    MagickBooleanType sharpen = MagickFalse;
    double contrast = 3.0;
    double midpoint = 50.0;
    ChannelType channels;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);

    switch (argc)
    {
        case 3:
            sharpen  = (MagickBooleanType) RTEST(argv[2]);
        case 2:
            midpoint = NUM2DBL(argv[1]);
        case 1:
            contrast = NUM2DBL(argv[0]);
        case 0:
            break;
        default:
            raise_ChannelType_error(argv[argc-1]);
            break;
    }

    new_image = rm_clone_image(image);

    (void) SigmoidalContrastImageChannel(new_image, channels, sharpen, contrast, midpoint);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#signatureObject

Compute a message digest from an image pixel stream with an implementation of the NIST SHA-256 Message Digest algorithm.

Ruby usage:

- @verbatim Image#signature @endverbatim

Parameters:

  • self

    this object

Returns:

  • the message digest



12545
12546
12547
12548
12549
12550
12551
12552
12553
12554
12555
12556
12557
12558
12559
12560
12561
# File 'ext/RMagick/rmimage.c', line 12545

VALUE
Image_signature(VALUE self)
{
    Image *image;
    const char *signature;

    image = rm_check_destroyed(self);

    (void) SignatureImage(image);
    rm_check_image_exception(image, RetainOnError);
    signature = rm_get_property(image, "signature");
    if (!signature)
    {
        return Qnil;
    }
    return rb_str_new(signature, 64);
}

#sketch(*args) ⇒ Object

Call SketchImage.

Ruby usage:

- @verbatim Image#sketch @endverbatim
- @verbatim Image#sketch(radius) @endverbatim
- @verbatim Image#sketch(radius, sigma) @endverbatim
- @verbatim Image#sketch(radius, sigma, angle) @endverbatim

Notes:

- Default radius is 0.0
- Default sigma is 1.0
- Default angle is 0.0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:



12584
12585
12586
12587
12588
12589
# File 'ext/RMagick/rmimage.c', line 12584

VALUE
Image_sketch(int argc, VALUE *argv, VALUE self)
{
    (void) rm_check_destroyed(self);
    return motion_blur(argc, argv, self, SketchImage);
}

#solarize(*args) ⇒ Object

Apply a special effect to the image, similar to the effect achieved in a photo darkroom by selectively exposing areas of photo sensitive paper to light. Threshold ranges from 0 to QuantumRange and is a measure of the extent of the solarization.

Ruby usage:

- @verbatim Image#solarize @endverbatim
- @verbatim Image#solarize(threshold) @endverbatim

Notes:

- Default threshold is 50.0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



12610
12611
12612
12613
12614
12615
12616
12617
12618
12619
12620
12621
12622
12623
12624
12625
12626
12627
12628
12629
12630
12631
12632
12633
12634
12635
12636
12637
12638
# File 'ext/RMagick/rmimage.c', line 12610

VALUE
Image_solarize(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    double threshold = 50.0;

    image = rm_check_destroyed(self);
    switch (argc)
    {
        case 1:
            threshold = NUM2DBL(argv[0]);
            if (threshold < 0.0 || threshold > QuantumRange)
            {
                rb_raise(rb_eArgError, "threshold out of range, must be >= 0.0 and < QuantumRange");
            }
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
            break;
    }

    new_image = rm_clone_image(image);

    (void) SolarizeImage(new_image, threshold);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#sparse_color(*args) ⇒ Object

Call SparseColorInterpolate.

Ruby usage:

- @verbatim Image#sparse_color(method, x1, y1, color) @endverbatim
- @verbatim Image#sparse_color(method, x1, y1, color, x2, y2, color) @endverbatim
- @verbatim Image#sparse_color(method, x1, y1, color, x2, y2, color, ...) @endverbatim
- @verbatim Image#sparse_color(method, x1, y1, color, channel) @endverbatim
- @verbatim Image#sparse_color(method, x1, y1, color, x2, y2, color, channel) @endverbatim
- @verbatim Image#sparse_color(method, x1, y1, color, x2, y2, color, ..., channel) @endverbatim
- @verbatim Image#sparse_color(method, x1, y1, color, channel, ...) @endverbatim
- @verbatim Image#sparse_color(method, x1, y1, color, x2, y2, color, channel, ...) @endverbatim
- @verbatim Image#sparse_color(method, x1, y1, color, x2, y2, color, ..., channel, ...) @endverbatim

Notes:

- Default channel is AllChannels
- As usual, 'color' can be either a color name or a pixel

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



12756
12757
12758
12759
12760
12761
12762
12763
12764
12765
12766
12767
12768
12769
12770
12771
12772
12773
12774
12775
12776
12777
12778
12779
12780
12781
12782
12783
12784
12785
12786
12787
12788
12789
12790
12791
12792
12793
12794
12795
12796
12797
12798
12799
12800
12801
12802
12803
12804
12805
12806
12807
12808
12809
12810
12811
12812
12813
12814
12815
12816
12817
12818
12819
12820
12821
12822
12823
12824
12825
12826
12827
12828
12829
12830
12831
12832
12833
12834
12835
12836
12837
12838
12839
12840
12841
12842
12843
12844
12845
# File 'ext/RMagick/rmimage.c', line 12756

VALUE
Image_sparse_color(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    unsigned long x, nargs, ncolors;
    SparseColorMethod method;
    int n, exp;
    double * volatile args;
    ChannelType channels;
    MagickPixel pp;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    n = argc;
    channels = extract_channels(&argc, argv);
    n -= argc;  // n is now the number of channel arguments

    // After the channel arguments have been removed, and not counting the first
    // (method) argument, the number of arguments should be a multiple of 3.
    if (argc < 4 || argc % 3 != 1)
    {
        exp = argc - 1;
        exp = (argc + 2) / 3 * 3;
        exp = max(exp, 3);
        rb_raise(rb_eArgError, "wrong number of arguments (expected at least %d, got %d)", n+exp+1,  n+argc);
    }

    // Get the method from the argument list
    VALUE_TO_ENUM(argv[0], method, SparseColorMethod);
    argv += 1;
    argc -= 1;

    // A lot of the following code is based on SparseColorOption, in wand/mogrify.c
    ncolors = count_channels(image, &channels);
    nargs = (argc / 3) * (2 + ncolors);

    // Allocate args from Ruby's memory so that GC will collect it if one of
    // the type conversions below raises an exception.
    args = ALLOC_N(double, nargs);
    memset(args, 0, nargs * sizeof(double));

    x = 0;
    n = 0;
    while (n < argc)
    {
        VALUE elem1 = argv[n++];
        VALUE elem2 = argv[n++];
        if (rm_check_num2dbl(elem1) && rm_check_num2dbl(elem2))
        {
            args[x++] = NUM2DBL(elem1);
            args[x++] = NUM2DBL(elem2);
        }
        else
        {
            xfree((void *) args);
            rb_raise(rb_eTypeError, "type mismatch: %s and %s given", rb_class2name(CLASS_OF(elem1)), rb_class2name(CLASS_OF(elem2)));
        }
        Color_to_MagickPixel(NULL, &pp, argv[n++]);
        if (channels & RedChannel)
        {
            args[x++] = pp.red / QuantumRange;
        }
        if (channels & GreenChannel)
        {
            args[x++] = pp.green / QuantumRange;
        }
        if (channels & BlueChannel)
        {
            args[x++] = pp.blue / QuantumRange;
        }
        if (channels & IndexChannel)
        {
            args[x++] = pp.index / QuantumRange;
        }
        if (channels & OpacityChannel)
        {
            args[x++] = pp.opacity / QuantumRange;
        }
    }

    exception = AcquireExceptionInfo();
    new_image = SparseColorImage(image, channels, method, nargs, args, exception);
    xfree((void *) args);
    rm_check_exception(exception, new_image, DestroyOnError);
    (void) DestroyExceptionInfo(exception);
    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#splice(*args) ⇒ Object

Splice a solid color into the part of the image specified by the x, y, width, and height arguments. If the color argument is specified it must be a color name or Pixel.

Ruby usage:

- @verbatim Image#splice(x, y, width, height) @endverbatim
- @verbatim Image#splice(x, y, width, height, color) @endverbatim

Notes:

- Default color is the background color.
- Splice is the inverse of chop

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:

  • Image_chop


12867
12868
12869
12870
12871
12872
12873
12874
12875
12876
12877
12878
12879
12880
12881
12882
12883
12884
12885
12886
12887
12888
12889
12890
12891
12892
12893
12894
12895
12896
12897
12898
12899
12900
12901
12902
12903
12904
12905
12906
12907
12908
12909
12910
12911
12912
# File 'ext/RMagick/rmimage.c', line 12867

VALUE
Image_splice(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    PixelColor color, old_color;
    RectangleInfo rectangle;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    switch (argc)
    {
        case 4:
            // use background color
            color = image->background_color;
            break;
        case 5:
            // Convert color argument to PixelColor
            Color_to_PixelColor(&color, argv[4]);
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 4 or 5)", argc);
            break;
    }

    rectangle.x      = NUM2LONG(argv[0]);
    rectangle.y      = NUM2LONG(argv[1]);
    rectangle.width  = NUM2ULONG(argv[2]);
    rectangle.height = NUM2ULONG(argv[3]);

    exception = AcquireExceptionInfo();

    // Swap in color for the duration of this call.
    old_color = image->background_color;
    image->background_color = color;
    new_image = SpliceImage(image, &rectangle, exception);
    image->background_color = old_color;

    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#spread(*args) ⇒ Object

Randomly displace each pixel in a block defined by “radius”.

Ruby usage:

- @verbatim Image#spread @endverbatim
- @verbatim Image#spread(radius) @endverbatim

Notes:

- Default radius is 3.0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



12930
12931
12932
12933
12934
12935
12936
12937
12938
12939
12940
12941
12942
12943
12944
12945
12946
12947
12948
12949
12950
12951
12952
12953
12954
12955
12956
12957
# File 'ext/RMagick/rmimage.c', line 12930

VALUE
Image_spread(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    double radius = 3.0;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    switch (argc)
    {
        case 1:
            radius = NUM2DBL(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
            break;
    }

    exception = AcquireExceptionInfo();
    new_image = SpreadImage(image, radius, exception);
    rm_check_exception(exception, new_image, DestroyOnError);
    rm_ensure_result(new_image);

    (void) DestroyExceptionInfo(exception);

    return rm_image_new(new_image);
}

#steganoObject

#stereo(offset_image_arg) ⇒ Object

Combine two images and produces a single image that is the composite of a left and right image of a stereo pair. Special red-green stereo glasses are required to view this effect.

Ruby usage:

- @verbatim Image#stereo(offset_image) @endverbatim

Parameters:

  • self

    this object

  • offset_image_arg

    the other image

Returns:

  • a new image



13016
13017
13018
13019
13020
13021
13022
13023
13024
13025
13026
13027
13028
13029
13030
13031
13032
13033
13034
13035
13036
13037
13038
13039
13040
# File 'ext/RMagick/rmimage.c', line 13016

VALUE
Image_stereo(VALUE self, VALUE offset_image_arg)
{
    Image *image, *new_image;
    VALUE offset_image;
    Image *offset;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    offset_image = rm_cur_image(offset_image_arg);
    offset = rm_check_destroyed(offset_image);

    exception = AcquireExceptionInfo();
    new_image = StereoImage(image, offset, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    RB_GC_GUARD(offset_image);

    return rm_image_new(new_image);
}

#store_pixels(x_arg, y_arg, cols_arg, rows_arg, new_pixels) ⇒ Object

Replace the pixels in the specified rectangle.

Ruby usage:

- @verbatim Image#store_pixels(x,y,cols,rows,new_pixels) @endverbatim

Notes:

- Calls GetImagePixels, then SyncImagePixels after replacing the pixels.
- This is the complement of get_pixels. The array object returned by
  get_pixels is suitable for use as the "new_pixels" argument.

Parameters:

  • self

    this object

  • x_arg

    x position of start of region

  • y_arg

    y position of start of region

  • cols_arg

    width of region

  • rows_arg

    height of region

  • new_pixels

    the replacing pixels

Returns:

  • self



13129
13130
13131
13132
13133
13134
13135
13136
13137
13138
13139
13140
13141
13142
13143
13144
13145
13146
13147
13148
13149
13150
13151
13152
13153
13154
13155
13156
13157
13158
13159
13160
13161
13162
13163
13164
13165
13166
13167
13168
13169
13170
13171
13172
13173
13174
13175
13176
13177
13178
13179
13180
13181
13182
13183
13184
13185
13186
13187
13188
13189
13190
13191
13192
13193
# File 'ext/RMagick/rmimage.c', line 13129

VALUE
Image_store_pixels(VALUE self, VALUE x_arg, VALUE y_arg, VALUE cols_arg
                   , VALUE rows_arg, VALUE new_pixels)
{
    Image *image;
    Pixel *pixel;
    VALUE new_pixel;
    long n, size;
    long x, y;
    unsigned long cols, rows;
    unsigned int okay;
    ExceptionInfo *exception;
    PixelPacket *pixels;

    image = rm_check_destroyed(self);

    x = NUM2LONG(x_arg);
    y = NUM2LONG(y_arg);
    cols = NUM2ULONG(cols_arg);
    rows = NUM2ULONG(rows_arg);
    if (x < 0 || y < 0 || x+cols > image->columns || y+rows > image->rows)
    {
        rb_raise(rb_eRangeError, "geometry (%lux%lu%+ld%+ld) exceeds image bounds"
                 , cols, rows, x, y);
    }

    size = (long)(cols * rows);
    rm_check_ary_len(new_pixels, size);

    okay = SetImageStorageClass(image, DirectClass);
    rm_check_image_exception(image, RetainOnError);
    if (!okay)
    {
        rb_raise(Class_ImageMagickError, "SetImageStorageClass failed. Can't store pixels.");
    }

    // Get a pointer to the pixels. Replace the values with the PixelPackets
    // from the pixels argument.
    {
        exception = AcquireExceptionInfo();

        pixels = GetAuthenticPixels(image, x, y, cols, rows, exception);
        CHECK_EXCEPTION()
        DestroyExceptionInfo(exception);

        if (pixels)
        {
            for (n = 0; n < size; n++)
            {
                new_pixel = rb_ary_entry(new_pixels, n);
                Data_Get_Struct(new_pixel, Pixel, pixel);
                pixels[n] = *pixel;
            }
            exception = AcquireExceptionInfo();

            SyncAuthenticPixels(image, exception);
            CHECK_EXCEPTION()
            DestroyExceptionInfo(exception);
        }
    }

    RB_GC_GUARD(new_pixel);

    return self;
}

#strip!Object

Strips an image of all profiles and comments.

Ruby usage:

- @verbatim Image#strip! @endverbatim

Parameters:

  • self

    this object

Returns:

  • self



13205
13206
13207
13208
13209
13210
13211
13212
# File 'ext/RMagick/rmimage.c', line 13205

VALUE
Image_strip_bang(VALUE self)
{
    Image *image = rm_check_frozen(self);
    (void) StripImage(image);
    rm_check_image_exception(image, RetainOnError);
    return self;
}

#swirl(degrees_obj) ⇒ Object

Swirl the pixels about the center of the image, where degrees indicates the sweep of the arc through which each pixel is moved. You get a more dramatic effect as the degrees move from 1 to 360.

Ruby usage:

- @verbatim Image#swirl(degrees) @endverbatim

Parameters:

  • self

    this object

  • degrees

    the degrees

Returns:

  • a new image



13227
13228
13229
13230
13231
13232
13233
13234
13235
13236
13237
13238
13239
13240
13241
13242
13243
13244
13245
# File 'ext/RMagick/rmimage.c', line 13227

VALUE
Image_swirl(VALUE self, VALUE degrees_obj)
{
    Image *image, *new_image;
    ExceptionInfo *exception;
    double degrees = NUM2DBL(degrees_obj);

    image = rm_check_destroyed(self);

    exception = AcquireExceptionInfo();
    new_image = SwirlImage(image, degrees, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#sync_profilesObject

Deprecated.

This method has been deprecated.

Synchronize image properties with the image profiles.

Ruby usage:

- @verbatim Image#sync_profiles @endverbatim

Parameters:

  • self

    this object

Returns:

  • true if succeeded, otherwise false



13258
13259
13260
13261
13262
13263
13264
13265
13266
13267
13268
13269
# File 'ext/RMagick/rmimage.c', line 13258

VALUE
Image_sync_profiles(VALUE self)
{
    rb_warning("Image#sync_profiles is deprecated");
    Image *image = rm_check_destroyed(self);
    VALUE okay =  SyncImageProfiles(image) ? Qtrue : Qfalse;
    rm_check_image_exception(image, RetainOnError);

    RB_GC_GUARD(okay);

    return okay;
}

#texture_fill_to_border(x, y, texture) ⇒ Object

Replace neighboring pixels to border color with texture pixels



1010
1011
1012
# File 'lib/rmagick_internal.rb', line 1010

def texture_fill_to_border(x, y, texture)
  texture_flood_fill(border_color, texture, x, y, FillToBorderMethod)
end

#texture_flood_fill(color_obj, texture_obj, x_obj, y_obj, method_obj) ⇒ Object

Emulates Magick++‘s floodFillTexture.

If the FloodfillMethod method is specified, flood-fills texture across pixels starting at the target pixel and matching the specified color.

If the FillToBorderMethod method is specified, flood-fills ‘texture across pixels starting at the target pixel and stopping at pixels matching the specified color.’

Ruby usage:

- @verbatim Image#texture_flood_fill(color, texture, x, y, method) @endverbatim

Parameters:

  • self

    this object

  • color_obj

    the color

  • texture_obj

    the texture to fill

  • x_obj

    the x position

  • y_obj

    the y position

  • method_obj

    the method to call (FloodfillMethod or FillToBorderMethod)

Returns:

  • a new image



13293
13294
13295
13296
13297
13298
13299
13300
13301
13302
13303
13304
13305
13306
13307
13308
13309
13310
13311
13312
13313
13314
13315
13316
13317
13318
13319
13320
13321
13322
13323
13324
13325
13326
13327
13328
13329
13330
13331
13332
13333
13334
13335
13336
13337
13338
13339
13340
13341
13342
13343
13344
13345
13346
13347
13348
13349
13350
13351
13352
13353
13354
13355
13356
13357
13358
13359
13360
13361
13362
13363
# File 'ext/RMagick/rmimage.c', line 13293

VALUE
Image_texture_flood_fill(VALUE self, VALUE color_obj, VALUE texture_obj
                         , VALUE x_obj, VALUE y_obj, VALUE method_obj)
{
    Image *image, *new_image;
    Image *texture_image;
    PixelColor color;
    VALUE texture;
    DrawInfo *draw_info;
    long x, y;
    PaintMethod method;
    MagickPixel color_mpp;
    MagickBooleanType invert;

    image = rm_check_destroyed(self);

    Color_to_PixelColor(&color, color_obj);
    texture = rm_cur_image(texture_obj);
    texture_image = rm_check_destroyed(texture);

    x = NUM2LONG(x_obj);
    y = NUM2LONG(y_obj);

    if ((unsigned long)x > image->columns || (unsigned long)y > image->rows)
    {
        rb_raise(rb_eArgError, "target out of range. %ldx%ld given, image is %lux%lu"
                 , x, y, image->columns, image->rows);
    }

    VALUE_TO_ENUM(method_obj, method, PaintMethod);
    if (method != FillToBorderMethod && method != FloodfillMethod)
    {
        rb_raise(rb_eArgError, "paint method must be FloodfillMethod or "
                 "FillToBorderMethod (%d given)", (int)method);
    }

    draw_info = CloneDrawInfo(NULL, NULL);
    if (!draw_info)
    {
        rb_raise(rb_eNoMemError, "not enough memory to continue");
    }

    draw_info->fill_pattern = rm_clone_image(texture_image);
    new_image = rm_clone_image(image);


    rm_init_magickpixel(new_image, &color_mpp);
    if (method == FillToBorderMethod)
    {
        invert = MagickTrue;
        color_mpp.red   = (MagickRealType) image->border_color.red;
        color_mpp.green = (MagickRealType) image->border_color.green;
        color_mpp.blue  = (MagickRealType) image->border_color.blue;
    }
    else
    {
        invert = MagickFalse;
        color_mpp.red   = (MagickRealType) color.red;
        color_mpp.green = (MagickRealType) color.green;
        color_mpp.blue  = (MagickRealType) color.blue;
    }

    (void) FloodfillPaintImage(new_image, DefaultChannels, draw_info, &color_mpp, x, y, invert);

    (void) DestroyDrawInfo(draw_info);
    rm_check_image_exception(new_image, DestroyOnError);

    RB_GC_GUARD(texture);

    return rm_image_new(new_image);
}

#texture_floodfill(x, y, texture) ⇒ Object

Replace matching neighboring pixels with texture pixels



1004
1005
1006
1007
# File 'lib/rmagick_internal.rb', line 1004

def texture_floodfill(x, y, texture)
  target = pixel_color(x, y)
  texture_flood_fill(target, texture, x, y, FloodfillMethod)
end

#threshold(threshold_obj) ⇒ Object

Change the value of individual pixels based on the intensity of each pixel compared to threshold. The result is a high-contrast, two color image.

Ruby usage:

- @verbatim Image#threshold(threshold) @endverbatim

Parameters:

  • self

    this object

  • threshold

    the threshold

Returns:

  • a new image



13377
13378
13379
13380
13381
13382
13383
13384
13385
13386
13387
13388
13389
13390
# File 'ext/RMagick/rmimage.c', line 13377

VALUE
Image_threshold(VALUE self, VALUE threshold_obj)
{
    Image *image, *new_image;
    double threshold = NUM2DBL(threshold_obj);

    image = rm_check_destroyed(self);
    new_image = rm_clone_image(image);

    (void) BilevelImageChannel(new_image, DefaultChannels, threshold);
    rm_check_image_exception(new_image, DestroyOnError);

    return rm_image_new(new_image);
}

#thumbnail(*args) ⇒ Object

Fast resize for thumbnail images.

Ruby usage:

- @verbatim Image#thumbnail(scale) @endverbatim
- @verbatim Image#thumbnail(cols, rows) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:



13546
13547
13548
13549
13550
13551
# File 'ext/RMagick/rmimage.c', line 13546

VALUE
Image_thumbnail(int argc, VALUE *argv, VALUE self)
{
    (void) rm_check_destroyed(self);
    return thumbnail(False, argc, argv, self);
}

#thumbnail!(*args) ⇒ Object

Fast resize for thumbnail images.

Ruby usage:

- @verbatim Image#thumbnail!(scale) @endverbatim
- @verbatim Image#thumbnail!(cols, rows) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • self

See Also:



13568
13569
13570
13571
13572
13573
# File 'ext/RMagick/rmimage.c', line 13568

VALUE
Image_thumbnail_bang(int argc, VALUE *argv, VALUE self)
{
    (void) rm_check_frozen(self);
    return thumbnail(True, argc, argv, self);
}

#tint(*args) ⇒ Object

Call TintImage.

Ruby usage:

- @verbatim Image#tint(tint, red_alpha) @endverbatim
- @verbatim Image#tint(tint, red_alpha, green_alpha) @endverbatim
- @verbatim Image#tint(tint, red_alpha, green_alpha, blue_alpha) @endverbatim
- @verbatim Image#tint(tint, red_alpha, green_alpha, blue_alpha, alpha_alpha) @endverbatim

Notes:

- Default green_alpha is red_alpha
- Default blue_alpha is red_alpha
- Default alpha_alpha is 1.0
- Alpha values are percentages: 0.10 -> 10%.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



13632
13633
13634
13635
13636
13637
13638
13639
13640
13641
13642
13643
13644
13645
13646
13647
13648
13649
13650
13651
13652
13653
13654
13655
13656
13657
13658
13659
13660
13661
13662
13663
13664
13665
13666
13667
13668
13669
13670
13671
13672
13673
13674
13675
13676
13677
13678
13679
13680
13681
13682
13683
13684
13685
13686
13687
13688
13689
13690
13691
13692
# File 'ext/RMagick/rmimage.c', line 13632

VALUE
Image_tint(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    PixelColor tint;
    double red_pct_opaque, green_pct_opaque, blue_pct_opaque;
    double alpha_pct_opaque = 1.0;
    char alpha[50];
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    switch (argc)
    {
        case 2:
            red_pct_opaque   = NUM2DBL(argv[1]);
            green_pct_opaque = blue_pct_opaque = red_pct_opaque;
            break;
        case 3:
            red_pct_opaque   = NUM2DBL(argv[1]);
            green_pct_opaque = NUM2DBL(argv[2]);
            blue_pct_opaque  = red_pct_opaque;
            break;
        case 4:
            red_pct_opaque     = NUM2DBL(argv[1]);
            green_pct_opaque   = NUM2DBL(argv[2]);
            blue_pct_opaque    = NUM2DBL(argv[3]);
            break;
        case 5:
            red_pct_opaque     = NUM2DBL(argv[1]);
            green_pct_opaque   = NUM2DBL(argv[2]);
            blue_pct_opaque    = NUM2DBL(argv[3]);
            alpha_pct_opaque   = NUM2DBL(argv[4]);
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 to 5)", argc);
            break;
    }

    if (red_pct_opaque < 0.0 || green_pct_opaque < 0.0
        || blue_pct_opaque < 0.0 || alpha_pct_opaque < 0.0)
    {
        rb_raise(rb_eArgError, "alpha percentages must be non-negative.");
    }

    snprintf(alpha, sizeof(alpha),
            "%g,%g,%g,%g", red_pct_opaque*100.0, green_pct_opaque*100.0
            , blue_pct_opaque*100.0, alpha_pct_opaque*100.0);

    Color_to_PixelColor(&tint, argv[0]);
    exception = AcquireExceptionInfo();

    new_image = TintImage(image, alpha, tint, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#to_blobObject

Return a “blob” (a String) from the image.

Ruby usage:

- @verbatim Image#to_blob @endverbatim

Notes:

- The magick member of the Image structure determines the format of the
  returned blob (GIG, JPEG,  PNG, etc.)

Parameters:

  • self

    this object

Returns:

  • the blob



13708
13709
13710
13711
13712
13713
13714
13715
13716
13717
13718
13719
13720
13721
13722
13723
13724
13725
13726
13727
13728
13729
13730
13731
13732
13733
13734
13735
13736
13737
13738
13739
13740
13741
13742
13743
13744
13745
13746
13747
13748
13749
13750
13751
13752
13753
13754
13755
13756
13757
13758
13759
13760
13761
13762
13763
13764
13765
13766
13767
13768
13769
13770
13771
13772
13773
13774
13775
13776
13777
13778
13779
13780
13781
13782
13783
# File 'ext/RMagick/rmimage.c', line 13708

VALUE
Image_to_blob(VALUE self)
{
    Image *image;
    Info *info;
    const MagickInfo *magick_info;
    VALUE info_obj;
    VALUE blob_str;
    void *blob = NULL;
    size_t length = 2048;       // Do what Magick++ does
    ExceptionInfo *exception;

    // The user can specify the depth (8 or 16, if the format supports
    // both) and the image format by setting the depth and format
    // values in the info parm block.
    info_obj = rm_info_new();
    Data_Get_Struct(info_obj, Info, info);

    image = rm_check_destroyed(self);

    // Copy the depth and magick fields to the Image
    if (info->depth != 0)
    {
        (void) SetImageDepth(image, info->depth);
        rm_check_image_exception(image, RetainOnError);
    }

    exception = AcquireExceptionInfo();
    if (*info->magick)
    {
        (void) SetImageInfo(info, MagickTrue, exception);
        CHECK_EXCEPTION()

        if (*info->magick == '\0')
        {
            return Qnil;
        }
        strncpy(image->magick, info->magick, sizeof(info->magick)-1);
    }

    // Fix #2844 - libjpeg exits when image is 0x0
    magick_info = GetMagickInfo(image->magick, exception);
    CHECK_EXCEPTION()

    if (magick_info)
    {
        if (  (!rm_strcasecmp(magick_info->name, "JPEG")
               || !rm_strcasecmp(magick_info->name, "JPG"))
              && (image->rows == 0 || image->columns == 0))
        {
            rb_raise(rb_eRuntimeError, "Can't convert %lux%lu %.4s image to a blob"
                     , image->columns, image->rows, magick_info->name);
        }
    }

    rm_sync_image_options(image, info);

    blob = ImageToBlob(info, image, &length, exception);
    CHECK_EXCEPTION()

    (void) DestroyExceptionInfo(exception);

    if (length == 0 || !blob)
    {
        return Qnil;
    }

    blob_str = rb_str_new(blob, length);

    magick_free((void*)blob);

    RB_GC_GUARD(info_obj);
    RB_GC_GUARD(blob_str);

    return blob_str;
}

#to_color(pixel_arg) ⇒ Object

Return a color name for the color intensity specified by the Magick::Pixel argument.

Ruby usage:

- @verbatim Image#to_color(pixel) @endverbatim

Notes:

- Respects depth and matte attributes

Parameters:

  • self

    this object

  • pixel_arg

    the pixel

Returns:

  • the color name



13800
13801
13802
13803
13804
13805
13806
13807
13808
13809
13810
13811
13812
13813
13814
13815
13816
13817
13818
13819
13820
13821
13822
13823
# File 'ext/RMagick/rmimage.c', line 13800

VALUE
Image_to_color(VALUE self, VALUE pixel_arg)
{
    Image *image;
    PixelColor pixel;
    ExceptionInfo *exception;
    char name[MaxTextExtent];

    image = rm_check_destroyed(self);
    Color_to_PixelColor(&pixel, pixel_arg);
    exception = AcquireExceptionInfo();

    // QueryColorname returns False if the color represented by the PixelPacket
    // doesn't have a "real" name, just a sequence of hex digits. We don't care
    // about that.

    (void) QueryColorname(image, &pixel, AllCompliance, name, exception);
    CHECK_EXCEPTION()

    (void) DestroyExceptionInfo(exception);

    return rb_str_new2(name);

}

#transparent(*args) ⇒ Object

Call TransparentPaintImage.

Ruby usage:

- @verbatim Image#transparent(color-name) @endverbatim
- @verbatim Image#transparent(color-name, alpha: alpha) @endverbatim
- @verbatim Image#transparent(pixel) @endverbatim
- @verbatim Image#transparent(pixel, alpha: alpha) @endverbatim

Notes:

- Default alpha is Magick::TransparentAlpha.
- Can use Magick::OpaqueAlpha or Magick::TransparentAlpha, or any
  value >= 0 && <= QuantumRange.
- Use Image#fuzz= to define the tolerance level.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



13892
13893
13894
13895
13896
13897
13898
13899
13900
13901
13902
13903
13904
13905
13906
13907
13908
13909
13910
13911
13912
13913
13914
13915
13916
13917
13918
13919
13920
13921
13922
13923
13924
13925
13926
# File 'ext/RMagick/rmimage.c', line 13892

VALUE
Image_transparent(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    MagickPixel color;
    Quantum alpha = TransparentAlpha;
    MagickBooleanType okay;

    image = rm_check_destroyed(self);

    switch (argc)
    {
        case 2:
            alpha = get_named_alpha_value(argv[1]);
        case 1:
            Color_to_MagickPixel(image, &color, argv[0]);
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
            break;
    }

    new_image = rm_clone_image(image);

    okay = TransparentPaintImage(new_image, &color, QuantumRange - alpha, MagickFalse);
    rm_check_image_exception(new_image, DestroyOnError);
    if (!okay)
    {
        // Force exception
        DestroyImage(new_image);
        rm_magick_error("TransparentPaintImage failed with no explanation");
    }

    return rm_image_new(new_image);
}

#transparent_chroma(*args) ⇒ Object

Call TransparentPaintImageChroma.

Ruby usage:

- @verbatim Image#transparent_chroma(low, high) @endverbatim
- @verbatim Image#transparent_chroma(low, high, alpha: alpha) @endverbatim
- @verbatim Image#transparent_chroma(low, high, invert, alpha: alpha) @endverbatim

Notes:

- Default alpha is TransparentAlpha
- Default invert is false
- Available in ImageMagick >= 6.4.5-6

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



13947
13948
13949
13950
13951
13952
13953
13954
13955
13956
13957
13958
13959
13960
13961
13962
13963
13964
13965
13966
13967
13968
13969
13970
13971
13972
13973
13974
13975
13976
13977
13978
13979
13980
13981
13982
13983
13984
13985
13986
13987
13988
13989
13990
13991
13992
13993
13994
13995
13996
13997
13998
13999
# File 'ext/RMagick/rmimage.c', line 13947

VALUE
Image_transparent_chroma(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    Quantum alpha = TransparentAlpha;
    MagickPixel low, high;
    MagickBooleanType invert = MagickFalse;
    MagickBooleanType okay;

    image = rm_check_destroyed(self);

    switch (argc)
    {
        case 4:
            if (TYPE(argv[argc - 1]) == T_HASH)
            {
                invert = RTEST(argv[3]);
            }
            else
            {
                invert = RTEST(argv[2]);
            }
        case 3:
            if (TYPE(argv[argc - 1]) == T_HASH)
            {
                alpha = get_alpha_from_hash(argv[argc - 1]);
            }
            else
            {
                alpha = get_alpha_from_opacity(argv[2]);
            }
        case 2:
            Color_to_MagickPixel(image, &high, argv[1]);
            Color_to_MagickPixel(image, &low, argv[0]);
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 2, 3 or 4)", argc);
            break;
    }

    new_image = rm_clone_image(image);

    okay = TransparentPaintImageChroma(new_image, &low, &high, QuantumRange - alpha, invert);
    rm_check_image_exception(new_image, DestroyOnError);
    if (!okay)
    {
        // Force exception
        DestroyImage(new_image);
        rm_magick_error("TransparentPaintImageChroma failed with no explanation");
    }

    return rm_image_new(new_image);
}

#transposeObject

Call TransposeImage.

Ruby usage:

- @verbatim Image#transpose @endverbatim

Parameters:

  • self

    this object

Returns:

  • a new image

See Also:

  • crisscross
  • Image_transpose_bang


14049
14050
14051
14052
14053
14054
# File 'ext/RMagick/rmimage.c', line 14049

VALUE
Image_transpose(VALUE self)
{
    (void) rm_check_destroyed(self);
    return crisscross(False, self, TransposeImage);
}

#transpose!Object

Call TransposeImage.

Ruby usage:

- @verbatim Image#transpose! @endverbatim

Parameters:

  • self

    this object

Returns:

  • self

See Also:

  • crisscross
  • Image_transpose


14068
14069
14070
14071
14072
14073
# File 'ext/RMagick/rmimage.c', line 14068

VALUE
Image_transpose_bang(VALUE self)
{
    (void) rm_check_frozen(self);
    return crisscross(True, self, TransposeImage);
}

#transverseObject

Call TransverseImage.

Ruby usage:

- @verbatim Image#transverse @endverbatim

Parameters:

  • self

    this object

Returns:

  • a new image

See Also:

  • crisscross
  • Image_transverse_bang


14087
14088
14089
14090
14091
14092
# File 'ext/RMagick/rmimage.c', line 14087

VALUE
Image_transverse(VALUE self)
{
    (void) rm_check_destroyed(self);
    return crisscross(False, self, TransverseImage);
}

#transverse!Object

Call TransverseImage.

Ruby usage:

- @verbatim Image#transverse! @endverbatim

Parameters:

  • self

    this object

Returns:

  • self

See Also:

  • crisscross
  • Image_transverse_bang


14105
14106
14107
14108
14109
14110
# File 'ext/RMagick/rmimage.c', line 14105

VALUE
Image_transverse_bang(VALUE self)
{
    (void) rm_check_frozen(self);
    return crisscross(True, self, TransverseImage);
}

#trim(*args) ⇒ Object

Convenient front-end to CropImage.

Ruby usage:

- @verbatim Image#trim @endverbatim
- @verbatim Image#trim(reset_page) @endverbatim

Notes:

- Default reset_page is false
- Respects fuzz attribute.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:

  • trimmer
  • Image_trim_bang


14191
14192
14193
14194
14195
14196
# File 'ext/RMagick/rmimage.c', line 14191

VALUE
Image_trim(int argc, VALUE *argv, VALUE self)
{
    (void) rm_check_destroyed(self);
    return trimmer(False, argc, argv, self);
}

#trim!(*args) ⇒ Object

Convenient front-end to CropImage.

Ruby usage:

- @verbatim Image#trim! @endverbatim
- @verbatim Image#trim!(reset_page) @endverbatim

Notes:

- Default reset_page is false
- Respects fuzz attribute.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • self

See Also:

  • trimmer
  • Image_trim


14217
14218
14219
14220
14221
14222
# File 'ext/RMagick/rmimage.c', line 14217

VALUE
Image_trim_bang(int argc, VALUE *argv, VALUE self)
{
    (void) rm_check_frozen(self);
    return trimmer(True, argc, argv, self);
}

#undefine(artifact) ⇒ Object

Call RemoveImageArtifact.

Ruby usage:

- @verbatim Image#undefine(artifact) @endverbatim

Notes:

- Normally a script should never call this method.

Parameters:

  • self

    this object

  • artifact

    the artifact

Returns:

  • self

See Also:

  • Image_define


14321
14322
14323
14324
14325
14326
14327
14328
14329
14330
14331
14332
# File 'ext/RMagick/rmimage.c', line 14321

VALUE
Image_undefine(VALUE self, VALUE artifact)
{
    Image *image;
    char *key;
    long key_l;

    image = rm_check_frozen(self);
    key = rm_str2cstr(artifact, &key_l);
    (void) DeleteImageArtifact(image, key);
    return self;
}

#unique_colorsObject

Call UniqueImageColors.

Ruby usage:

- @verbatim Image#unique_colors @endverbatim

Parameters:

  • self

    this object

Returns:

  • a new image



14344
14345
14346
14347
14348
14349
14350
14351
14352
14353
14354
14355
14356
14357
14358
14359
14360
# File 'ext/RMagick/rmimage.c', line 14344

VALUE
Image_unique_colors(VALUE self)
{
    Image *image, *new_image;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    exception = AcquireExceptionInfo();

    new_image = UniqueImageColors(image, exception);
    rm_check_exception(exception, new_image, DestroyOnError);
    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#unsharp_mask(*args) ⇒ Object

Sharpen an image. “amount” is the percentage of the difference between the original and the blur image that is added back into the original. “threshold” is the threshold in pixels needed to apply the diffence amount.

Ruby usage:

- @verbatim Image#unsharp_mask @endverbatim
- @verbatim Image#unsharp_mask(radius) @endverbatim
- @verbatim Image#unsharp_mask(radius, sigma) @endverbatim
- @verbatim Image#unsharp_mask(radius, sigma, amount) @endverbatim
- @verbatim Image#unsharp_mask(radius, sigma, amount, threshold) @endverbatim

Notes:

- Default radius is 0.0
- Default sigma is 1.0
- Default amount is 1.0
- Default threshold is 0.05

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:

  • unsharp_mask_args


14512
14513
14514
14515
14516
14517
14518
14519
14520
14521
14522
14523
14524
14525
14526
14527
14528
14529
14530
14531
14532
# File 'ext/RMagick/rmimage.c', line 14512

VALUE
Image_unsharp_mask(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    double radius = 0.0, sigma = 1.0, amount = 1.0, threshold = 0.05;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    unsharp_mask_args(argc, argv, &radius, &sigma, &amount, &threshold);

    exception = AcquireExceptionInfo();
    new_image = UnsharpMaskImage(image, radius, sigma, amount, threshold, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#unsharp_mask_channel(*args) ⇒ Object

Call UnsharpMaskImageChannel.

Ruby usage:

- @verbatim Image#unsharp_mask @endverbatim
- @verbatim Image#unsharp_mask(radius) @endverbatim
- @verbatim Image#unsharp_mask(radius, sigma) @endverbatim
- @verbatim Image#unsharp_mask(radius, sigma, amount) @endverbatim
- @verbatim Image#unsharp_mask(radius, sigma, amount, threshold) @endverbatim
- @verbatim Image#unsharp_mask(radius, sigma, amount, threshold, channel) @endverbatim
- @verbatim Image#unsharp_mask(radius, sigma, amount, threshold, channel, ...) @endverbatim

Notes:

- Default radius is 0.0
- Default sigma is 1.0
- Default amount is 1.0
- Default threshold is 0.05
- Default channel is AllChannels

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:

  • unsharp_mask_args


14560
14561
14562
14563
14564
14565
14566
14567
14568
14569
14570
14571
14572
14573
14574
14575
14576
14577
14578
14579
14580
14581
14582
14583
14584
14585
14586
# File 'ext/RMagick/rmimage.c', line 14560

VALUE
Image_unsharp_mask_channel(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    ChannelType channels;
    double radius = 0.0, sigma = 1.0, amount = 1.0, threshold = 0.05;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    channels = extract_channels(&argc, argv);
    if (argc > 4)
    {
        raise_ChannelType_error(argv[argc-1]);
    }

    unsharp_mask_args(argc, argv, &radius, &sigma, &amount, &threshold);

    exception = AcquireExceptionInfo();
    new_image = UnsharpMaskImageChannel(image, channels, radius, sigma, amount, threshold, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#view(x, y, width, height) ⇒ Object

Construct a view. If a block is present, yield and pass the view object, otherwise return the view object.



1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
# File 'lib/rmagick_internal.rb', line 1016

def view(x, y, width, height)
  view = View.new(self, x, y, width, height)

  return view unless block_given?

  begin
    yield(view)
  ensure
    view.sync
  end
  nil
end

#vignette(*args) ⇒ Object

Soften the edges of an image.

Ruby usage:

- @verbatim Image#vignette @endverbatim
- @verbatim Image#vignette(horz_radius) @endverbatim
- @verbatim Image#vignette(horz_radius, vert_radius) @endverbatim
- @verbatim Image#vignette(horz_radius, vert_radius, radius) @endverbatim
- @verbatim Image#vignette(horz_radius, vert_radius, radius, sigma) @endverbatim

Notes:

- Default horz_radius is image-columns*0.1+0.5
- Default vert_radius is image-rows*0.1+0.5
- Default radius is 0.0
- Default sigma is 1.0
- The outer edges of the image are replaced by the background color.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



14611
14612
14613
14614
14615
14616
14617
14618
14619
14620
14621
14622
14623
14624
14625
14626
14627
14628
14629
14630
14631
14632
14633
14634
14635
14636
14637
14638
14639
14640
14641
14642
14643
14644
14645
14646
14647
14648
14649
14650
14651
# File 'ext/RMagick/rmimage.c', line 14611

VALUE
Image_vignette(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    long horz_radius, vert_radius;
    double radius = 0.0, sigma = 10.0;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);

    horz_radius = (long)(image->columns * 0.10 + 0.5);
    vert_radius = (long)(image->rows * 0.10 + 0.5);

    switch (argc)
    {
        case 4:
            sigma = NUM2DBL(argv[3]);
        case 3:
            radius = NUM2DBL(argv[2]);
        case 2:
            vert_radius = NUM2INT(argv[1]);
        case 1:
            horz_radius = NUM2INT(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 4)", argc);
            break;
    }

    exception = AcquireExceptionInfo();

    new_image = VignetteImage(image, radius, sigma, horz_radius, vert_radius, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#watermark(*args) ⇒ Object

Add a watermark to an image.

Ruby usage:

- @verbatim Image#watermark(mark) @endverbatim
- @verbatim Image#watermark(mark, brightness) @endverbatim
- @verbatim Image#watermark(mark, brightness, saturation) @endverbatim
- @verbatim Image#watermark(mark, brightness, saturation, gravity) @endverbatim
- @verbatim Image#watermark(mark, brightness, saturation, gravity, x_off) @endverbatim
- @verbatim Image#watermark(mark, brightness, saturation, gravity, x_off, y_off) @endverbatim
- @verbatim Image#watermark(mark, brightness, saturation, x_off) @endverbatim
- @verbatim Image#watermark(mark, brightness, saturation, x_off, y_off) @endverbatim

Notes:

- Default brightness is 100%
- Default saturation is 100%
- Default x_off is 0
- Default y_off is 0
- x_off and y_off can be negative, which means measure from the
  right/bottom of the target image.


14721
14722
14723
14724
14725
14726
14727
14728
14729
14730
14731
14732
14733
14734
14735
14736
14737
14738
14739
14740
14741
14742
14743
14744
14745
14746
14747
14748
14749
14750
14751
14752
14753
14754
14755
14756
14757
14758
14759
14760
14761
14762
14763
14764
14765
14766
14767
14768
14769
14770
14771
14772
# File 'ext/RMagick/rmimage.c', line 14721

VALUE
Image_watermark(int argc, VALUE *argv, VALUE self)
{
    Image *image, *overlay, *new_image;
    double src_percent = 100.0, dst_percent = 100.0;
    long x_offset = 0L, y_offset = 0L;
    char geometry[20];
    VALUE ovly;

    image = rm_check_destroyed(self);

    if (argc < 1)
    {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 to 6)", argc);
    }

    ovly = rm_cur_image(argv[0]);
    overlay = rm_check_destroyed(ovly);

    if (argc > 3)
    {
        get_composite_offsets(argc-3, &argv[3], image, overlay, &x_offset, &y_offset);
        // There must be 3 arguments left
        argc = 3;
    }

    switch (argc)
    {
        case 3:
            dst_percent = rm_percentage(argv[2],1.0) * 100.0;
        case 2:
            src_percent = rm_percentage(argv[1],1.0) * 100.0;
        case 1:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 to 6)", argc);
            break;
    }

    blend_geometry(geometry, sizeof(geometry), src_percent, dst_percent);
    (void) CloneString(&overlay->geometry, geometry);
    (void) SetImageArtifact(overlay,"compose:args", geometry);

    new_image = rm_clone_image(image);
    (void) CompositeImage(new_image, ModulateCompositeOp, overlay, x_offset, y_offset);

    rm_check_image_exception(new_image, DestroyOnError);

    RB_GC_GUARD(ovly);

    return rm_image_new(new_image);
}

#wave(*args) ⇒ Object

Create a “ripple” effect in the image by shifting the pixels vertically along a sine wave whose amplitude and wavelength is specified by the given parameters.

Ruby usage:

- @verbatim Image#wave @endverbatim
- @verbatim Image#wave(amplitude) @endverbatim
- @verbatim Image#wave(amplitude, wavelength) @endverbatim

Notes:

- Default amplitude is 25.0
- Default wavelength is 150.0

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image



14794
14795
14796
14797
14798
14799
14800
14801
14802
14803
14804
14805
14806
14807
14808
14809
14810
14811
14812
14813
14814
14815
14816
14817
14818
14819
14820
14821
14822
14823
14824
# File 'ext/RMagick/rmimage.c', line 14794

VALUE
Image_wave(int argc, VALUE *argv, VALUE self)
{
    Image *image, *new_image;
    double amplitude = 25.0, wavelength = 150.0;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    switch (argc)
    {
        case 2:
            wavelength = NUM2DBL(argv[1]);
        case 1:
            amplitude = NUM2DBL(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 2)", argc);
            break;
    }

    exception = AcquireExceptionInfo();
    new_image = WaveImage(image, amplitude, wavelength, exception);
    rm_check_exception(exception, new_image, DestroyOnError);

    (void) DestroyExceptionInfo(exception);

    rm_ensure_result(new_image);

    return rm_image_new(new_image);
}

#wet_floor(*args) ⇒ Object

Construct a “wet floor” reflection.

Ruby usage:

- @verbatim Image#wet_floor @endverbatim
- @verbatim Image#wet_floor(initial) @endverbatim
- @verbatim Image#wet_floor(initial, rate) @endverbatim

Notes:

- Default initial is 0.5
- Default rate is 1.0
- `initial' is a number between 0 and 1, inclusive, that represents the
  initial level of transparency. Smaller numbers are less transparent than
  larger numbers. 0 is fully opaque. 1.0 is fully transparent.
- `rate' is the rate at which the initial level of transparency changes to
  complete transparency. Larger values cause the change to occur more
  rapidly. The resulting reflection will be shorter. Smaller values cause
  the change to occur less rapidly. The resulting reflection will be
  taller. If the rate is exactly 0 then the amount of transparency doesn't
  change at all.

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:



14854
14855
14856
14857
14858
14859
14860
14861
14862
14863
14864
14865
14866
14867
14868
14869
14870
14871
14872
14873
14874
14875
14876
14877
14878
14879
14880
14881
14882
14883
14884
14885
14886
14887
14888
14889
14890
14891
14892
14893
14894
14895
14896
14897
14898
14899
14900
14901
14902
14903
14904
14905
14906
14907
14908
14909
14910
14911
14912
14913
14914
14915
14916
14917
14918
14919
14920
14921
14922
14923
14924
14925
14926
14927
14928
14929
14930
14931
14932
14933
14934
14935
14936
14937
14938
14939
14940
14941
14942
14943
14944
14945
14946
14947
14948
14949
14950
14951
14952
14953
14954
14955
14956
14957
14958
14959
14960
14961
14962
14963
14964
14965
14966
14967
14968
14969
14970
14971
14972
14973
14974
14975
14976
14977
# File 'ext/RMagick/rmimage.c', line 14854

VALUE
Image_wet_floor(int argc, VALUE *argv, VALUE self)
{
    Image *image, *reflection, *flip_image;
    const PixelPacket *p;
    PixelPacket *q;
    RectangleInfo geometry;
    long x, y, max_rows;
    double initial = 0.5;
    double rate = 1.0;
    double opacity, step;
    const char *func;
    ExceptionInfo *exception;

    image = rm_check_destroyed(self);
    switch (argc)
    {
        case 2:
            rate = NUM2DBL(argv[1]);
        case 1:
            initial = NUM2DBL(argv[0]);
        case 0:
            break;
        default:
            rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 to 2)", argc);
            break;
    }


    if (initial < 0.0 || initial > 1.0)
    {
        rb_raise(rb_eArgError, "Initial transparency must be in the range 0.0-1.0 (%g)", initial);
    }
    if (rate < 0.0)
    {
        rb_raise(rb_eArgError, "Transparency change rate must be >= 0.0 (%g)", rate);
    }

    initial *= TransparentOpacity;

    // The number of rows in which to transition from the initial level of
    // transparency to complete transparency. rate == 0.0 -> no change.
    if (rate > 0.0)
    {
        max_rows = (long)((double)image->rows) / (3.0 * rate);
        max_rows = (long)min((unsigned long)max_rows, image->rows);
        step =  (TransparentOpacity - initial) / max_rows;
    }
    else
    {
        max_rows = (long)image->rows;
        step = 0.0;
    }


    exception = AcquireExceptionInfo();
    flip_image = FlipImage(image, exception);
    CHECK_EXCEPTION();


    geometry.x = 0;
    geometry.y = 0;
    geometry.width = image->columns;
    geometry.height = max_rows;
    reflection = CropImage(flip_image, &geometry, exception);
    DestroyImage(flip_image);
    CHECK_EXCEPTION();


    (void) SetImageStorageClass(reflection, DirectClass);
    rm_check_image_exception(reflection, DestroyOnError);


    reflection->matte = MagickTrue;
    opacity = initial;

    for (y = 0; y < max_rows; y++)
    {
        if (opacity > TransparentOpacity)
        {
            opacity = TransparentOpacity;
        }

        p = GetVirtualPixels(reflection, 0, y, image->columns, 1, exception);
        rm_check_exception(exception, reflection, DestroyOnError);
        if (!p)
        {
            func = "AcquireImagePixels";
            goto error;
        }

        q = QueueAuthenticPixels(reflection, 0, y, image->columns, 1, exception);

        rm_check_exception(exception, reflection, DestroyOnError);
        if (!q)
        {
            func = "SetImagePixels";
            goto error;
        }

        for (x = 0; x < (long) image->columns; x++)
        {
            q[x] = p[x];
            // Never make a pixel *less* transparent than it already is.
            q[x].opacity = max(q[x].opacity, (Quantum)opacity);
        }


        SyncAuthenticPixels(reflection, exception);
        rm_check_exception(exception, reflection, DestroyOnError);

        opacity += step;
    }


    (void) DestroyExceptionInfo(exception);
    return rm_image_new(reflection);

    error:
    (void) DestroyExceptionInfo(exception);
    (void) DestroyImage(reflection);
    rb_raise(rb_eRuntimeError, "%s failed on row %lu", func, y);
    return(VALUE)0;
}

#white_threshold(*args) ⇒ Object

Call WhiteThresholdImage.

Ruby usage:

- @verbatim Image#white_threshold(red) @endverbatim
- @verbatim Image#white_threshold(red, green) @endverbatim
- @verbatim Image#white_threshold(red, green, blue) @endverbatim
- @verbatim Image#white_threshold(red, green, blue, alpha: alpha) @endverbatim

Parameters:

  • argc

    number of input arguments

  • argv

    array of input arguments

  • self

    this object

Returns:

  • a new image

See Also:

  • threshold_image
  • Image_black_threshold


14996
14997
14998
14999
15000
# File 'ext/RMagick/rmimage.c', line 14996

VALUE
Image_white_threshold(int argc, VALUE *argv, VALUE self)
{
    return threshold_image(argc, argv, self, WhiteThresholdImage);
}

#write(file) ⇒ Object

Write the image to the file.

Ruby usage:

- @verbatim Image#write(filename) @endverbatim

Parameters:

  • self

    this object

  • file

    the filename

Returns:

  • self



15103
15104
15105
15106
15107
15108
15109
15110
15111
15112
15113
15114
15115
15116
15117
15118
15119
15120
15121
15122
15123
15124
15125
15126
15127
15128
15129
15130
15131
15132
15133
15134
15135
15136
15137
15138
15139
15140
15141
15142
15143
15144
15145
15146
15147
# File 'ext/RMagick/rmimage.c', line 15103

VALUE
Image_write(VALUE self, VALUE file)
{
    Image *image;
    Info *info;
    VALUE info_obj;

    image = rm_check_destroyed(self);

    info_obj = rm_info_new();
    Data_Get_Struct(info_obj, Info, info);

    if (TYPE(file) == T_FILE)
    {
        rb_io_t *fptr;

        // Ensure file is open - raise error if not
        GetOpenFile(file, fptr);
        rb_io_check_writable(fptr);
#if defined(_WIN32)
        add_format_prefix(info, fptr->pathv);
        strcpy(image->filename, info->filename);
        SetImageInfoFile(info, NULL);
#else
        SetImageInfoFile(info, rb_io_stdio_file(fptr));
        memset(image->filename, 0, sizeof(image->filename));
#endif
    }
    else
    {
        add_format_prefix(info, file);
        strcpy(image->filename, info->filename);
        SetImageInfoFile(info, NULL);
    }

    rm_sync_image_options(image, info);

    info->adjoin = MagickFalse;
    (void) WriteImage(info, image);
    rm_check_image_exception(image, RetainOnError);

    RB_GC_GUARD(info_obj);

    return self;
}