Visual c++ 确定颜色位图是否为黑白

Visual c++ 确定颜色位图是否为黑白,visual-c++,bitmap,c++-cli,gdi+,foxit,Visual C++,Bitmap,C++ Cli,Gdi+,Foxit,我有一个HBitmap,我从一个用于转换PDF文档中页面的API接收。生成的位图是24位彩色位图。我正试图用制作成PDF的黑白扫描图像来确定Foxit生成的位图上的黑白图像。Foxit是PDF API。这里有一些代码!(c++/cli) //使用Foxit的RenderPage函数获取HBITMAP //稍后转换为dib IntPtr hbitmap=FlattPageToHBITMAP(文件名,第页); if(hbitmap==IntPtr::零) 返回IntPtr::零; 位图^b=位图::

我有一个HBitmap,我从一个用于转换PDF文档中页面的API接收。生成的位图是24位彩色位图。我正试图用制作成PDF的黑白扫描图像来确定Foxit生成的位图上的黑白图像。Foxit是PDF API。这里有一些代码!(c++/cli)

//使用Foxit的RenderPage函数获取HBITMAP
//稍后转换为dib
IntPtr hbitmap=FlattPageToHBITMAP(文件名,第页);
if(hbitmap==IntPtr::零)
返回IntPtr::零;
位图^b=位图::来自hbitmap(hbitmap);
bool-isColor=false;
对于(int y=0;yHeight;y++)
{
对于(intx=0;xWidth;x++)
{
颜色^c=b->GetPixel(x,y);
无符号整数位=(int)c->ToArgb();
bits=bits>8;//应该去掉ARGB中的A
布尔白=(位==0xFFFFFF);
布尔黑=(位==0);
如果(!黑色&&!白色)
{
isColor=true;
打破
}
}
if(isColor)
打破
}
}
一旦我有了这个HBitmap并确定了它的颜色,我将把HBitmap转换成一个独立于设备的位图,我可以使用我们的内部工具包将它写回各种文档格式

问题
Foxit生成的HBitmap似乎从来都不是完全黑色或白色的。有没有一种算法可以用来判断它是否“足够接近”并转换它?位图的像素格式用于将其保存回pdf以确定使用的压缩。

如果您知道如何获得每个像素的R、G和B,则BW图片应具有R==G==B

如果不是,并且希望为灰度,请使用以下公式计算新的RGB值:

value = 0.3 R + 0.59 G + 0.11 B

用值填充R、G和B,就可以了。

如果你知道如何得到每个像素的R、G和B,那么BW图片应该有R==G==B

如果不是,并且希望为灰度,请使用以下公式计算新的RGB值:

value = 0.3 R + 0.59 G + 0.11 B

用数值填充R、G和B,就可以了。

当然,只需计算亮度并测试它是否真的接近零或一

Color c = b->GetPixel(x, y); // no ^ because Color is a value type
float Y = (0.2126*c.R + 0.7152*c.G + 0.0722*c.B) / 255;
bool white = (Y > .95);
bool black = (Y < .05);
if (!black && !white)
{
    isColor = true;
    break;
}
Color c=b->GetPixel(x,y);//否^,因为颜色是值类型
浮动Y=(0.2126*c.R+0.7152*c.G+0.0722*c.B)/255;
布尔白=(Y>0.95);
布尔黑=(Y<0.05);
如果(!黑色&&!白色)
{
isColor=true;
打破
}
使用


或者,
Y=c.GetBrightness()也可以工作。

当然,只需计算亮度并测试它是否真的接近零或一

Color c = b->GetPixel(x, y); // no ^ because Color is a value type
float Y = (0.2126*c.R + 0.7152*c.G + 0.0722*c.B) / 255;
bool white = (Y > .95);
bool black = (Y < .05);
if (!black && !white)
{
    isColor = true;
    break;
}
Color c=b->GetPixel(x,y);//否^,因为颜色是值类型
浮动Y=(0.2126*c.R+0.7152*c.G+0.0722*c.B)/255;
布尔白=(Y>0.95);
布尔黑=(Y<0.05);
如果(!黑色&&!白色)
{
isColor=true;
打破
}
使用


或者,
Y=c.GetBrightness()也可以工作。

你是说它使用的颜色是非常深灰色(即基本黑色)还是非常浅灰色(即基本白色);或者你的意思是大多数(但不是全部)像素是黑色还是白色

首先,你可以找到一个“距离”函数。例如,dist=R*R+G*G+B*B。然后选择定义黑色或白色的阈值。类似地,您可以说“黑色是当R
至于像素,你可以计算所有符合阈值的像素,然后决定是否超过80%(比如)符合阈值,那么它是黑色还是白色。

你的意思是它使用的颜色是非常深灰色(即基本黑色)还是非常浅灰色(即基本白色);或者你的意思是大多数(但不是全部)像素是黑色还是白色

首先,你可以找到一个“距离”函数。例如,dist=R*R+G*G+B*B。然后选择定义黑色或白色的阈值。类似地,您可以说“黑色是当R
至于像素,你可以计算所有符合阈值的像素,然后决定是否超过80%(比如)符合阈值,然后是黑色还是白色。

虽然已经给出了答案,但它们似乎涉及一些神奇的数字。这里有一个通用的、更可调整的方法,以防您出于某种奇怪的原因不得不使用RGB(我刚刚意识到,HSV/HSL当然很简单):


根据,真灰色是指红=绿=蓝的颜色,即RGB颜色空间对角线上的颜色。由于您还需要接近灰色的颜色,因此如果颜色位于对角线的半径t管状邻域中,则对于t>=0,我们将其定义为阈值t neargray。因此,要确定RGB颜色x是否为阈值t neargray,只需计算x与其对角线之间的距离r。如果r虽然已经给出了答案,但它们似乎涉及一些神奇的数字。这里有一个通用的、更可调整的方法,以防您出于某种奇怪的原因不得不使用RGB(我刚刚意识到,HSV/HSL当然很简单):


根据,真灰色是指红=绿=蓝的颜色,即RGB颜色空间对角线上的颜色。由于您还需要接近灰色的颜色,因此如果颜色位于对角线的半径t管状邻域中,则对于t>=0,我们将其定义为阈值t neargray。因此,要确定RGB颜色x是否为阈值t neargray,只需计算x与其对角线之间的距离r。如果r为什么是这些数字(0.3,0.59,0.11)?另外,如果RGB图像是灰度的,我想确定它是否“接近”BW.BTW,列出亮度公式的位置可能会很有用,因为我建议使用相同的方法,但在Wikipedia上发现了不同的公式。我认为您需要灰度,并且它编码在RGB中。我的错。为什么是那些数字(0.3,0.59,0.11)?另外,如果RGB图像是灰度的,我想确定它是否“接近”BW.BTW,列出亮度公式的位置可能会很有用,因为我建议使用相同的方法