C++ 将单色FreeType位图转换为8位像素阵列
我花了几个小时试图将FreeType生成的单色位图转换为每像素使用8位的像素阵列(以便我可以将它们用作OpenGL的alpha值)。我知道我可以得到一个普通的8bpp位图并使用它,但我真的需要单色版本。我已经尝试过阈值化像素的方法,但结果并不令人满意。看起来,一旦你有了抗锯齿版本,你就再也回不去了 下面的代码片段就是我现在所拥有的,除了几个字母之外,它几乎可以正常工作C++ 将单色FreeType位图转换为8位像素阵列,c++,freetype2,C++,Freetype2,我花了几个小时试图将FreeType生成的单色位图转换为每像素使用8位的像素阵列(以便我可以将它们用作OpenGL的alpha值)。我知道我可以得到一个普通的8bpp位图并使用它,但我真的需要单色版本。我已经尝试过阈值化像素的方法,但结果并不令人满意。看起来,一旦你有了抗锯齿版本,你就再也回不去了 下面的代码片段就是我现在所拥有的,除了几个字母之外,它几乎可以正常工作 if (FT_Load_Glyph(face, glyphIndex, FT_LOAD_MONOCHROME | FT_LOAD
if (FT_Load_Glyph(face, glyphIndex, FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO))
throw exception();
if (FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO))
throw exception();
const Size bitmapSize = Size(
face->glyph->metrics.width / 64, face->glyph->metrics.height / 64
);
u8 *bitmapBits = face->glyph->bitmap.buffer;
u8 *bitmapBytes = new u8[bitmapSize.width * bitmapSize.height];
memset(bitmapBytes, 0, bitmapSize.width * bitmapSize.height);
int width = face->glyph->bitmap.width;
int height = face->glyph->bitmap.rows;
const u8 *src = bitmapBits;
for (int row = 0; row < height; ++row)
{
u8 *dst = &bitmapBytes[row * width];
for (int col = 0; col < width / 8; ++col)
{
u8 byte = src[col];
*dst++ = ((byte & (1 << 7)) != 0) ? 255: 0;
*dst++ = ((byte & (1 << 6)) != 0) ? 255: 0;
*dst++ = ((byte & (1 << 5)) != 0) ? 255: 0;
*dst++ = ((byte & (1 << 4)) != 0) ? 255: 0;
*dst++ = ((byte & (1 << 3)) != 0) ? 255: 0;
*dst++ = ((byte & (1 << 2)) != 0) ? 255: 0;
*dst++ = ((byte & (1 << 1)) != 0) ? 255: 0;
*dst++ = ((byte & (1 << 0)) != 0) ? 255: 0;
}
u8 trailingByte = src[width / 8];
int i = 7;
switch (width % 8)
{
case 7: *dst++ = ((trailingByte & (1 << (i--))) != 0) ? 255 : 0;
case 6: *dst++ = ((trailingByte & (1 << (i--))) != 0) ? 255 : 0;
case 5: *dst++ = ((trailingByte & (1 << (i--))) != 0) ? 255 : 0;
case 4: *dst++ = ((trailingByte & (1 << (i--))) != 0) ? 255 : 0;
case 3: *dst++ = ((trailingByte & (1 << (i--))) != 0) ? 255 : 0;
case 2: *dst++ = ((trailingByte & (1 << (i--))) != 0) ? 255 : 0;
case 1: *dst++ = ((trailingByte & (1 << (i--))) != 0) ? 255 : 0;
case 0: break;
}
src += face->glyph->bitmap.pitch;
}
if(FT_Load_字形(面、字形索引、FT_Load_单色| FT_Load_目标_单色))
抛出异常();
如果(FT_渲染_字形(面->字形,FT_渲染_模式_单声道))
抛出异常();
常量大小bitmapSize=大小(
面->字形->metrics.width/64,面->字形->metrics.height/64
);
u8*位图位=面->字形->位图.buffer;
u8*bitmapBytes=新u8[bitmapSize.width*bitmapSize.height];
memset(bitmapBytes,0,bitmapSize.width*bitmapSize.height);
int width=face->glyph->bitmap.width;
int height=face->glyph->bitmap.rows;
常量u8*src=位图位;
对于(int行=0;行<高度;++行)
{
u8*dst=&bitmapBytes[行*宽度];
用于(整数列=0;列<宽度/8;++列)
{
u8字节=src[col];
*dst++=(字节和(1行中的字节数不一定是适合行中位的最小数目,而是在位图的节距字段中报告。您可以使用FT_RENDER_MODE_NORMAL获得适合用作alpha通道的8位灰度位图,或使用FT_bitmap_Convert将单色位图转换为8位。您可以还可以看看@RetiredInja,我需要单色位图(没有抗锯齿),所以FT_RENDER_MODE_NORMAL是不可能的(我尝试过使用FT_bitmap_Convert,但不管我做了什么,我都会胡言乱语)。我不能只加载一个普通位图,然后通过阈值化像素手动将其转换为单色图像,因为结果很难看,没有单色版本那么清晰和漂亮。一旦有了抗锯齿版本,你就不能回头了。:/有趣的是,即使我将原始单色位图从FreeType输入到OpenGL(使用glTexImage2D和GL_位图)根本不起作用(只得到黑色矩形而不是字母),因此似乎需要进行一些处理,我几乎得到了它,除了我遇到麻烦的几个字母。有什么想法吗?