Remove all greyscale from image using QuickMagick

62 Views Asked by At

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  | ):
1

There are 1 best solutions below

1
8bithero On BEST ANSWER

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