【问题标题】:Transparency on white background bitmap C++ winapi白色背景位图C ++ winapi上的透明度
【发布时间】:2011-09-28 23:45:23
【问题描述】:

嗯,我有一个关于我想保存为 png 文件的位图文件的透明度的问题,目前我在系统中截取光标并将其保存为 png,这项工作很好,白色箭头,手和其他光标,但在使用 I 型光标或“非”光标之类的光标时会出现问题,解释是每个光标都有一个遮罩和一个颜色位图,它们组合并产生透明光标,但 I 型光标和其他光标没有颜色位图,他们只有在同一个位图中包含颜色和遮罩的遮罩,我参考这篇文章:C# - Capturing the Mouse cursor image 他们使用 C#,但想法是一样的。

在我的代码中,我使用 C++,我设法创建了一个光标,但背景颜色为白色,我不知道如何将其转换为透明颜色,在帖子中我提到使用函数 MakeTransparent,有什么想法吗?感谢您的帮助:D

    CURSORINFO cursor;
    ICONINFO cursorIconInfo;
    HICON cursorIcon;
    cursor.cbSize=sizeof(CURSORINFO);
    GetCursorInfo(&cursor);
    GetIconInfo(cursor.hCursor,&cursorIconInfo);
    //cursorIcon=CopyIcon(cursor.hCursor);
    //GetIconInfo(LoadCursor(NULL,IDC_ARROW),&cursorIconInfo);
    //cursorIcon=CreateIconIndirect(&cursorIconInfo);

    CxImage* imag=new CxImage();
    /*imag->CreateFromHICON(cursorIcon);
    imag->Save("cursor.png",CXIMAGE_FORMAT_PNG);*/
    BITMAP bm;
    //CImage* imag=new CImage();
    GetObject(cursorIconInfo.hbmMask,sizeof(BITMAP),&bm);
    if(bm.bmHeight == bm.bmWidth*2){
        HDC screendc=CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
        HDC cursormaskDC=CreateCompatibleDC(screendc);
        HDC cursorfinalDC=CreateCompatibleDC(screendc);

        HBITMAP cursormask=CreateCompatibleBitmap(screendc,bm.bmWidth,bm.bmWidth);
        HBITMAP cursorfinal=CreateCompatibleBitmap(screendc,bm.bmWidth,bm.bmWidth);

        SelectObject(cursormaskDC,cursorIconInfo.hbmMask);
        SelectObject(cursorfinalDC,cursorfinal);

        BitBlt(cursorfinalDC,0,0,bm.bmWidth,bm.bmWidth,cursormaskDC,0,bm.bmWidth,SRCCOPY); 
        BitBlt(cursorfinalDC,0,0,bm.bmWidth,bm.bmWidth,cursormaskDC,0,0,SRCINVERT);

        /*cursorIconInfo.hbmColor=cursorcolor;
        cursorIconInfo.hbmMask=cursormask;
        cursorIcon=CreateIconIndirect(&cursorIconInfo);
        imag->CreateFromHICON(cursorIcon);
        imag->Save("cursorPrub.png",CXIMAGE_FORMAT_PNG);*/
        imag->CreateFromHBITMAP(cursorfinal);

        imag->Save("cursor.png",CXIMAGE_FORMAT_PNG);
        DeleteObject(cursorIconInfo.hbmMask);
        DeleteObject(cursorIconInfo.hbmColor);
        DestroyIcon(cursorIcon);

        imag->Destroy();
        return;
    }

【问题讨论】:

  • 不,这个想法肯定相同。您尝试复制的 C# 代码是使用 .NET Framework 编写的,该框架不仅封装了 GDI+,还为程序员提供了大量方便、可重用的代码库。当您编写本机、非托管 C++ 时,您必须自己完成所有工作,因为这些库还没有为您编写。您不能简单地将 C# 代码翻译成 C++ 代码,但这不是语言问题,而是库问题。 MakeTransparent() 函数将无处可寻。
  • 感谢科迪,我对此进行了调查,您是对的,但是我如何将具有白色背景的位图转换为透明位图?,我使用建议的 BitBlt,并使用 SRCAND 和 SRCPAINT 来做工作,但不工作,我得到一个黑色图像或白色图像,我不知道如何使用工字梁遮罩来创建透明度:/

标签: c++ visual-c++ bitmap transparency


【解决方案1】:

使用 GDIPlus。它适用于 alpha。有时 Gdi 与 alpha 一起工作不正确。

【讨论】:

  • 您好,谢谢,我没有使用 gdi,我使用包含 jpeglib 的 CxImage 非常好且简单,但问题不在于库,而更多来自逻辑我猜,在我提到的帖子中,他们使用了函数 MakeTransparent (C#) 简单但在 C++ 中此函数不存在
  • 这个答案不是很有用。它没有解释 如何 提问者应该从 C++ 应用程序中使用 GDI+。而且它也很模糊:“Gdi 有时与 alpha 一起工作不正确”。不,它没有。它完全按照设计工作。没有什么是随机的,它不会只是偶尔发生。更有用的是解释 GDI 的局限性并将它们与 GDI+ 进行比较。
  • 我的意思是,什么 GDI+ 支持 alpha 混合。 “首先,GDI+ 通过提供新功能扩展了 GDI 的功能,例如渐变画笔和 alpha 混合。” (msdn.microsoft.com/en-us/library/ms536338(VS.85).aspx)。抱歉,我没有使用 GDI+ 的示例,但 Internet 包含许多示例。我认为不好的答案总比没有好。
  • 是的,注意我没有说你是,我说答案不是很有用。合并到 MSDN 的链接将是改善您的答案的良好开端。正如解释缺少的链接是 alpha 混合一样。 GDI 仅支持一种非常原始的透明度形式,其中一种颜色在整个图像中被替换为透明颜色。它没有任何 Alpha 通道。但是,您的回答并不能解释所有这些。它不会告诉对 GDI+ 或 alpha 通道一无所知的人他们需要知道的任何事情。
猜你喜欢
  • 2014-08-21
  • 2012-08-07
  • 2013-12-15
  • 2013-04-03
  • 2021-10-26
  • 1970-01-01
  • 1970-01-01
  • 2013-11-27
  • 2018-04-24
相关资源
最近更新 更多