unsigned char* 缓冲区到 System::Drawing::Bitmap
我正在尝试创建一个工具/资产转换器,使用 FreeType2 引擎。
下面的第一张图片是 FreeType2]1 引擎的直接输出。第二个图像是尝试将其转换为 System::Drawing::Bitmap 后的结果。
目标 http://www.freeimagehosting.net/uploads/fb102ee6da.jpg 当前结果 http://www.freeimagehosting.net/uploads/9ea77fa307.jpg
任何提示/技巧/对这里发生的事情的想法将不胜感激。解释字节布局和像素格式的文章链接也会有所帮助。
FT_Bitmap *bitmap = &face->glyph->bitmap;
int width = (face->bitmap->metrics.width / 64);
int height = (face->bitmap->metrics.height / 64);
// must be aligned on a 32 bit boundary or 4 bytes
int depth = 8;
int stride = ((width * depth + 31) & ~31) >> 3;
int bytes = (int)(stride * height);
// as *.bmp
array<Byte>^ values = gcnew array<Byte>(bytes);
Marshal::Copy((IntPtr)glyph->buffer, values, 0, bytes);
Bitmap^ systemBitmap = gcnew Bitmap(width, height, PixelFormat::Format24bppRgb);
// create bitmap data, lock pixels to be written.
BitmapData^ bitmapData = systemBitmap->LockBits(Rectangle(0, 0, width, height), ImageLockMode::WriteOnly, bitmap->PixelFormat);
Marshal::Copy(values, 0, bitmapData->Scan0, bytes);
systemBitmap->UnlockBits(bitmapData);
systemBitmap->Save("Test.bmp");
更新。将 PixelFormat 更改为 8bppIndexed
。
FT_Bitmap *bitmap = &face->glyph->bitmap;
// stride must be aligned on a 32 bit boundary or 4 bytes
int depth = 8;
int stride = ((width * depth + 31) & ~31) >> 3;
int bytes = (int)(stride * height);
target = gcnew Bitmap(width, height, PixelFormat::Format8bppIndexed);
// create bitmap data, lock pixels to be written.
BitmapData^ bitmapData = target->LockBits(Rectangle(0, 0, width, height), ImageLockMode::WriteOnly, target->PixelFormat);
array<Byte>^ values = gcnew array<Byte>(bytes);
Marshal::Copy((IntPtr)bitmap->buffer, values, 0, bytes);
Marshal::Copy(values, 0, bitmapData->Scan0, bytes);
target->UnlockBits(bitmapData);
I'm trying to create a tool/asset converter that rasterises a font to a texture page for an XNA game using the FreeType2 engine.
Below, the first image is the direct output from the FreeType2]1 engine. The second image is the result after attempting to convert it to a System::Drawing::Bitmap
.
target http://www.freeimagehosting.net/uploads/fb102ee6da.jpg currentresult http://www.freeimagehosting.net/uploads/9ea77fa307.jpg
Any hints/tips/ideas on what is going on here would be greatly appreciated. Links to articles explaining byte layout and pixel formats would also be helpful.
FT_Bitmap *bitmap = &face->glyph->bitmap;
int width = (face->bitmap->metrics.width / 64);
int height = (face->bitmap->metrics.height / 64);
// must be aligned on a 32 bit boundary or 4 bytes
int depth = 8;
int stride = ((width * depth + 31) & ~31) >> 3;
int bytes = (int)(stride * height);
// as *.bmp
array<Byte>^ values = gcnew array<Byte>(bytes);
Marshal::Copy((IntPtr)glyph->buffer, values, 0, bytes);
Bitmap^ systemBitmap = gcnew Bitmap(width, height, PixelFormat::Format24bppRgb);
// create bitmap data, lock pixels to be written.
BitmapData^ bitmapData = systemBitmap->LockBits(Rectangle(0, 0, width, height), ImageLockMode::WriteOnly, bitmap->PixelFormat);
Marshal::Copy(values, 0, bitmapData->Scan0, bytes);
systemBitmap->UnlockBits(bitmapData);
systemBitmap->Save("Test.bmp");
Update. Changed PixelFormat to 8bppIndexed
.
FT_Bitmap *bitmap = &face->glyph->bitmap;
// stride must be aligned on a 32 bit boundary or 4 bytes
int depth = 8;
int stride = ((width * depth + 31) & ~31) >> 3;
int bytes = (int)(stride * height);
target = gcnew Bitmap(width, height, PixelFormat::Format8bppIndexed);
// create bitmap data, lock pixels to be written.
BitmapData^ bitmapData = target->LockBits(Rectangle(0, 0, width, height), ImageLockMode::WriteOnly, target->PixelFormat);
array<Byte>^ values = gcnew array<Byte>(bytes);
Marshal::Copy((IntPtr)bitmap->buffer, values, 0, bytes);
Marshal::Copy(values, 0, bitmapData->Scan0, bytes);
target->UnlockBits(bitmapData);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
啊哈。解决了。
FT_Bitmap
是 8 位图像,因此正确的PixelFormat
是8bppIndexed
,从而产生此输出。未与 32 字节边界对齐 http://www.freeimagehosting.net/uploads/dd90fa2252.jpg
System::Drawing::Bitmap
需要在 32 位边界上对齐。我正在计算步幅,但在写入位图时没有填充它。将
FT_Bitmap
缓冲区复制到byte[]
,然后将其写入MemoryStream
,添加必要的填充。固定内存,以便 GC 不会打扰它。
由于没有
Format8bppIndexed
灰色,图像仍然不正确。替代文本 http://www.freeimagehosting.net/uploads/8a883b7dce.png
然后将位图调色板更改为灰度 256。
替代文本 http://www.freeimagehosting.net/uploads /59a745269e.jpg
最终解决方案。
Ah ha. Worked it out.
FT_Bitmap
is an 8bit image, so the correctPixelFormat
was8bppIndexed
, which resulted this output.Not aligned to 32byte boundary http://www.freeimagehosting.net/uploads/dd90fa2252.jpg
System::Drawing::Bitmap
needs to be aligned on a 32 bit boundary.I was calculating the stride but was not padding it when writing the bitmap. Copied the
FT_Bitmap
buffer to abyte[]
and then wrote that to aMemoryStream
, adding the necessary padding.Pinned the memory so the GC would leave it alone.
As there is no
Format8bppIndexed
Grey the image was still not correct.alt text http://www.freeimagehosting.net/uploads/8a883b7dce.png
Then changed the bitmap palette to grey scale 256.
alt text http://www.freeimagehosting.net/uploads/59a745269e.jpg
Final solution.
您的“深度”值与位图的像素格式不匹配。它需要是 24 才能匹配 Format24bppRgb。位图的 PF 也需要与 FT_Bitmap 的 PF 和步幅相匹配,我不认为你关心这一点。
Your "depth" value doesn't match the PixelFormat of the Bitmap. It needs to be 24 to match Format24bppRgb. The PF for the bitmap needs to match the PF and stride of the FT_Bitmap as well, I don't see you take care of that.