C++ 使用ImageMagick++;修改图像对比度/亮度的步骤

C++ 使用ImageMagick++;修改图像对比度/亮度的步骤,c++,bitmap,imagemagick,brightness,contrast,C++,Bitmap,Imagemagick,Brightness,Contrast,我试图将对比度和亮度应用于内存中的位图,但我完全迷失了方向。目前我正在尝试使用Magick++来实现这一点,但如果其他API中有一个能更好地工作,我会洗耳恭听。我设法找到了Magick::Image::sigmoidalContrast()来应用对比度,但我不知道如何让它工作。我正在创建一个图像,将缓冲区指针传递给它,然后调用该函数,但它似乎没有改变任何东西,所以我的第一个想法是它正在制作一个副本并修改它。即使如此,我也不知道如何从Magick::Image对象中获取数据 这是我到目前为止得到的

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

这是我到目前为止得到的

Magick::Image image(fBitmapData->mGetTextureWidth(), fBitmapData->mGetTextureHeight(), "RGBA", MagickCore::CharPixel, pixels);
image.sigmoidalContrast(1, 20.0);
文档是无用的,搜索之后,我只能找到提示,第一个参数实际上是一个布尔值,尽管它需要一个大小\u t,用于指定是添加还是减去对比度,第二个值是我不知道要传递什么,所以我只使用20.0来测试


那么,有人知道这是否适用于对比度,如果没有,那么如何应用对比度?同样地,我也不知道如何应用亮度,也找不到任何看起来能正常工作的功能。

根据Imagemagick网站的说法-用于命令行,但可能是相同的

-乙状结肠对比度X中点

在不饱和高光或阴影的情况下增加对比度

在不饱和高光或阴影的情况下,使用S形传递函数增加图像的对比度。对比度表示要增加多少对比度。例如,接近0表示无,3表示典型,20表示很多。请注意,精确为零是无效的,但0.0001与对比度无变化的差别可以忽略。中点指示中间色调在合成图像中的位置(0为白色;50%为中灰色;100%为黑色)。默认情况下,图像对比度增加,使用+S形对比度降低对比度

要实现相当于S形亮度变化的效果,请使用-S形对比度亮度X0%增加亮度,使用class=“arg”>+S形对比度亮度X0%降低亮度

在命令行上有一个新的亮度对比度设置,它可能在较新版本的magic++

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

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

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

您还可以使用-channel控制要应用亮度和/或对比度更改的通道。默认情况下,对所有通道应用相同的转换

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

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

负斜率,即对图像求反,不可能使用此功能。所有可实现的斜率均为零或正

偏移在亮度=-100时为-0.5,在亮度=0时为0,在亮度=+100时为+0.5。因此,当对比度=0且亮度=100时,结果为全白色。类似地,当对比度=0且亮度=-100时,结果为全黑

由于参数的值范围为-100到+100,因此添加“%”符号与不使用“%”符号无异


如果magick++与Imagick相似,那么它可能远远落后于Imagemagick选项

解决方案;我使用的对比度函数是正确的,对于亮度,我最终使用了
image.modulate(亮度,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\u QUANTUM\u DEPTH
,因为这将极大地改变值。对于我的代码,
MAGICKCORE\u QUANTUM_DEPTH
恰好被定义为16,因此所有的值都在0到65535之间,我只是在复制数据时通过执行
realValue=magickValue>>8
来修正,因为纹理数据是
无符号字符

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

对于
modulate()
,文档中说,每个值都应该指定为1.0,以便不进行更改,这是完全错误的。这些值实际上是一个百分比,因此