Method: Magick::Image#pixel_color

Defined in:
ext/RMagick/rmimage.c

#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

[View source]

9765
9766
9767
9768
9769
9770
9771
9772
9773
9774
9775
9776
9777
9778
9779
9780
9781
9782
9783
9784
9785
9786
9787
9788
9789
9790
9791
9792
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
9842
9843
9844
9845
9846
9847
9848
9849
9850
9851
9852
9853
9854
9855
9856
9857
9858
9859
9860
9861
9862
9863
9864
9865
9866
9867
9868
9869
9870
9871
9872
9873
9874
9875
9876
9877
9878
9879
9880
9881
9882
# File 'ext/RMagick/rmimage.c', line 9765

VALUE
Image_pixel_color(int argc, VALUE *argv, VALUE self)
{
    Image *image;
    PixelPacket old_color, new_color, *pixel;
    ExceptionInfo exception;
    long x, y;
    unsigned int set = False;
    MagickBooleanType okay;

    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_PixelPacket(&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)
    {
        GetExceptionInfo(&exception);
#if defined(HAVE_GETVIRTUALPIXELS)
        old_color = *GetVirtualPixels(image, x, y, 1, 1, &exception);
#else
        old_color = *AcquireImagePixels(image, x, y, 1, 1, &exception);
#endif
        CHECK_EXCEPTION()

        (void) DestroyExceptionInfo(&exception);

        // PseudoClass
        if (image->storage_class == PseudoClass)
        {
#if defined(HAVE_GETAUTHENTICINDEXQUEUE)
            IndexPacket *indexes = GetAuthenticIndexQueue(image);
#else
            IndexPacket *indexes = GetIndexes(image);
#endif
            old_color = image->colormap[*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_PixelPacket(&image->background_color);
    }

    // Set the color of a pixel. Return previous color.
    // Convert to DirectClass
    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.");
        }
    }


#if defined(HAVE_GETAUTHENTICPIXELS) || defined(HAVE_SYNCAUTHENTICPIXELS)
    GetExceptionInfo(&exception);
#endif

#if defined(HAVE_GETAUTHENTICPIXELS)
    pixel = GetAuthenticPixels(image, x, y, 1, 1, &exception);
    CHECK_EXCEPTION()
#else
    pixel = GetImagePixels(image, x, y, 1, 1);
    rm_check_image_exception(image, RetainOnError);
#endif

    if (pixel)
    {
        old_color = *pixel;
        if (!image->matte)
        {
            old_color.opacity = OpaqueOpacity;
        }
    }
    *pixel = new_color;

#if defined(HAVE_SYNCAUTHENTICPIXELS)
    SyncAuthenticPixels(image, &exception);
    CHECK_EXCEPTION()
#else
    SyncImagePixels(image);
    rm_check_image_exception(image, RetainOnError);
#endif

#if defined(HAVE_GETAUTHENTICPIXELS) || defined(HAVE_SYNCAUTHENTICPIXELS)
    (void) DestroyExceptionInfo(&exception);
#endif

    return Pixel_from_PixelPacket(&old_color);
}