gpt4 book ai didi

visual-c++ - unsigned char* 缓冲区到 System::Drawing::Bitmap

转载 作者:行者123 更新时间:2023-12-04 06:45:46 26 4
gpt4 key购买 nike

我正在尝试创建一个工具/ Assets 转换器,使用 FreeType2 将字体光栅化为 XNA 游戏的纹理页面。引擎。

下面,第一张图片是 FreeType2 的直接输出] 1引擎。第二个图像是尝试将其转换为 System::Drawing::Bitmap 后的结果.

target http://www.freeimagehosting.net/uploads/fb102ee6da.jpg currentresult 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);

最佳答案

啊哈。解决了。
FT_Bitmap是 8 位图像,所以正确的 PixelFormat8bppIndexed ,这导致了这个输出。
Not aligned to 32byte boundary http://www.freeimagehosting.net/uploads/dd90fa2252.jpg
System::Drawing::Bitmap需要在 32 位边界上对齐。

我正在计算步幅,但在编写位图时没有填充它。已复制 FT_Bitmap缓冲到 byte[]然后将其写入 MemoryStream ,添加必要的填充。

  int stride = ((width * pixelDepth + 31) & ~31) >> 3;
int padding = stride - (((width * pixelDepth) + 7) / 8);

array<Byte>^ pad = gcnew array<Byte>(padding);
array<Byte>^ buffer = gcnew array<Byte>(size);
Marshal::Copy((IntPtr)source->buffer, buffer, 0, size);

MemoryStream^ ms = gcnew MemoryStream();

for (int i = 0; i < height; ++i)
{
ms->Write(buffer, i * width, width);
ms->Write(pad, 0, padding);
}

固定内存,以便 GC 不理会它。
  // pin memory and create bitmap
GCHandle handle = GCHandle::Alloc(ms->ToArray(), GCHandleType::Pinned);
target = gcnew Bitmap(width, height, stride, PixelFormat::Format8bppIndexed, handle.AddrOfPinnedObject());
ms->Close();

因为没有 Format8bppIndexed灰色图像仍然不正确。

alt text http://www.freeimagehosting.net/uploads/8a883b7dce.png

然后将位图调色板更改为灰度 256。
  // 256-level greyscale palette
ColorPalette^ palette = target->Palette;
for (int i = 0; i < palette->Entries->Length; ++i)
palette->Entries[i] = Color::FromArgb(i,i,i);

target->Palette = palette;

alt text http://www.freeimagehosting.net/uploads/59a745269e.jpg

最终解决方案。
  error = FT_Load_Char(face, ch, FT_LOAD_RENDER);
if (error)
throw gcnew InvalidOperationException("Failed to load and render character");

FT_Bitmap *source = &face->glyph->bitmap;

int width = (face->glyph->metrics.width / 64);
int height = (face->glyph->metrics.height / 64);
int pixelDepth = 8;
int size = width * height;

// stride must be aligned on a 32 bit boundary or 4 bytes
// padding is the number of bytes to add to make each row a 32bit aligned row
int stride = ((width * pixelDepth + 31) & ~31) >> 3;
int padding = stride - (((width * pixelDepth) + 7) / 8);

array<Byte>^ pad = gcnew array<Byte>(padding);
array<Byte>^ buffer = gcnew array<Byte>(size);
Marshal::Copy((IntPtr)source->buffer, buffer, 0, size);

MemoryStream^ ms = gcnew MemoryStream();

for (int i = 0; i < height; ++i)
{
ms->Write(buffer, i * width, width);
ms->Write(pad, 0, padding);
}

// pin memory and create bitmap
GCHandle handle = GCHandle::Alloc(ms->ToArray(), GCHandleType::Pinned);
target = gcnew Bitmap(width, height, stride, PixelFormat::Format8bppIndexed, handle.AddrOfPinnedObject());
ms->Close();

// 256-level greyscale palette
ColorPalette^ palette = target->Palette;
for (int i = 0; i < palette->Entries->Length; ++i)
palette->Entries[i] = Color::FromArgb(i,i,i);

target->Palette = palette;

FT_Done_FreeType(library);

关于visual-c++ - unsigned char* 缓冲区到 System::Drawing::Bitmap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2750342/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com