public static bool ApplyImageToMask(
            CanvasRenderTarget image,
            CanvasRenderTarget mask,
            CanvasRenderTarget canvas,
            Color maskColor,
            bool NoAlphaAtBoundary)
        {
            if (image == null || mask == null || canvas == null)
            {
                return(false);
            }

            byte[] pixelsImage  = image.GetPixelBytes();
            byte[] pixelsMask   = mask.GetPixelBytes();
            byte[] pixelsCanvas = canvas.GetPixelBytes();
            if (pixelsImage == null || pixelsMask == null || pixelsCanvas == null)
            {
                return(false);
            }

            uint col          = 0;
            uint image_stride = image.SizeInPixels.Width;
            uint stride       = canvas.SizeInPixels.Width;
            uint mask_stride  = mask.SizeInPixels.Width;

            for (uint row = 0; row < canvas.SizeInPixels.Height; ++row)
            {
                uint total_row_len       = (uint)(row * stride);
                uint total_row_mask_len  = (uint)(row * mask_stride);
                uint total_row_image_len = (uint)(row * image_stride);
                for (col = 0; col < canvas.SizeInPixels.Width; ++col)
                {
                    if (row >= image.SizeInPixels.Height || col >= image.SizeInPixels.Width)
                    {
                        continue;
                    }
                    if (row >= mask.SizeInPixels.Height || col >= mask.SizeInPixels.Width)
                    {
                        continue;
                    }

                    uint index      = (total_row_len + col) * 4;
                    uint indexMask  = (total_row_mask_len + col) * 4;
                    uint indexImage = (total_row_image_len + col) * 4;

                    byte maskByte = 0;

                    if (MaskColor.IsEqual(maskColor, MaskColor.Red))
                    {
                        maskByte = pixelsMask[indexMask + 2];
                    }
                    else if (MaskColor.IsEqual(maskColor, MaskColor.Green))
                    {
                        maskByte = pixelsMask[indexMask + 1];
                    }
                    else if (MaskColor.IsEqual(maskColor, MaskColor.Blue))
                    {
                        maskByte = pixelsMask[indexMask];
                    }

                    if (maskByte > 0)
                    {
                        uint pixels_canvas = (uint)((pixelsCanvas[index + 3] << 24) | (pixelsCanvas[index + 2] << 16) | (pixelsCanvas[index + 1] << 8) | pixelsCanvas[index]);
                        uint pixels_image  = (uint)((pixelsImage[index + 3] << 24) | (pixelsImage[index + 2] << 16) | (pixelsImage[index + 1] << 8) | pixelsImage[index]);
                        if (NoAlphaAtBoundary)
                        {
                            uint result = AlphablendNoAlphaAtBoundary(pixels_canvas, pixels_image, pixelsMask[indexMask + 3], pixelsMask[indexMask + 3]);
                            pixelsCanvas[index + 3] = (byte)((result & 0xff000000) >> 24);
                            pixelsCanvas[index + 2] = (byte)((result & 0xff0000) >> 16);
                            pixelsCanvas[index + 1] = (byte)((result & 0xff00) >> 8);
                            pixelsCanvas[index]     = (byte)(result & 0xff);
                        }
                        else
                        {
                            uint result = Alphablend(pixels_canvas, pixels_image, pixelsMask[indexMask + 3], pixelsMask[indexMask + 3]);
                            pixelsCanvas[index + 3] = (byte)((result & 0xff000000) >> 24);
                            pixelsCanvas[index + 2] = (byte)((result & 0xff0000) >> 16);
                            pixelsCanvas[index + 1] = (byte)((result & 0xff00) >> 8);
                            pixelsCanvas[index]     = (byte)(result & 0xff);
                        }
                    }
                }
            }
            canvas.SetPixelBytes(pixelsCanvas);

            return(true);
        }
        public static bool ApplyShadowToMask(
            Color clrShadow,
            CanvasRenderTarget mask,
            CanvasRenderTarget canvas,
            Color maskColor,
            Point offset)
        {
            if (mask == null || canvas == null)
            {
                return(false);
            }

            byte[] pixelsMask   = mask.GetPixelBytes();
            byte[] pixelsCanvas = canvas.GetPixelBytes();

            if (pixelsMask == null || pixelsCanvas == null)
            {
                return(false);
            }

            uint col         = 0;
            uint stride      = canvas.SizeInPixels.Width;
            uint mask_stride = mask.SizeInPixels.Width;

            for (uint row = 0; row < canvas.SizeInPixels.Height; ++row)
            {
                uint total_row_len      = (uint)(row * stride);
                uint total_row_mask_len = (uint)((row - offset.Y) * mask_stride);
                for (col = 0; col < canvas.SizeInPixels.Width; ++col)
                {
                    if ((row - offset.Y) >= mask.SizeInPixels.Height || (col - offset.X) >= mask.SizeInPixels.Width ||
                        (row - offset.Y) < 0 || (col - offset.X) < 0)
                    {
                        continue;
                    }

                    uint index     = (total_row_len + col) * 4;
                    uint indexMask = (uint)((total_row_mask_len + (col - offset.X)) * 4);

                    byte maskByte = 0;

                    if (MaskColor.IsEqual(maskColor, MaskColor.Red))
                    {
                        maskByte = pixelsMask[indexMask + 2];
                    }
                    else if (MaskColor.IsEqual(maskColor, MaskColor.Green))
                    {
                        maskByte = pixelsMask[indexMask + 1];
                    }
                    else if (MaskColor.IsEqual(maskColor, MaskColor.Blue))
                    {
                        maskByte = pixelsMask[indexMask];
                    }

                    uint color = (uint)(0xff << 24 | clrShadow.R << 16 | clrShadow.G << 8 | clrShadow.B);

                    if (maskByte > 0)
                    {
                        uint pixels_canvas = (uint)((pixelsCanvas[index + 3] << 24) | (pixelsCanvas[index + 2] << 16) | (pixelsCanvas[index + 1] << 8) | pixelsCanvas[index]);

                        uint result = Alphablend(pixels_canvas, color, pixelsMask[indexMask + 3], (byte)(pixelsMask[indexMask + 3] * clrShadow.A / 255));
                        pixelsCanvas[index + 3] = (byte)((result & 0xff000000) >> 24);
                        pixelsCanvas[index + 2] = (byte)((result & 0xff0000) >> 16);
                        pixelsCanvas[index + 1] = (byte)((result & 0xff00) >> 8);
                        pixelsCanvas[index]     = (byte)(result & 0xff);
                    }
                }
            }
            canvas.SetPixelBytes(pixelsCanvas);

            return(true);
        }
        public static bool MeasureMaskLength(
            CanvasRenderTarget mask,
            Color maskColor,
            out uint top,
            out uint left,
            out uint bottom,
            out uint right)
        {
            top    = 30000;
            left   = 30000;
            bottom = 0;
            right  = 0;

            if (mask == null)
            {
                return(false);
            }

            byte[] pixelsMask = mask.GetPixelBytes();

            if (pixelsMask == null)
            {
                return(false);
            }

            uint col    = 0;
            uint stride = mask.SizeInPixels.Width;

            for (uint row = 0; row < mask.SizeInPixels.Height; ++row)
            {
                uint total_row_len = (uint)(row * stride);
                for (col = 0; col < mask.SizeInPixels.Width; ++col)
                {
                    uint index  = total_row_len + col;
                    byte nAlpha = 0;

                    if (MaskColor.IsEqual(maskColor, MaskColor.Red))
                    {
                        nAlpha = pixelsMask[index + 2];
                    }
                    else if (MaskColor.IsEqual(maskColor, MaskColor.Green))
                    {
                        nAlpha = pixelsMask[index + 1];
                    }
                    else if (MaskColor.IsEqual(maskColor, MaskColor.Blue))
                    {
                        nAlpha = pixelsMask[index];
                    }

                    if (nAlpha > 0)
                    {
                        if (col < left)
                        {
                            left = col;
                        }
                        if (row < top)
                        {
                            top = row;
                        }
                        if (col > right)
                        {
                            right = col;
                        }
                        if (row > bottom)
                        {
                            bottom = row;
                        }
                    }
                }
            }

            return(true);
        }