确定彩色位图是否为黑白
我有一个从 API 接收的 HBitmap,我正在使用它来转换 PDF 文档中的页面。生成的位图是 24 位颜色位图。我试图确定,使用制作成 pdf 的黑白扫描图像,福昕生成的位图上是否是黑白的。 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 时,会使用位图的像素格式来确定所使用的压缩方式。
I have a HBitmap I am recieving from an API i am using to convert pages in PDF documents. The resulting bitmap is 24 bit color bitmap. I am trying to determine, using black and white scanned images that were made into pdfs, are black and white on the resulting bitmap from Foxit. Foxit is the PDF API. Here is some Code! (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;
}
}
once I have this HBitmap and have determined its colors, I will convert the HBitmap to a Device-Independent Bitmap which I can use our in-house toolkit to write back to various document formats.
The Problem
The resulting HBitmap from Foxit never seems to be fully black or white. Is there an algorithm I can use to see if its "close enough" and convert it? the pixel format of the bitmap is used when saving it back out to a pdf to determine the compression used.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
当然,只需计算亮度并测试它是否真的接近零或一。
使用维基百科的亮度公式。
或者,
Y = c.GetBrightness();
也可以工作。Sure, just calculate luminance and test if it's really near zero or one.
Using the luminance formula from Wikipedia.
Or,
Y = c.GetBrightness();
could also work.如果您知道如何获取每个像素的 R、G 和 B,那么黑白图片应该具有 R == G == B。
如果不是,并且您希望它是灰度,请使用以下公式计算新的 RGB 值:
将值填充到 R、G 和 B 中即可。
If you know how to get R, G and B for every pixel, then BW picture should have R == G == B.
If it isn't and you want it to be grayscale, use this formula to calculate new RGB values:
Fill R, G and B with value and there you go.
您的意思是它使用非常深的灰色(即本质上是黑色)或非常浅的灰色(即本质上是白色)的颜色吗?或者你的意思是大多数(但不是全部)像素是黑色或白色?
首先,您可以找到“距离”函数。例如。距离 = R*R+G*G+B*B。然后选择定义黑度或白度的阈值。类似地,您可以说“当 R < a && G < a && B < a 时黑色”,其中 a 是您的阈值。
至于像素,你可以统计所有满足阈值的像素,并决定如果超过 80%(比如)满足阈值,则它是黑色或白色。
Do you mean it uses colors which are very dark gray (ie. essentially black) or very light gray (ie. essentially white); or do you mean most (but not all) of the pixels are black or white?
For the first, you could find a "distance" function. Eg. dist = R*R+G*G+B*B. Then choose thresholds that define how black or how white. similarly, you could say "black is when R < a && G < a && B < a" where a is your threshold.
As for pixels, you could count up all pixels that meet the threshold, and decide if more than 80% (say) meet the threshold then it is black or white.
尽管已经给出了答案,但它们似乎涉及一些神奇的数字。这是一种通用的、更可调整的方法,以防您由于某种奇怪的原因必须使用 RGB(我刚刚意识到这对于 HSV/HSL 当然是微不足道的):
根据 维基百科,真正的灰色是那些红度 = 绿度 = 蓝度的颜色,即 RGB 颜色空间对角线上的颜色。由于您还需要接近灰色的颜色,因此如果颜色位于对角线的半径 t 管状邻域内,我们将在 >= 0 时将颜色定义为阈值 t 接近灰色。因此,要确定 RGB 颜色 x 是否为接近灰色的阈值 t,只需计算 x 与其正交投影之间的距离 r投影到对角线上。如果 r <= t,则 x 是“足够灰色”。根据您的喜好调整 t。
Although there are already answers given, they seem to involve some magic numbers. Here's a general, more adjustable approach in case you for some strange reason have to use RGB (I just realized that it's of course trivial with HSV/HSL):
According to Wikipedia, true gray colors are those for which redness = greenness = blueness, i.e. those colors on the diagonal of the RGB color-space. Since you also want near-gray colors, we'll define a color as threshold t neargray for a t >= 0 if it lies in a radius t tubular neighborhood of the diagonal. Thus, to determine if an RGB-color x is threshold t neargray, simply calculate the distance r between x and its orthogonal projection onto the diagonal. If r <= t, x is "gray enough". Adjust t to your liking.