使用带有Wand的Python中ImageMagick的+ level-colors

时间:2016-07-28 16:48:37

标签: python imagemagick wand

我将使用Wand来剪切图像的某些部分。图像具有透明背景。但在我删除部分之前,我首先要对源图像进行一些调整(而不是实际更改源文件)。

我想做的调整是:

  1. 将黑点更改为灰色并将白点保持白色
  2. 将所有颜色值缩放到新的灰色和白色范围
  3. 将透明背景替换为100%黑色
  4. 将图像转换为灰度
  5. 我可以使用ImageMagick的简单命令获得所需的结果:

    convert input.png +clone +level-colors gray,white -background black -alpha remove -colorspace Gray output.png

    但是如何使用Wand做到这一点?似乎没有办法从Wand应用+ level-colors操作。我猜这个问题的解决方案:Is there a -level function in wand-py也不适用于我的问题。因为似乎magick图像API没有水平颜色方法。

    效果的示例结果:

    输入: Before 输出: After

5 个答案:

答案 0 :(得分:2)

-level-colors行为可以通过wand.image.Image.level方法应用,但需要针对每个颜色通道执行。提供的两种颜色用作参考黑/白点。

例如......

from wand.image import Image
from wand.color import Color
from wand.compat import nested

with Image(filename='rose:') as rose:
    # -level-colors red,green
    with nested(Color('red'),
                Color('green')) as (black_point,
                                    white_point):
        # Red channel
        rose.level(black_point.red,
                   white_point.red,
                   1.0,
                   'red')
        # Green channel
        rose.level(black_point.green,
                   white_point.green,
                   1.0,
                   'green')
        # Blue channel
        rose.level(black_point.blue,
                   white_point.blue,
                   1.0,
                   'blue')
    rose.save(filename='output.png')

-level-colors

对于+level-colors,只需反转黑/白点。

rose.level(white_point.red,
           black_point.red,
           1.0,
           'red')

答案 1 :(得分:1)

由于你的输出图像是灰色的,你真的不需要+level-colors,你可以做同样的事情:

convert movies.png -channel RGB -colorspace gray +level 50,100% -background black -alpha remove output.png

另一种选择可能是使用-fx运算符。如果您想象您的像素亮度在0(黑色)和1(白色)之间变化,那么如果将所有亮度除以2,它们将在0和{{1}之间变化}。然后,如果你添加0.5,它们会在0.5(灰色中间)和0.5(白色)之间变化 - 这就是你想要的:

1

答案 2 :(得分:0)

fmw42在A way to perform the +level ImageMagick operation in Wand?中使用多项式函数指定了一种在Wand中实现+ level运算的方法。

我已经应用了fmw42的解决方案来创建一个执行+ level-colors操作的函数。

from wand.image import Image

#wand_imageToColorize should be an instance of wand.image.Image.
#i_listRgbRangeLowerLimits = [iRedLowerLimit, iGreenLowerLimit, iBlueLowerLimit]
#i_listRgbRangeUpperLimits = [iRedUpperLimit, iGreenUpperLimit, iBlueUpperLimit]
def Colorize(wand_imageToColorize,
             i_listRgbRangeLowerLimits, i_listRgbRangeUpperLimits):
    #input assurance
    for iIndex in range(0, 3):
        if i_listRgbRangeLowerLimits[iIndex] > \
            i_listRgbRangeUpperLimits[iIndex]:
            iTemp = i_listRgbRangeLowerLimits[iIndex]
            i_listRgbRangeLowerLimits[iIndex] = i_listRgbRangeUpperLimits[iIndex]
            i_listRgbRangeUpperLimits[iIndex] = iTemp

        if i_listRgbRangeLowerLimits[iIndex] < 0:
            i_listRgbRangeLowerLimits[iIndex] = 0

        if i_listRgbRangeUpperLimits[iIndex] > 255:
            i_listRgbRangeUpperLimits[iIndex] = 255

    #perform colorization
    str_tupleChannelNames = ('red', 'green', 'blue')

    for iColorComponentIndex in range(0, 3):
        strChannelName = str_tupleChannelNames[iColorComponentIndex]

        fB = float(i_listRgbRangeLowerLimits[iColorComponentIndex]) / 255.0
        fA = float(i_listRgbRangeUpperLimits[iColorComponentIndex]) / 255.0 - fB

        wand_imageToColorize.function('polynomial', [fA, fB], strChannelName)

答案 3 :(得分:0)

您的命令没有任何意义。 +克隆导致两个相同的输出图像。通常,克隆要求将其放在一组括号中。

所以也许你的意思

convert input.png +level-colors gray,white -background black -alpha remove -colorspace Gray output.png


除了图像是JPG而不是PNG的事实之外,我可以实现与您类似的功能
convert input.jpg -colorspace gray -evaluate add 50% result.jpg


enter image description here

稍微调整一下值(50%)可以使其更接近。

请参阅http://docs.wand-py.org/en/0.5.1/wand/image.html的wand.image.EVALUATE_OPS--evaluate添加50%

答案 4 :(得分:0)

My other answer is probably simpler and does the job in question. But here is a formal way to do +level-colors by using -clut.

For example:

Input:

enter image description here


Here is +level-colors

convert lenag.png +level-colors red,blue lenag_levelcolors.png


enter image description here

Using -clut, you can get pretty close though not a perfect match.

convert lenag.png \( -size 1x1 xc:red xc:blue +append -filter cubic -resize 256x1! \) -clut lenag_rb4.png


enter image description here

For the OP original processing, one could then do:

convert input.jpg -colorspace gray \( -size 1x1 xc:gray xc:white +append -filter cubic -resize 256x1! \) -clut output.jpg


enter image description here

See Wand clut at http://docs.wand-py.org/en/0.5.1/wand/image.html