rmagick / rmagick

Ruby bindings for ImageMagick
https://rmagick.github.io/
MIT License
696 stars 140 forks source link

How to replace the deprecated Image#opacity= #1335

Closed nengxu closed 1 year ago

nengxu commented 2 years ago

The Image#opacity= has been deprecated in: https://github.com/rmagick/rmagick/pull/753/commits/82c0335149bb7df07837325238e2e257a207c6bb

How can we replace the existing Image#opacity=? In our application, opacity= was used to set the opacity with an integer (percentage number). The CHANGELOG.md just mentioned Image#alpha. However, alpha() only accepts enumeration Magick::AlphaChannelOption, not integer as parameter. It cannot set opacity like before.

TypeError (wrong enumeration type - expected Magick::AlphaChannelOption, got Integer):

Our application is broken due to this. Any help is appreciated.

dlemstra commented 2 years ago

You can use the fx method for that: image.fx('0.5', Magick::AlphaChannel) instead.

nengxu commented 2 years ago

@dlemstra The parameter to opacity= is an integer, and no need to specify channel. Now fx(expression, channel), expression is a string of float? How can we just restore to the equivalent of opacity= with fx()?

dlemstra commented 2 years ago

Not sure what you are asking? The "replacement" for this would be to use the fx method instead.

nengxu commented 2 years ago

The parameters are different between opacity= and fx(). I just tried image.fx('0.5', Magick::AlphaChannel). It produced nothing visible.

We used to have the below code:

white_canvas.opacity = set_opacity(opacity)

def set_opacity(opacity=nil) if opacity.blank? Magick::QuantumRange else Magick::QuantumRange - (Magick::QuantumRange * opacity / 100.to_f).to_i end end

While the opacity parameter is a percentage number, eg., 75 (75%). How can we achieve the same result with fx()?

dlemstra commented 1 year ago

The fx method returns a new images so you will need to do this: result = white_canvas.fx('0.5', Magick::AlphaChannel).

nengxu commented 1 year ago

Thanks for this tip. However, fx() is not equivalent to the deprecated opacity=(). We just cannot use fx() to restore the old opacity function.

Before with rmagick V3, We have text color, and background color. We can set opacity for both the text and the background.

Now with fx(), like this: white_canvas = white_canvas.fx((opacity / 100.0).to_s, Magick::AlphaChannel)

the text box will be shown as background color with sort of opacity, but the text is not visible.

We are not familiar with image processing. For example, we don't understand the Magick::AlphaChannel parameter in fx(). We don't have this kind of parameter in the old opacity=().

Please help us to solve this problem.

dlemstra commented 1 year ago

Using (opacity / Magick::QuantumRange).to_s will probably allow you to use the same value for opacity. The value should be a percentage in the range from 0.0 till 1.0. So the value 0.5 would mean 50%.

nengxu commented 1 year ago

@dlemstra We are saving the transparency as percentage. So the 0.5 part has no problem. But the canvas.fx() just cannot achieve the same effect as the old opacity=(). As mentioned in my previous comment:

the text box is shown as background color with sort of opacity, but the text is not visible.

nengxu commented 1 year ago

@dlemstra We also tried this:

white_canvas.quantum_operator(Magick::SetQuantumOperator, 0.30 * Magick::QuantumRange, Magick::AlphaChannel)

However, the same result, transparency is achieved with the text color, not the background color as expected. And the text is not shown, possibly due to text color is used for transparency.

nengxu commented 1 year ago

We figured out that the transparency issue is related to opaque_channel() and its fuzz parameter. We used use 300, now need to reduce to below 250.