如何获取并显示彩色或黑白位图图像的级别
Photoshop 中有一个工具可让您调整图像的级别。我希望能够做同样的事情。我在网上看到过一些显示级别的示例,但它们适用于每个单独的颜色通道(红色、绿色、蓝色或 alpha 或 CMYK),而不是像 Photoshop 输入级别那样的组合视图(见下文)。
另外,有没有办法找到最佳的阴影和高光输入级别设置(基本上是自动级别按钮确定的设置)?
更新:
我想我已经更接近了,但我不确定。这是我拼凑的方法。第一张图片是我的结果,第二张图片是 Photoshop 结果,两者都分析了 Google 徽标:
更新 2:
好的,我想我明白了。代码如下。大多数情况下,它一直在工作。
额外学分: https://pixelero.wordpress.com/2008 /06/19/flash-10-bitmapdatahistogram/#comment-448
我的结果:
Photoshop 结果:
色阶方法:
/**
* Get a histogram of the grayscale levels
* */
private function drawGrayscaleHistogram(bitmapImage:BitmapImage, sprite:Sprite):BitmapData {
var grayScale:Array = [0.3086, 0.3086, 0.3086, 0, 0, 0.3086, 0.3086, 0.3086, 0, 0, 0.3086, 0.3086, 0.3086, 0, 0, 0, 0, 0, 1, 0];
var color:Array = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];
var filter:ColorMatrixFilter = new ColorMatrixFilter(grayScale);
var histogram:Vector.<Vector.<Number>>;
var graphWidth:int = sprite.width;
var graphHeight:int = sprite.height;
var g:Graphics = sprite.graphics;
var vector:Vector.<Number>;
var bitmapData:BitmapData;
var maxValue:int;
var value:int;
var i:int;
// clone the bitmap
bitmapData = bitmapImage.bitmapData.clone();
// convert it to gray scale
bitmapData.applyFilter(bitmapImage.bitmapData, bitmapImage.bitmapData.rect, new Point(), filter);
// get histogram
histogram = bitmapData.histogram();
// since it's grayscale the red green and blue are all the same
vector = histogram[0];
// get the max value for drawing the graph
for (var s:* in vector) {
if (vector[s]>maxValue) {
maxValue = vector[s];
}
}
//trace(maxValue);
//maxValue = 300;
// create white background
g.clear();
g.beginFill(0xFFFFFF, 1.0);
g.drawRect(0, 0, graphWidth, graphHeight);
// draw each line
for each (value in vector) {
g.lineStyle(1, 0);
g.moveTo(i, graphHeight);
g.lineTo(i++, Math.max(0.0, graphHeight-value * graphHeight/maxValue));
}
// assign it to bitmap data
// so we can resize easily if we want
bitmapData = new BitmapData(graphWidth, graphHeight, true, 0x00000000);
bitmapData.draw(sprite);
return bitmapData;
}
用法:
levelsBitmapImage.source = drawGrayscaleHistogram(selectedPicture, sprite1);
In Photoshop there is a tool that lets you adjust the levels of an image. I'd like to be able to do the same thing. I've seen examples online that show the levels but they are for each individual color channel (red, green, blue or alpha or CMYK) but not a combined view like in Photoshop Input Levels (see below).
Also, as a bonus is there a way to find the best shadow and highlight input level settings, basically the settings the Auto level button determines?
Update:
I think I'm closer but I'm not sure. Here is the method I pieced together. The first image is my results and the second is Photoshop results both analyzing the Google logo:
Update 2:
Ok I think I got it. The code is below. It's mostly working all the time, mostly.
Additional credits:
https://pixelero.wordpress.com/2008/06/19/flash-10-bitmapdatahistogram/#comment-448
My results:
Photoshops results:
Levels method:
/**
* Get a histogram of the grayscale levels
* */
private function drawGrayscaleHistogram(bitmapImage:BitmapImage, sprite:Sprite):BitmapData {
var grayScale:Array = [0.3086, 0.3086, 0.3086, 0, 0, 0.3086, 0.3086, 0.3086, 0, 0, 0.3086, 0.3086, 0.3086, 0, 0, 0, 0, 0, 1, 0];
var color:Array = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];
var filter:ColorMatrixFilter = new ColorMatrixFilter(grayScale);
var histogram:Vector.<Vector.<Number>>;
var graphWidth:int = sprite.width;
var graphHeight:int = sprite.height;
var g:Graphics = sprite.graphics;
var vector:Vector.<Number>;
var bitmapData:BitmapData;
var maxValue:int;
var value:int;
var i:int;
// clone the bitmap
bitmapData = bitmapImage.bitmapData.clone();
// convert it to gray scale
bitmapData.applyFilter(bitmapImage.bitmapData, bitmapImage.bitmapData.rect, new Point(), filter);
// get histogram
histogram = bitmapData.histogram();
// since it's grayscale the red green and blue are all the same
vector = histogram[0];
// get the max value for drawing the graph
for (var s:* in vector) {
if (vector[s]>maxValue) {
maxValue = vector[s];
}
}
//trace(maxValue);
//maxValue = 300;
// create white background
g.clear();
g.beginFill(0xFFFFFF, 1.0);
g.drawRect(0, 0, graphWidth, graphHeight);
// draw each line
for each (value in vector) {
g.lineStyle(1, 0);
g.moveTo(i, graphHeight);
g.lineTo(i++, Math.max(0.0, graphHeight-value * graphHeight/maxValue));
}
// assign it to bitmap data
// so we can resize easily if we want
bitmapData = new BitmapData(graphWidth, graphHeight, true, 0x00000000);
bitmapData.draw(sprite);
return bitmapData;
}
Usage:
levelsBitmapImage.source = drawGrayscaleHistogram(selectedPicture, sprite1);
<s:BitmapImage id="selectedPicture" width="100%" height="100%"
scaleMode="letterbox"/>
<mx:UIComponent id="sprite1"/>
<s:BitmapImage id="thresholdGraph" width="100%" height="45"/>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于图像的每个像素,使用公式获取亮度值,然后递增相应的计数器(256 之一)。您将在这 256 个柜台中获得级别分布。将这些值绘制为线条,您将获得如上所示的级别图片。
(从评论中复制以做出正确答案)
For each pixel of image, get brightness value using formula, then increment corresponding counter (one of 256). You'll get levels distribution in those 256 counters. Draw those values as lines and you'll get levels picture like above.
(copied from comments to make proper answer)