• 20612阅读
  • 26回复

『结贴』背景是图片时,对前面的小透明图片设置alpha通道值? [复制链接]

上一主题 下一主题
离线kingnight
 
只看楼主 正序阅读 楼主  发表于: 2009-11-10
版主救救!背景是图片时,对前面的小透明图片设置alpha通道值,效果是要透出背景图片,而不能被变换后的前面小图遮住
有透明度的png图片
我的目的就是对图片能做透明度的变化,同时还能衬托出背景色!
[ 此帖被kingnight在2009-11-19 19:38重新编辑 ]
离线uihjk999
只看该作者 26楼 发表于: 2011-01-04
好帖,正在学透明处理,标记之
离线f23505106
只看该作者 25楼 发表于: 2010-04-10
是不是背景图片放在Qwidget上,前景使用了QWidget上的Qlabel,这样两个图层一个是widget一个是qlael
离线f23505106
只看该作者 24楼 发表于: 2010-04-09
我也正用到这方面的内容,感谢各位提供的知识
有一个地方没看懂
QPainter painter(this);
this这里把背景图画到哪里了?是ui->label么?
离线kingnight
只看该作者 23楼 发表于: 2009-11-19
果然正解!!!!!!!!超级感谢!!!!!结贴!!!!!!!!
离线jiulai
只看该作者 22楼 发表于: 2009-11-19
离线yb824
只看该作者 21楼 发表于: 2009-11-18
//试下就知道行不行了贝
//---画背景
QPixmap pixmapBg(":bg.jpg");
    QPainter painter(this);
    painter.drawPixmap(0, 0, pixmapBg);

    QPixmap pixmapTop(":top.jpg");
    int alpha = 125;
//---前景图片透明度处理
    QPixmap temp(pixmapTop.size());
    temp.fill(Qt::transparent);
    QPainter p(&temp);
    p.setCompositionMode(QPainter::CompositionMode_Source);
    p.drawPixmap(0, 0, pixmapTop);
    p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
    p.fillRect(temp.rect(), QColor(0, 0, 0, alpha));
//--lable显示前景图片
    ui->label->setScaledContents(true);
    ui->label->setPixmap(temp);
离线kingnight
只看该作者 20楼 发表于: 2009-11-18
引用第19楼yb824于2009-11-16 19:38发表的  :
    试这个
    QPixmap pixmapBg(":bg.jpg");
    QPainter painter(this);
    painter.drawPixmap(0, 0, pixmapBg);
.......


抱歉,没试就发表意见,不过我看代码看不出什么改变,麻烦请yb824 详细解释下,这个为什么能达到效果,好像也不行吧
离线yb824
只看该作者 19楼 发表于: 2009-11-16
    试这个
    QPixmap pixmapBg(":bg.jpg");
    QPainter painter(this);
    painter.drawPixmap(0, 0, pixmapBg);

    QPixmap pixmapTop(":top.jpg");
    int alpha = 125;

    QPixmap temp(pixmapTop.size());
    temp.fill(Qt::transparent);
    QPainter p(&temp);
    p.setCompositionMode(QPainter::CompositionMode_Source);
    p.drawPixmap(0, 0, pixmapTop);
    p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
    p.fillRect(temp.rect(), QColor(0, 0, 0, alpha));

    ui->label->setScaledContents(true);
    ui->label->setPixmap(temp);
离线kingnight
只看该作者 18楼 发表于: 2009-11-16
引用第17楼jiulai于2009-11-16 17:19发表的  :
m_background就是A,m_foreground就是B。要调B的位置就改变倒数第四行的QRect。
void Widget::slotChangeTransparency(int trans)
{
    m_mergeImage = QImage(m_background.width(), m_background.height(), QImage::Format_ARGB32);
    QPainter painter(&m_mergeImage);
.......


谢谢,你这个类似像素遍历的方法我试过,即使成功了也不好用,因为消耗cpu资源很大,多张图片一起动画在板子上会很卡,希望高手指教有改进的办法!
离线jiulai
只看该作者 17楼 发表于: 2009-11-16
m_background就是A,m_foreground就是B。要调B的位置就改变倒数第四行的QRect。
void Widget::slotChangeTransparency(int trans)
{
    m_mergeImage = QImage(m_background.width(), m_background.height(), QImage::Format_ARGB32);
    QPainter painter(&m_mergeImage);
    painter.setCompositionMode(QPainter::CompositionMode_Source);
    painter.drawImage(0, 0, m_background);

    QImage foregroundWithTranspareny = m_foreground;

    int width = foregroundWithTranspareny.width();
    int height = foregroundWithTranspareny.height();
    uchar *bits = foregroundWithTranspareny.bits();
    uchar *line = bits + 3, *pixel;
    for (int y = 0; y < height; y++) {
        pixel = line;
        for (int x = 0; x < width; x++) {
            if (*pixel != 0) {
                *pixel = trans;
            }
            pixel += 4;
        }
        line += foregroundWithTranspareny.bytesPerLine();
    }
    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
    painter.drawImage(QRect(0, 0, width, height), foregroundWithTranspareny);
    painter.end();
    m_label->setPixmap(QPixmap::fromImage(m_mergeImage));
}
当B不带透明度的时候,不行,郁闷。那位高手指教一下啊。
离线kingnight
只看该作者 16楼 发表于: 2009-11-16
    QPainter painter(&pixmapBg);
    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
    painter.drawPixmap(0, 0, pixmapTop);

这句paint的位置是paint开始的(0,0)位置,不是整个画布的(0,0),如果B在A的中间位置,画完之后B的背景就变成A的左上角开始的背景了,不是B中间位置后面对应的A的背景,所以我觉得还是不行呀!!!!!!

非常感谢各位的意见!!!有好办法告诉我
离线yb824
只看该作者 15楼 发表于: 2009-11-16
试一下
    QPixmap pixmapBg(":image/bg.png");
    QPixmap pixmapTop(":image/top.png");
    int alpha = 125;

    QPainter p(&pixmapTop);
    p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
    p.fillRect(rect(), QColor(0, 0, 0, alpha));

    QPainter painter(&pixmapBg);
    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
    painter.drawPixmap(0, 0, pixmapTop);

    ui->label->setPixmap(pixmapBg);
离线kingnight
只看该作者 14楼 发表于: 2009-11-16
大家再给点意见呀?
离线kingnight
只看该作者 13楼 发表于: 2009-11-15
帖子顶上去!!!!!!!!!!!!!
离线kingnight
只看该作者 12楼 发表于: 2009-11-14
版主救救!背景是图片时,对前面的小透明图片设置alpha通道值?
引用第11楼jiulai于2009-11-13 16:20发表的  :
那你就把第七行改为p.drawImage(image);  其中image是你的带alpha的图片。
你现在要混合两个图,dest和source。你先把dest画在画布上,设一下CompositionMode,再画上source。
QPainter里面有很多中CompositionMode, 常用的有,CompositionMode_SourceOver的意思是按source的alpha混合, QPainter::CompositionMode_DestinationOver是按dest的alpha混合,QPainter::CompositionMode_Source是source把dest完全遮住。


感谢jiulai,您说的这种方法是对于两张图片大小相同条件件下有效吧?
我这意思是有个大背景A,前面有个有小控件B,最好能只对图片B做透明度变换,同时还能时刻透出后面A,如附件
离线jiulai
只看该作者 11楼 发表于: 2009-11-13
那你就把第七行改为p.drawImage(image);  其中image是你的带alpha的图片。

你现在要混合两个图,dest和source。你先把dest画在画布上,设一下CompositionMode,再画上source。
QPainter里面有很多中CompositionMode, 常用的有,CompositionMode_SourceOver的意思是按source的alpha混合, QPainter::CompositionMode_DestinationOver是按dest的alpha混合,QPainter::CompositionMode_Source是source把dest完全遮住。
离线kingnight
只看该作者 10楼 发表于: 2009-11-13
帖子顶上去,高手给点意见呀!!!!!!!!!!!!!
离线kingnight
只看该作者 9楼 发表于: 2009-11-13
引用第8楼jiulai于2009-11-13 09:28发表的  :
不好意思,上面第二句错了,
应该改第七行p.fillRect(temp.rect(), QColor(0, 0, 0, opacity));颜色。


请教jiulai,我的背景不是纯的颜色,而是一幅图片,你说的方法是对一个QColor有效吧??
离线jiulai
只看该作者 8楼 发表于: 2009-11-13
不好意思,上面第二句错了,
应该改第七行p.fillRect(temp.rect(), QColor(0, 0, 0, opacity));颜色。
离线jiulai
只看该作者 7楼 发表于: 2009-11-13
把四楼的QPainter::CompositionMode_DestinationIn换成QPainter::CompositionMode_SourceOver就可以了。
要设背景就改四楼第二行temp.fill(Qt::transparent)成背景色。
离线kingnight
只看该作者 6楼 发表于: 2009-11-12
没解决呀,我也急呢
离线yxhappy
只看该作者 5楼 发表于: 2009-11-12
请问楼主问题解决没?我也想知道呢,分享下呀。
离线kingnight
只看该作者 4楼 发表于: 2009-11-11
非常感谢4楼,我试过了,代码如下,没看到预期的效果,哪位还有其他办法????????????
PicTrans::PicTrans(QWidget *parent,const char *  name)
    : QWidget(parent)
{
    pixmap=QPixmap(QString::fromUtf8(name));

    bglabel=new QLabel(this);
    bglabel->setAutoFillBackground (true);
    bglabel->setScaledContents(true);

    QPalette palette ;
    palette.setBrush(QPalette::Background,QBrush(QPixmap(pixmap)));
    palette.setColor(QPalette::WindowText,Qt::white);
     bglabel->setPalette(palette);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(bglabel);
    setLayout(layout);
}


void PicTrans::paintEvent(QPaintEvent * e)
{
    QPixmap temp(pixmap.size());
    temp.fill(Qt::transparent);
    QPainter p(&temp);
    p.setCompositionMode(QPainter::CompositionMode_Source);
    p.drawPixmap(0,0,pixmap);
    p.setCompositionMode(QPainter::CompositionMode_Destination);
    p.fillRect(temp.rect(),QColor(0,0,0,opacity));
    p.end();
    pixmap=temp;

    QPalette palette ;
    palette.setBrush(QPalette::Background,QBrush(QPixmap(pixmap)));
    bglabel->setPalette(palette);
}

void PicTrans::SetTransValue(int value)
{
    if(value>=0&&value<=255)
            opacity=value;
    repaint();
}
离线yb824
只看该作者 3楼 发表于: 2009-11-11
    QPixmap temp(pixmap.size());
    temp.fill(Qt::transparent);
    QPainter p(&temp);
    p.setCompositionMode(QPainter::CompositionMode_Source);
    p.drawPixmap(0, 0, pixmap);
    p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
    p.fillRect(temp.rect(), QColor(0, 0, 0, opacity));
    p.end();
    pixmap = temp;
离线kingnight
只看该作者 2楼 发表于: 2009-11-11
各位高手给点意见呀,版主救救呀!!!!!!!!!!!!!!!
离线午小夜

只看该作者 1楼 发表于: 2009-11-10
QWidget::setWindowOpacity? i'm not sure.
[操作系统版本]  Windows XP;Linux Ubuntu;Linux Fedora;
[Qt SDK版本]    4.7.0
[SDK 发布日期]  2010.05
[IDE(集成开发环境)] QtCreator
个人网页:http://hi.baidu.com/午小夜
學歷:Royal Jalidon
快速回复
限100 字节
 
上一个 下一个