【问题标题】:Using ImageMagick++ to modify image contrast/brightness使用 ImageMagick++ 修改图像对比度/亮度
【发布时间】:2012-06-13 23:56:48
【问题描述】:

我正在尝试将对比度和亮度应用于内存中的位图,但我完全迷失了。目前我正在尝试使用 Magick++ 来做到这一点,但如果其他 API 之一能更好地工作,我会全力以赴。我设法找到 Magick::Image::sigmoidalContrast() 来应用对比度,但我不知道如何让它工作。我正在创建一个图像,将缓冲区指针传递给它,然后调用该函数,但它似乎没有改变任何东西,所以我的第一个想法是它正在制作一个副本并修改它。即便如此,我也不知道如何从 Magick::Image 对象中获取数据。

这是我目前得到的。

Magick::Image image(fBitmapData->mGetTextureWidth(), fBitmapData->mGetTextureHeight(), "RGBA", MagickCore::CharPixel, pixels);
image.sigmoidalContrast(1, 20.0);

文档没用,搜索后我只能发现第一个参数实际上是一个布尔值的提示,即使它需要一个 size_t,它指定是添加还是减去对比度,而第二个值是我没有的知道要通过什么,所以我只是使用 20.0 来测试。

那么有谁知道这是否适用于对比,如果不是,那么你如何应用对比?同样,我仍然不知道如何应用亮度,也找不到任何看起来可以工作的功能。

【问题讨论】:

    标签: c++ bitmap imagemagick brightness contrast


    【解决方案1】:

    根据 Imagemagick 网站 - 对于命令行但可能相同?

    -sigmoidal-对比度对比x中点

    增加对比度而不使高光或阴影饱和。

    使用 sigmoidal 传递函数增加图像的对比度,而不会使高光或阴影饱和。对比度表示增加对比度的程度。例如,接近 0 表示无,3 表示典型,20 表示很多。请注意,恰好为零是无效的,但 0.0001 与对比度没有变化可以忽略不计。中点表示中间色调在合成图像中的位置(0 为白色;50% 为中灰色;100% 为黑色)。默认图片对比度增加,使用+sigmoidal-contrast降低对比度。

    要实现等效于 sigmoidal 的亮度变化,请使用 -sigmoidal-contrast brightx0% 来增加亮度,使用 class="arg">+sigmoidal-contrast brightnessx0% 来降低亮度。

    在命令行有一个新的亮度对比度设置,可能在以后的magic++版本中?

    -brightness-对比度亮度{xcontrast}{%}}

    调整图像的亮度和/或对比度。

    亮度和对比度值将更改应用于输入图像。它们不是绝对的设置。亮度或对比度值为零表示没有变化。每个值的范围是 -100 到 +100。正值增加亮度或对比度,负值降低亮度或对比度。要仅控制对比度,请将亮度设置为 0。要仅控制亮度,请将对比度设置为 0 或将其关闭。

    您还可以使用 -channel 来控制应用亮度和/或对比度变化的通道。默认是对所有通道应用相同的转换。

    亮度和对比度参数转换为线性变换的偏移量和斜率,并使用 -function 多项式“斜率,偏移量”应用。

    斜率从对比度=-100 的 0 变化到对比度=+100 的几乎垂直。对于亮度=0 和对比度=-100,结果完全是中灰色。对于亮度=0 和对比度=+100,结果将接近但未完全达到中灰的阈值;也就是说,线性变换是一条非常陡峭的中灰色垂直线。

    使用此功能无法实现负斜率,即否定图像。所有可实现的斜率都是零或正数。

    偏移量从亮度=-100 时的 -0.5 到亮度=0 时的 0 到亮度=+100 时的 +0.5 变化。因此,当对比度=0 和亮度=100 时,结果是全白的。同样,当对比度=0,亮度=-100时,结果是全黑。

    由于参数的取值范围是 -100 到 +100,因此添加 '%' 符号与不使用它没有什么不同。

    如果 magick++ 与 Imagick 类似,它可能会远远落后于 Imagemagick 选项

    【讨论】:

      【解决方案2】:

      想通了;我使用的对比度功能是正确的,而对于亮度,我最终使用了image.modulate(brightness, 100.0, 100.0);。要从图像对象中获取数据,您可以通过以下方式获取整个图像的像素

      const MagickCore::PixelPacket * magickPixels = image.getConstPixels(0, 0, image.columns(), image.rows());
      

      然后将magickPixels 数据复制回传递给图像构造函数的原始pixels。需要注意的重要一点是,MagickCore::PixelPacket::opacity 成员并不是您想象的那样。如果像素是完全透明的,您会认为该值为 0,对吧?出于某种原因,ImageMagick 正在做相反的事情。因此,为了完全透明,该值将是 255。这意味着您需要执行 255 - opacity 才能获得正确的值。

      还要注意编译 ImageMagick 时使用的MAGICKCORE_QUANTUM_DEPTH,因为这会极大地改变值。对于我的代码 MAGICKCORE_QUANTUM_DEPTH 恰好被定义为 16,因此所有值的范围都在 0 到 65535 之间,由于纹理数据是 unsigned char 值,所以我只是在将数据复制回来时通过执行 realValue = magickValue >> 8 来修复它.

      只是为了说明如何使用这些函数,由于文档很糟糕并且完全错误,signmoidalContrast() 的第一个参数实际上是一个布尔值,即使类型是 size_t,它指定是否增加对比度( true) 或减少它 (false),第二个是从 0.00001 到 20.0 的范围。我说 0.00001 是因为 0.0 是一个无效值,所以它只需要是一些接近但不完全是 0.0 的小数。

      对于modulate(),文档说每个值都应该指定为 1.0 以保持不变,这是完全错误的。这些值实际上是一个百分比,因此您可以指定 100.0。

      我希望这对某人有所帮助,因为我花了一整天的时间才弄明白这些东西。

      【讨论】:

      • 我想知道为什么我的图像变黑了。这就解释了!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多