我有一个HBitmap我从一个用于转换PDF文档中的页面的API中收到的。生成的位图是24位彩色位图。我试图确定,使用制作成pdfs的黑白扫描图像,在Foxit生成的位图上是黑白的。 Foxit是PDF API。这是一些代码! (C / CLI)
// Get HBITMAP using Foxit's RenderPage function
// to convert to dib later
IntPtr hbitmap = FlattenPageToHBitmap(filename, page);
if (hbitmap == IntPtr::Zero)
return IntPtr::Zero;
Bitmap^ b = Bitmap::FromHbitmap(hbitmap);
bool isColor = false;
for (int y = 0; y < b->Height; y++)
{
for (int x = 0; x < b->Width; x++)
{
Color^ c = b->GetPixel(x, y);
unsigned int bits = (int)c->ToArgb();
bits = bits << 8;
bits = bits >> 8; //should get rid of A in ARGB
bool white = (bits == 0xFFFFFF);
bool black = (bits == 0);
if (!black && !white)
{
isColor = true;
break;
}
}
if (isColor)
break;
}
}
一旦我有了这个HBitmap并确定了它的颜色,我会将HBitmap转换为独立于设备的位图,我可以使用我们的内部工具包来回写各种文档格式。
Foxit产生的HBitmap似乎永远不会是完全黑色或白色。有没有一种算法可以用来查看它是否“足够接近”并转换它?将位图保存回pdf时使用位图的像素格式来确定使用的压缩。
答案 0 :(得分:6)
当然,只需计算亮度并测试它是否真的接近零或一。
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;
}
使用the luminance formula from Wikipedia。
或者,Y = c.GetBrightness();
也可以。
答案 1 :(得分:4)
如果你知道如何为每个像素获得R,G和B,那么BW图片应该有R == G == B.
如果不是,并且您希望它是灰度,请使用此公式计算新的RGB值:
value = 0.3 R + 0.59 G + 0.11 B
用值填充R,G和B,然后你去。
答案 2 :(得分:1)
你的意思是它使用深灰色(即基本上是黑色)或非常浅灰色(即基本上是白色)的颜色;或者你的意思是大多数(但不是全部)像素是黑色还是白色?
首先,您可以找到“距离”功能。例如。 dist = R * R + G * G + B * B.然后选择定义黑色或白色的阈值。类似地,你可以说“黑色是当R&lt; a&amp;&amp; G&lt; a&amp;&amp; B&lt; a”,其中a是你的门槛。
对于像素,您可以计算满足阈值的所有像素,并确定是否超过80%(比如说)达到阈值,然后是黑色或白色。
答案 3 :(得分:1)
虽然已经给出了答案,但它们似乎涉及一些神奇的数字。这是一个通用的,更可调的方法,以防你因某些奇怪的原因必须使用RGB(我刚刚意识到它对于HSV / HSL来说当然是微不足道的):
根据Wikipedia,真正的灰色是红色=绿色=蓝色的颜色,即RGB颜色空间对角线上的那些颜色。由于您还需要近灰色,如果t> = 0,我们将颜色定义为阈值t neargray ,如果它位于对角线的半径t管状邻域中。因此,为了确定RGB颜色x是否接近阈值t,只需计算x与其orthogonal projection之间的距离r到对角线上。如果r <= t,则x为“足够灰”。根据自己的喜好调整。