[PPTX analysis] image effect algorithm: set transparent color

Keywords: C# Algorithm ppt

PPTX resolution: set transparent color

In PPT, we can set the specified color to be transparent through the picture format options - > Color - > set transparent color, so as to realize the need to remove the solid color background.

Effect principle

The logic of setting transparent color in PPT is very simple and clear:

·Replace color A with color B

When color B is a transparent color, the requirement of setting a color as a transparent color can be met.

Resolve color substitution node (OpenXml)

First, let's look at the xml node where PPT stores transparent colors:

<p:pic>
	......
	<p:blipFill>
		<a:blip ......>
			<a:clrChange>
				<a:clrFrom>
					<a:srgbClr val="FFAAFF" >
						<a:alpha val="100000" />
					</a:srgbClr>
				</a:clrFrom>
				<a:clrTo>
					<a:srgbClr val="FFAAFF">
						<a:alpha val="0" />
					</a:srgbClr>
				</a:clrTo>
			</a:clrChange>
		</a:blip>
		......
	</p:blipFill>
	......
</p:pic>

Node attribute resolution:

Node namemeaningValue meaning
p:picpictureThis element specifies the existence of a picture object in the document
p:blipFillPicture fillThis element specifies that the picture object has the type of picture fill
a:blipBlipThe image specified by this element (binary large image or picture) exists and contains a reference to image data
a:clrChangeDiscoloration effectThis element specifies the color change effect. Replace the instance of clrFrom with the instance of clrTo.
a:clrFromChange Color FromThis element specifies the color to be removed in the color change effect. It is the "from" or source input color.
a:clrToChange Color ToThis element specifies the color to replace clrFrom in the clrChange effect. This is the target or target color in the color change effect.

Alpha channel resolution of color

There is an attribute value val in the node * * < A: srgbclr / > * * which represents the hexadecimal representation of the RGB channel of the color.

There is an attribute value val in the child node * * < A: Alpha / > * * which represents the thousandfold percentage of the Alpha channel of the color (for example, 100000 actual value represents 100%).

Note: when the val value in node * * < A: Alpha / > is 100000, this node can be omitted. That is, when there is no child node < A: Alpha / > * * in the node < A: srgbclr / >, the percentage of Alpha channels representing the color is 100% (255).

In this case, we resolved to replace the color #FFAAFF in the picture with the color #00FFAAFF.

Effect realization (C#)

You can refer to the following code to replace the color of the specified Bitmap:

/// <summary>
///Replace the color < paramref name = "colora" / > specified on the picture < paramref name = "bitmap" / > with the color < paramref name = "colorb" / >
/// </summary>
///< param name = "bitmap" > picture < / param >
///< param name = "colora" > color to be replaced < / param >
///< param name = "colorb" > replace < paramref name = "colora" / > with the color < / param >
public void ReplaceColor(Bitmap bitmap, System.Drawing.Color colorA, System.Drawing.Color colorB)
{
    //Here is to traverse every pixel in the picture
    bitmap.PerPixelProcess(color =>
    {
        //Replace if the current color is similar to colorA
        var isSimilar = IsSimilarColors(color, colorA);
        return isSimilar ? colorB : color;
    });
}

/// <summary>
///Is it an approximate color
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
///< param name = "accuracy" > allowable error of RGB channel < / param >
/// <returns></returns>
private bool IsSimilarColors(System.Drawing.Color x, System.Drawing.Color y, int accuracy = 36)
{
    var offsetA = x.A - y.A;
    var offsetR = x.R - y.R;
    var offsetG = x.G - y.G;
    var offsetB = x.B - y.B;

    if (Math.Abs(offsetA) > 1)
    {
        return false;
    }

    if (offsetR == offsetG && offsetR == offsetB)
    {
        if (Math.Abs(offsetR) > 1)
        {
            return ColorDifference(x, y) <= accuracy / 3d;
        }
    }

    var difference = ColorDifference(x, y);
    return difference <= accuracy;
}

/// <summary>
///The weighted Euclidean distance is calculated by formula in RGB space
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
private double ColorDifference(System.Drawing.Color x, System.Drawing.Color y)
{
    var m = (x.R + y.R) / 2.0;
    var r = Math.Pow(x.R - y.R, 2);
    var g = Math.Pow(x.G - y.G, 2);
    var b = Math.Pow(x.B - y.B, 2);

    return Math.Sqrt((2 + m / 256) * r + 4 * g + (2 + (255 - m) / 256) * b);
}

GitHub project warehouse:

If you want to refer to the complete case, please refer to the following items:
Set transparent color case

My blog will start on https://imxcg.com/ CSDN will be selected and released, but once released, it will be rarely updated.

This work adopts Knowledge sharing Attribution - non-commercial use - sharing in the same way 4.0 international license agreement License. Welcome to reprint, use and republish, but be sure to keep the signature of the article xiaochenge (including the link: https://imxcg.blog.csdn.net/ ), shall not be used for commercial purposes, and the works modified based on this article must be distributed under the same license. If you have any questions, please Contact me .

Posted by brynjar on Sat, 20 Nov 2021 01:18:37 -0800