我通过使用跛脚编码器对其进行下采样,然后从结果数据点绘制波形,在PHP中渲染波形.我目前正在获得这样的图像:

我想要做的是修改我的代码,使波形的表观动态范围基本上"压缩".要生成看起来更像这样的波形:
我目前用来渲染每个数据点高度的公式如下: -
// draw this data point
// relative value based on height of image being generated
// data values can range between 0 and 255
$v = (int) ( $data / 255 * $height );
// don't print flat values on the canvas if not necessary
if (!($v / $height == 0.5 && !$draw_flat))
// draw the line on the image using the $v value and centering it vertically on the canvas
imageline(
$img,
// x1
(int) ($data_point / DETAIL),
// y1: height of the image minus $v as a percentage of the height for the wave amplitude
$height * $wav - $v,
// x2
(int) ($data_point / DETAIL),
// y2: same as y1, but from the bottom of the image
$height * $wav - ($height - $v),
imagecolorallocate($img, $r, $g, $b)
);
Run Code Online (Sandbox Code Playgroud)
实际幅度由此代码的第一行定义: -
$v = (int) ( $data / 255 * $height );
Run Code Online (Sandbox Code Playgroud)
不幸的是,我的数学技能充其量只是很差 我需要做的是基本上对$ v的值应用'曲线',这样当输入到等式中的数字较低时,得到的输出较高,并且随着输入数量的增加,等式减小放大直到最后输入达到255时,输出也应该是255.同样曲线应该是这样的,输入为0时输出也是0.
如果不清楚我会道歉,但我发现这个问题很难用我有限的数学经验表达出来.
也许视觉表现有助于描述我的意图: -

当$ v的值为0或255时,等式的输出应该完全是输入(0或255).但是,当输入是中间值时,它应该遵循上面曲线的结果输出.(以上只是粗略说明.)
编辑:
基于Alnitiks的pow'功能解决方案,我现在生成的波形如下: -

使用$ v变量的替换公式如下: -
$v = pow($data / 255.0, 0.4) * $height;
Run Code Online (Sandbox Code Playgroud)
我试过提高0.4值,但结果仍然不如预期.
编辑2:
这里要求的是我的$ data变量的原始datadump:
在用于绘制波形之前,这会被传递到公式中以返回$ v(您可以看到我在上面发布的原始代码中对变量$ v做了什么.$ height很简单我设置图像的像素数高渲染.
此数据是逗号分隔的值列表.我希望这有帮助.看来你的断言平均值是128是正确的.到目前为止,我一直无法理解你的纠正.我担心它略微超出了我目前的理解.
没有数学技能(并且可能有助于快速显示):
您有 256 个可能的值。创建一个包含每个值的“动态”值的数组:
$dynamic = array(
0 => 0,
1 => 2,
...
);
Run Code Online (Sandbox Code Playgroud)
完成后,您可以轻松获得动态值:
$v = (int) ($dynamic[(int) $data / 255] * $height);
Run Code Online (Sandbox Code Playgroud)
您可能会失去一些精度,但它可能很有用。
自然动态值是由数学正弦和余弦函数生成的,在 PHP 中这个sin文档(以及那里链接的其他文档)。
您也可以使用循环和该函数来预填充数组并重新使用该数组,以便获得预先计算的值:
$sine = function($v)
{
return sin($v * 0.5 * M_PI);
};
$dynamic = array();
$base = 255;
for ($i = 0; $i <= $base; $i++)
{
$dynamic[$i] = $i/$base;
}
$dynamic = array_map($sine, $dynamic);
Run Code Online (Sandbox Code Playgroud)
我这里使用了一个可变函数,因此您可以编写多个并且可以轻松测试哪一个符合您的需求。