繁体   English   中英

如何使用Alpha通道将图像绘制到TSpeedButton?

[英]How do I draw an image with an alpha channel to a TSpeedButton?

我有一个TSpeedButton和一个包含各种字形的TImageList 其中一个有一个alpha通道,当它被绘制到UI的某些部分时看起来非常好......但是当在TSpeedButton上绘制该字形时,它不会使alpha通道生效。

查看TButtonGlyph.DrawButtonGlyph中的相关代码,它对Transparent参数传递为true ,但在if FThemesEnabled代码路径中根本不考虑Transparent ; 它只在else部分引用。 由于该程序启用了主题,这是否意味着无法将α混合图像绘制到TSpeedButton

有什么方法可以解决这个问题吗?

编辑:更仔细地看一下,它似乎需要考虑透明度......有点儿。 完全透明的像素根本不会被绘制,这是正确的行为。 但是边缘周围的抗锯齿(部分透明)被绘制为完全不透明。

从我所看到的, TSpeedButton获取您的位图并将其添加到图像列表中。 这是FGlyphList私有部分中的TButtonGlyph 该图像列表具有ColorDepthcdDeviceDependent 如果您希望尊重alpha透明度,则需要该图像列表具有ColorDepthcd32Bit 所以就在那里解释了这些文物。

我不确定你是如何解决这个问题的。 我认为我个人将TButtonGlyph子类TButtonGlyph并将其直接连接到您选择的图像列表。 然后使用从图像列表中绘制的代码替换TButtonGlyph.DrawButtonGlyph 我相信你能够编制代码。

但是没有简单的解决方法。 如果没有对VCL进行重大修改,该图像列表将使用cdDeviceDependent并且没有简单的方法可以更改它。 我看不到明显的快速解决方案。

实际上,我会做的就是使用TButton ,但那只是我。


关于速度按钮的Transparent属性, 文档说:

指定按钮的背景是否透明。

使用“透明”指定按钮的背景是否透明。

仅当TSpeedButton的Flat属性设置为True时,此属性才有效。

启用Windows主题时,“透明”属性无法使按钮背景透明。

也就是说,该属性会影响按钮背景,对于平面按钮,未经训练时,与绘制字形无关。

为了充分披露:我遇到了类似的问题,并使用此问答来建立我的初始解决方案。 由于我需要快速修复我的应用程序和编译器(我使用C ++ Builder 2009),我决定'破解'VCL的私有成员并将GlyphlistColorDepth设置为cd32Bit ,直到我有时间处理更永久的事情。 这个hack工作了,但有一些更改,但远非理想,出于所有明显的原因,但功能明智,还有一些问题需要考虑。

然而,在这样做的同时,我进一步尝试并最终到达下面,工作解决方案,没有任何需要的肮脏技巧。 对VCL的内部运作并不熟悉,而不是“VCL中更深入的人的反馈”,我现在对于我所缺少的东西有点不确定! 因为以下解决方案适合我。 在XP,XP-高对比度,W7和W10上确认。 字形在W2K上看起来不太好但是对于主菜单和弹出图标也是如此,所以就是这样。

我用C ++编写代码但使用相同的底层VCL,所以我将在这里发布我的C ++解决方案,作为Delphi问题的答案。 我希望这是好的,为了提供解决方案的途径而不是保持自己。 Delphi大师可以转换和发布作为答案,除非我遗漏了一些东西,我的解决方案不是一直需要的。

自从我开始使用'hack'方法后,我TSpeedButtonTSpeedButton子类TSpeedButton并将代码放在MyTSpeedButton函数中,但这并不需要这样做。 但是,这是我发布的代码:

class MyVCLTSpeedButton : public TSpeedButton
    {
    public:

    __fastcall MyVCLTSpeedButton(Classes::TComponent* AOwner) ;

    void __fastcall AddGlyphWithAlphaChannel(Imglist::TCustomImageList* ImageList, int UpIndex, int DisabledIndex = -1, int ClickedIndex = -1, int DownIndex = -1) ;

    };

CPP

void __fastcall MyVCLTSpeedButton::AddGlyphWithAlphaChannel(Imglist::TCustomImageList* ImageList, int UpIndex, int DisabledIndex, int ClickedIndex, int DownIndex)
{
Glyph->Assign(NULL) ; // Clear the current bitmap 

NumGlyphs = (DisabledIndex > -1)?((ClickedIndex > -1)?((DownIndex > -1)?(4):(3)):(2)):(1) ;

Graphics::TBitmap *BitMap = new Graphics::TBitmap ;

//BitMap->AlphaFormat = afDefined ; // Don't Change AlphaFormat, it will negatively affect rendering !
BitMap->PixelFormat = pf32bit ;   // Doesn't seem to be that important
BitMap->Height = ImageList->Height ;
BitMap->Width  = (ImageList->Width * NumGlyphs) ;

BitMap->Canvas->Brush->Color = Parent->Brush->Color ;
BitMap->Canvas->Brush->Style = bsSolid ;
BitMap->Canvas->FillRect(BitMap->Canvas->ClipRect) ;

TIcon *Icon = new TIcon() ;

for (int x = 0 ; x < NumGlyphs ; x++)
    {
    ImageList->GetIcon((x == 0)?(UpIndex):((x == 1)?(DisabledIndex):((x == 2)?(ClickedIndex):(DownIndex))), Icon) ;
    BitMap->Canvas->Draw((ImageList->Width * x), 0, Icon) ;
    }

Glyph->Assign(BitMap) ;

delete Icon ;
delete BitMap ;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM