rubyimagemagickimagemagick-convertrmagick

Remove all greyscale from image using QuickMagick


I want to remove all grey from an image using QuickMagick or RMagic in Ruby. I found this solution here: https://www.imagemagick.org/discourse-server/viewtopic.php?t=36051 for ImageMagick but I don't know how to convert the syntax properly to QuickMagick

convert in.jpg \( +clone -colorspace HCL -channel G -separate +channel -threshold 15% \) -alpha off -compose CopyOpacity -composite out.png

Edit: I tried by @8bithero

        image = QuickMagick::Image.read(remote_image.path).first

        # Clone the image and perform operations
        clone = image.clone
        clone.colorspace = 'HCL'
        clone.channel('G').separate
        clone.threshold(15)

        # Composite the original and the clone
        # image.alpha('off')
        image.compose = 'CopyOpacity'
        image = image.composite(clone, 0, 0, 'CopyOpacity')

        # Save the output
        image.save(outfile)

but I got an error

 QuickMagick::QuickMagickError (          Error executing command: command
15:45:49 web.1  |           Result is:
15:45:49 web.1  |           Error is: convert: unable to open image '#<QuickMagick::Image:0x000000010d0fe0c0> 0 0 CopyOpacity': No such file or directory @ error/blob.c/OpenBlob/3572.
15:45:49 web.1  | convert: no decode delegate for this image format `' @ error/constitute.c/ReadImage/746.
15:45:49 web.1  | convert: image sequence is required `-composite' @ error/mogrify.c/MogrifyImageList/8049.
15:45:49 web.1  | convert: no images defined `c8cfa655-8437-4ea6-8c34-e60f88fffe8b-1.png' @ error/convert.c/ConvertImageCommand/3362.
15:45:49 web.1  |
15:45:49 web.1  | ):

Solution

  • To get it to work you'd need to translate the command-line syntax into QuickMagick's Ruby-based syntax.

    Haven't tested this so not sure if it will work, but hopfully it will set you on the right track

    require 'quick_magick'
    
    # Load the image
    image = QuickMagick::Image.read(remote_image.path).first
    
    # Clone the image and perform operations
    clone = image.clone
    clone.colorspace = 'HCL'
    clone.channel('G').separate
    clone.threshold(15)
    
    # Composite the original and the clone
    image.alpha('off')
    image.compose = 'CopyOpacity'
    image = image.composite(clone, 0, 0, 'CopyOpacity')
    
    # Save the output
    image.save(outfile)
    

    Make sure to change remote_image.path to the path to your input image and output with the output path.

    UPDATE: The error you encountered suggests there's an issue in how the image objects are being passed and recognised within the QuickMagick framework. This could be due to differences in API calls or how image manipulation commands are structured in the latest versions. I assume RMagick is installed (gem install rmagick) and that ImageMagick is also installed and properly configured on your system and that you are using the latest versions. With that in mind, here's an updated version:

    require 'rmagick'
    
    # Load the image
    image = Magick::Image.read(remote_image.path).first
    
    # Clone the image and convert to HCL colorspace
    clone = image.clone
    clone.colorspace = Magick::HCLColorspace
    
    # Separate the green channel and apply threshold
    clone = clone.separate(Magick::GreenChannel).first
    threshold_image = clone.threshold(Magick::QuantumRange * 0.15)
    
    # Apply the threshold image as an opacity mask
    image.matte = false # Disable alpha channel
    image = image.composite(threshold_image, Magick::CenterGravity, Magick::CopyOpacityCompositeOp)
    
    # Save the output
    image.write(outfile)
    

    APPROACH 2: If the above suggestion also fails, you could just executing the ImageMagick command directly from Ruby by doing something like this:

    require 'open3'
    
    input_path = remote_image.path
    output_path = outfile
    command = "convert #{input_path.shellescape} \\( +clone -colorspace HCL -channel G -separate +channel -threshold 15% \\) -alpha off -compose CopyOpacity -composite #{output_path.shellescape}"
    
    Open3.popen3(command) do |stdin, stdout, stderr, wait_thr|
      exit_status = wait_thr.value
      unless exit_status.success?
        raise "ImageMagick command failed: #{stderr.read}"
      end
    end