使用 PHP 检测图像的主要阴影
我以前使用过 GD,但仅用于动态调整大小/生成图像 - 尽管我非常肯定它有能力完成我所追求的任务。
尽可能简单地,我需要检查图像以查明它是浅色背景还是深色背景。即,如果背景主要是“亮”,则返回值“1”,如果背景主要是“暗”,则返回值“0”。
在此过程中一次只会迭代 5 个图像,但我非常注意处理时间 - 该页面将被频繁调用。
谁能指出我该去哪里的正确方向?
I've used GD before, but only ever for resizing/generating images on the fly - though I'm pretty positive it has the capabilities to do what I'm after.
As simply as possible, I need to check an image to find out whether it has a light background or a dark background. I.e. if the background is predominately 'light' I'm returned a value of '1', and if it is predominately 'dark' it returns '0'.
There's only going to be 5 images iterated through in this process at a time, but I'm very concious here of processing time - the page is going to be called often.
Can anyone point me in the right direction on where to go with this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先看看是否有任何可以利用的模式 - 例如,左上角或右上角(例如)总是背景颜色吗?如果是这样,只需查看该像素的颜色即可。
也许您可以通过查看一些关键像素并对它们进行平均来获得“足够好”的想法。
如果做不到这样简单的事情,你需要做的工作就会开始增加几个数量级。
我的一个好主意是采用从左上角到右下角对角线的像素带(也许看看 Bresenham 直线算法)。寻找深色和浅色的串,并且可能选择最长的串;如果这不起作用,也许你应该根据它们的明暗程度对跑步进行“评分”。
如果您的图像不必要地大(例如 1000x1000 或更大),则使用 imagecopyresized 将其廉价地缩小到合理的值(例如 80x80)。
如果图像的大部分是背景色,那么可行的方法是将图像重新采样为 1 像素并检查该像素的颜色(或者可能很小,4x4 左右,然后计算像素以查看图像是否为背景色)主要是浅色或深色)。
请注意,imagecopyresampled 比 imagecopyresized 昂贵得多,因为“resized”仅从原始图像中获取单个像素,而“resampled”实际上将像素混合在一起。
如果您想要测量“亮度”,您只需将 R、G 和 B 值相加即可。或者您可以使用 YCbCr 中使用的亮度公式:
这给出了更“人性化”的结果。中心”的亮度测量。
First see if there are any patterns you can take advantage of - for instance, is the top-left or top-right corner (for example) always going to be of the background colour? If so, just look at the colour of that pixel.
Maybe you can get a "good enough" idea by looking at some key pixels and averaging them.
Failing something simple like that, the work you need to do starts to rise by orders of magnitude.
One nice idea I had would be to take the strip of pixels going diagonally across from the top-left corner to the bottom-right corner (maybe have a look at Bresenham's line algorithm). Look for runs of dark and light colour, and probably take the longest run; if that doesn't work, maybe you should "score" runs based on how light and dark they are.
If your image is unnecessarily large (say 1000x1000 or more) then use imagecopyresized to cheaply scale it down to something reasonable (say 80x80).
Something that will work if MOST of the image is background-colour is to resample the image to 1 pixel and check the colour of that pixel (or maybe something small, 4x4 or so, after which you count up pixels to see if the image is predominantly light or dark).
Note that imagecopyresampled is considerably more expensive than imagecopyresized, since 'resized just takes individual pixels from the original whereas 'resampled actually blends the pixels together.
If you want a measure of "lightness" you could simply add the R, G and B values together. Or you could go for the formula for luma used in YCbCr:
This gives a more "human-centric" measure of lightness.