繁体   English   中英

c#在新图像中合并具有背景色的半透明图像

[英]c# Merge semi transparent image with a background color in a new image

我需要基于纯色(背景)和半透明图像的合并生成一个新图像。 所有图像都是半透明的,因此都将与纯色融合。

我试过了:

 private Image BlendImageWithWindowBackgoundColor(Image pImage, float pColorOpacity)
    {
        Image mResult = null;
        if (pImage != null)
        {
            ColorMatrix matrix = new ColorMatrix(new float[][]{
            new float[] {1F, 0, 0, 0, 0},
            new float[] {0, 1F, 0, 0, 0},
            new float[] {0, 0, 1F, 0, 0},
            new float[] {0, 0, 0, pColorOpacity, 0}, //opacity in rage [0 1]
            new float[] {0, 0, 0, 0, 1F}});

            ImageAttributes imageAttributes = new ImageAttributes();
            imageAttributes.SetColorMatrix(matrix);
            imageAttributes.SetWrapMode(WrapMode.TileFlipXY);

            mResult = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
            Graphics g = Graphics.FromImage(mResult);

            g.Clear(Color.Red); //<--This is the color i want merged as background!
            g.CompositingMode = CompositingMode.SourceCopy;
            g.CompositingQuality = CompositingQuality.HighQuality;

            g.DrawImage(pImage, new Rectangle(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height), 0, 0, pImage.Width, pImage.Height, GraphicsUnit.Pixel, imageAttributes);
        }

        return mResult;

    }

如果我尝试pOpacity 0.5无法看到红色,则pOpacity为0时它将返回黑色。

即使我尝试使用g.CompositingMode = CompositingMode.SourceOver,它也只会生成半透明的图像,而忽略红色背景。

如果要平铺图像,则需要使用TextureBrushGraphics.FillRectangle而不是Drawimage 您的代码应为:

private void BlendImageWithWindowBackgoundColor( Image pImage, float pColorOpacity ) {
    Image mResult = null;
    Image tempImage = null; //we will set the opacity of pImage to pColorOpacity and copy
                            //it to tempImage 
    if( pImage != null ) {
        Graphics g;

        ColorMatrix matrix = new ColorMatrix( new float[][]{
                new float[] {1F, 0, 0, 0, 0},
                new float[] {0, 1F, 0, 0, 0},
                new float[] {0, 0, 1F, 0, 0},
                new float[] {0, 0, 0, pColorOpacity, 0}, //opacity in rage [0 1]
                new float[] {0, 0, 0, 0, 1F}} );

        ImageAttributes imageAttributes = new ImageAttributes();
        imageAttributes.SetColorMatrix( matrix );

        tempImage = new Bitmap( pImage.Width, pImage.Height, PixelFormat.Format32bppArgb );

        g = Graphics.FromImage( tempImage );
        g.Clear( Color.Transparent );
        //setting pColorOpacity to pImage and drawing to tempImage 
        g.DrawImage( pImage, new Rectangle( 0, 0, tempImage.Width, tempImage.Height ), 
                     0, 0, pImage.Width, pImage.Height, GraphicsUnit.Pixel, imageAttributes );

        g.Dispose();
        g = null;

        //now we will tile the tempImage
        TextureBrush texture = new TextureBrush( tempImage );
        texture.WrapMode = WrapMode.TileFlipXY;

        mResult = new Bitmap( Screen.PrimaryScreen.Bounds.Width,
                              Screen.PrimaryScreen.Bounds.Height,
                              PixelFormat.Format32bppArgb );

        g = Graphics.FromImage( mResult );
        g.Clear( Color.Red ); //<--This is the color i want merged as background!

        g.FillRectangle( texture, new Rectangle( 0, 0, mResult.Width, mResult.Height ) );

        g.Dispose();
        g = null;

        tempImage.Dispose();
        tempImage = null;

    }

    return mResult;

}

同时我找到了一个解决方案:

 private Image BlendImageWithWindowBackgoundColorToSize(Image pImage, float pColorOpacity)
    {
        Image mResult = null;
        if (pImage != null)
        {
            ColorMatrix matrix = new ColorMatrix(new float[][]{
            new float[] {1F, 0, 0, 0, 0},
            new float[] {0, 1F, 0, 0, 0},
            new float[] {0, 0, 1F, 0, 0},
            new float[] {0, 0, 0, pColorOpacity, 0}, //opacity in rage [0 1]
            new float[] {0, 0, 0, 0, 1F}});

            ImageAttributes imageAttributes = new ImageAttributes();
            imageAttributes.SetColorMatrix(matrix);
            imageAttributes.SetWrapMode(WrapMode.TileFlipXY);

            mResult = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);

            Image mImgSemiTransparent = (Image)mResult.Clone();
            Graphics g = Graphics.FromImage(mImgSemiTransparent);
            g.CompositingMode = CompositingMode.SourceOver; 
            g.CompositingQuality = CompositingQuality.HighQuality;           
            g.DrawImage(pImage, new Rectangle(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height), 0, 0, pImage.Width, pImage.Height, GraphicsUnit.Pixel, imageAttributes);

            Graphics gF = Graphics.FromImage(mResult);
            gF.Clear(Color.Red);
            gF.DrawImageUnscaled(mImgSemiTransparent, 0, 0, mImgSemiTransparent.Width, mImgSemiTransparent.Height);
        }

        return mResult;
    }

但是,用几颗柚木(不是我真正想要的)回答γηράσκωδ'αείπολλάδιδασσκόμε的人比我快四倍! :)

        private Image BlendImageWithWindowBackgoundColorToSize2(Image pImage, float pColorOpacity)
    {
        Image mResult = null;
        Image tempImage = null; //we will set the opacity of pImage to pColorOpacity and copy
                                //it to tempImage 
        if (pImage != null)
        {
            Graphics g;

            ColorMatrix matrix = new ColorMatrix(new float[][]{
            new float[] {1F, 0, 0, 0, 0},
            new float[] {0, 1F, 0, 0, 0},
            new float[] {0, 0, 1F, 0, 0},
            new float[] {0, 0, 0, pColorOpacity, 0}, //opacity in rage [0 1]
            new float[] {0, 0, 0, 0, 1F}});

            ImageAttributes imageAttributes = new ImageAttributes();
            imageAttributes.SetColorMatrix(matrix);
            imageAttributes.SetWrapMode(WrapMode.TileFlipXY);
            tempImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);

            g = Graphics.FromImage(tempImage);
            //g.Clear(Color.Transparent); //No need!
            //setting pColorOpacity to pImage and drawing to tempImage 
            g.DrawImage(pImage, new Rectangle(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height), 0, 0, pImage.Width, pImage.Height, GraphicsUnit.Pixel, imageAttributes);

            g.Dispose();
            g = null;

            //now we will tile the tempImage
            TextureBrush texture = new TextureBrush(tempImage);

            mResult = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                                  Screen.PrimaryScreen.Bounds.Height,
                                  PixelFormat.Format32bppArgb);

            g = Graphics.FromImage(mResult);
            g.Clear(myColor);

            g.FillRectangle(texture, new Rectangle(0, 0, mResult.Width, mResult.Height));

            g.Dispose();
            g = null;

            tempImage.Dispose();
            tempImage = null;

        }

        return mResult;

    }

暂无
暂无

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

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