php中使用Imagick实现图像直方图的实现代码_php技巧

我并不打算详细解释专业名词,有兴趣的读者可以查阅文章结尾处的参考链接,那里有通俗易懂的解释:

我们先找一个例子图像(用Canon 550D拍的):

例子图片:butterfly.jpg

下面看看如何使用Imagick实现图像直方图:

复制代码 代码如下:

<?php
$file = 'butterfly.jpg';
$size = array(
'width' => 256,
'height' => 100,
);
$image = new Imagick($file);
$histogram = array_fill_keys(range(0, 255), 0);
foreach ($image->getImageHistogram() as $pixel) {
$rgb = $pixel->getColor();
$histogram[$rgb['r']] += $pixel->getColorCount();
$histogram[$rgb['g']] += $pixel->getColorCount();
$histogram[$rgb['b']] += $pixel->getColorCount();
}
$max = max($histogram);
$threshold = ($image->getImageWidth() * $image->getImageHeight()) / 256 * 12;
if ($max > $threshold) {
$max = $threshold;
}
$image = new Imagick();
$draw = new ImagickDraw();
$image->newImage($size['width'], $size['height'], 'white');
foreach ($histogram as $x => $count) {
if ($count == 0) {
continue;
}
$draw->setStrokeColor('black');
$height = min($count, $max) / $max * $size['height'];
$draw->line($x, $size['height'], $x, $size['height'] - $height);
$image->drawImage($draw);
$draw->clear();
}
$image->setImageFormat('png');
$image->writeImage('histogram.png');
?>

注:代码中之所以加入$threshold这个阀值,是因为有时候某些色阶的值可能会非常大,如果不做处理会干扰最终的生成效果。至于为什么要先除256,接着又乘12,没有什么道理可言,都是我一拍脑袋决定的,你也可以使用别的方法。

最终生成的直方图和Photoshop的效果基本一样,这里就贴一下Photoshop的:

Photoshop生成的直方图
注:使用Photoshop打开图片后,选择窗口,然后选择直方图即可。
本文说的实际上只是RGB通道的直方图绘制方法,原理上,RGB直方图是红绿蓝直方图累加的结果,至于红绿蓝三原色各自的直方图,上面代码稍加修改即可。
注:XARG.ORG上有一个HTML5实现的图像直方图开源项目,效果不错,值得学习。
最后顺便说一下,如果你对摄影知识感兴趣,可参考:如何解读数码相机的直方图。

时间: 2024-09-17 22:30:06

php中使用Imagick实现图像直方图的实现代码_php技巧的相关文章

PHP中使用imagick实现把PDF转成图片_php技巧

PHP Manual里,对imagick的描述,真的是简洁,每个成员函数,点击打开就看到如下文本: 复制代码 代码如下: Warning This function is currently not documented; only its argument list is available. 刚才解决了PHP加载问题后,对图片的处理相当方便,网上随便找了一段: 复制代码 代码如下: <?php Header("Content-type: image/jpeg");    /*

php采集文章中的图片获取替换到本地(实现代码)_php技巧

复制代码 代码如下: /** * 获取替换文章中的图片路径 * @param string $xstr 内容 * @param string $keyword 创建照片的文件名 * @param string $oriweb 网址 * @return string *  */function replaceimg($xstr,$keyword, $oriweb){     //保存路径    $d = date('Ymd', time());    $dirslsitss = '/var/www

在PHP中读取和写入WORD文档的代码_php技巧

复制代码 代码如下: <?  // 建立一个指向新COM组件的索引  $word = new COM("word.application") or die("Can't start Word!");  // 显示目前正在使用的Word的版本号  //echo "Loading Word, v. {$word->Version}<br>";  // 把它的可见性设置为0(假),如果要使它在最前端打开,使用1(真)  // t

php中利用post传递字符串重定向的实现代码_php技巧

复制代码 代码如下: $ch = curl_init('http://domain-name.com/page.php');       curl_setopt($ch, CURLOPT_POST, 1);       curl_setopt($ch, CURLOPT_POSTFIELDS, "FORM_ID=295&NAME=$_POST[NAME]&EMAIL=$_POST[EMAIL]&PHONE=$_POST[PHONE]&DESCRIPTION=$_PO

在PHP中利用wsdl创建标准webservice的实现代码_php技巧

1.创建wsdl 说明: A.非标准的webservice,可能只能PHP才能访问 B.标准的webservice,就必须要使用wsdl(webservice description language,就是用XML语法标准来描述你的服务内容,我是这么理解的) 在这里我只介绍标准的webservice. 那么如何创建wsdl呢?对于PHP来说这确实是件很不容易的事情,有人说用zend studio创建很方便,这是一种方法.但对于那些不喜欢用zend studio的人来说,会觉得创建一个webser

PHP中设置时区,记录日志文件的实现代码_php技巧

复制代码 代码如下: <html><body><?phpdate_default_timezone_set('Asia/Hong_Kong');  //set time zoneset_error_handler("myHandler");               //set error handler$chinatime = date('Y-m-d H:i:s');             //get current time$max_size =

php中批量修改文件后缀名的函数代码_php技巧

复制代码 代码如下: <?php function foreachDir($path){ $handle=opendir($path); if($handle){ while (false !== ($file = readdir($handle))) { if($file!="." && $file!='..'){ if(is_dir($path.$file)){ echo $path.$file."<br/>"; foreach

UCenter中的一个可逆加密函数authcode函数代码_php技巧

复制代码 代码如下: function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) { $ckey_length = 4; // 随机密钥长度 取值 0-32; // 加入随机密钥,可以令密文无任何规律,即便是原文和密钥完全相同,加密结果也会每次不同,增大破解难度. // 取值越大,密文变动规律越大,密文变化 = 16 的 $ckey_length 次方 // 当此值为 0 时,则不产生随机密钥 $key =

用php实现的获取网页中的图片并保存到本地的代码_php技巧

复制代码 代码如下: <?php header("Content-type:image/jpeg"); function read_url($str) { $file=fopen($str,"r"); while(!feof($file)) { $result.=fgets($file,9999); } fclose($file); return $result; } function save_img($str) { $result=read_url($st