GDI+绘制的字符串倒置

3
我是一名有用的助手,以下是你需要翻译的内容:

我正在尝试使用DirectShow向从USB摄像头获取的位图写入文本。 问题在于文本镜像翻转并倒置,我不知道为什么。

这是编写文本的代码:

BITMAPINFOHEADER bih = m_videoInfo.bmiHeader;
Bitmap bmp(bih.biWidth, bih.biHeight, m_stride, m_pixFmt, pBuffer);
Graphics g(&bmp);

    if (this->introTimer->timeToDo())
    {

        RectF pos(10, 10, 100, 100);
        SolidBrush brush(Color::Black);

        Font font(FontFamily::GenericSerif(), 30);

        hr = g.DrawString(this->introText, -1, &font, pos, StringFormat::GenericDefault(), &brush);
        return hr;

    }

我不确定我的代码是否是影响字符串绘制的唯一因素。也许有一些配置或其他东西。

更新 我尝试使用Hans Passant建议的负高度,结果是文本根本没有被写入。


2
倒置上下或左右翻转?倒置上下比较常见,位图通常以相反的扫描线存储。将高度设为负值即可。 - Hans Passant
它被倒置了。 - Luke
你有尝试从你得到的点中减去总高度吗? - sergiol
@sergiol,我不理解你的问题,也许你可以用一个公式来描述你的意思。 - Luke
你尝试将bih.biHeight设置为负数了吗? - Felipe Lavratti
2个回答

2

显而易见的做法是在GDI+上设置转换。

基本上,您需要反转Y轴(虽然这样做现在会绘制到屏幕之外)。因此,您需要将其向下平移窗口大小。

类似这样:

 graphics.Transform = new Matrix2D( 1, 0,
                                    0, -1,
                                    0, -windowHeight );

然后像平常一样进行绘制。

值得注意的是,我在没有测试的情况下建议这样做。y轴位移可能不是负值,所以请尝试两种方式!


1

扫描线是倒置存储的,图像中存储的第一次扫描(扫描0)在内存中是最底部的扫描。这是Presentation Manager兼容性的另一个副作用。GDI在Set和Get操作期间自动反转图像。

关于Hans Passant的建议,您尝试在位置中使用负高度了吗?他建议在bih中使用负高度。

BITMAPINFOHEADER bih = m_videoInfo.bmiHeader;
bih.biHeight = -bih.biHeight;
Bitmap bmp(bih.biWidth, bih.biHeight, m_stride, m_pixFmt, pBuffer);
...

如果可以的话,还可以从此页面复制另一个解决方案。

void BitmapControl::OnPaint()
{
EnterCriticalSection (&CriticalSection);

if (_handleBMP)
{

    CPaintDC dc(this);
    //dc.SetMapMode(MM_ISOTROPIC);
    dc.SetMapMode(MM_LOENGLISH);
    CDC dcMem;
    dcMem.CreateCompatibleDC(&dc);

    CRect rect;
    GetClientRect(&rect);
    dc.DPtoLP(&rect);

    CBitmap* pBmpOld = dcMem.SelectObject(CBitmap::FromHandle(_handleBMP));

    //tst
    dc.SetStretchBltMode(COLORONCOLOR);

    //BitBlt(dc,rect.left,-0,rect.Width(),rect.Height(),dcMem,rect.left,rect.top,SRCCOPY); //works with MM_TEXT but upsidedown
    BitBlt(dc,0,rect.bottom,rect.Width(),-rect.Height(),dcMem,0,0,SRCCOPY); //works with MM_LOENGLISH
    dcMem.SelectObject(pBmpOld);
    DeleteDC(dc);
    DeleteDC(dcMem);
    DeleteObject(_handleBMP);
    DeleteObject(pBmpOld);
    _handleBMP = NULL;

}
LeaveCriticalSection (&CriticalSection);
}

在我的情况下,使用负高度的结果是根本没有打印文本。 - Luke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接