コード例 #1
0
        public static void DoBottomMirror(NonLinearTransfromNeededEventArg e)
        {
            var source = e.SourcePixels;
            var output = e.Pixels;

            var s      = e.Stride;
            var dy     = 1;
            var beginY = e.SourceClientRectangle.Bottom + dy;
            var sy     = e.ClientRectangle.Height;
            var beginX = e.SourceClientRectangle.Left;
            var endX   = e.SourceClientRectangle.Right;
            var d      = sy - beginY;

            for (int x = beginX; x < endX; x++)
            {
                for (int y = beginY; y < sy; y++)
                {
                    var sourceY = (int)(beginY - 1 - dy - (y - beginY));
                    if (sourceY < 0)
                    {
                        break;
                    }
                    var sourceX = x;
                    int sourceI = sourceY * s + sourceX * bytesPerPixel;
                    int outI    = y * s + x * bytesPerPixel;
                    output[outI + 0] = source[sourceI + 0];
                    output[outI + 1] = source[sourceI + 1];
                    output[outI + 2] = source[sourceI + 2];
                    output[outI + 3] = (byte)((1 - 1f * (y - beginY) / d) * 90);
                }
            }
        }
コード例 #2
0
        public static void DoBlind(NonLinearTransfromNeededEventArg e, Animation animation)
        {
            if (animation.BlindCoeff == PointF.Empty)
            {
                return;
            }

            var pixels = e.Pixels;
            var sx     = e.ClientRectangle.Width;
            var sy     = e.ClientRectangle.Height;
            var s      = e.Stride;
            var kx     = animation.BlindCoeff.X;
            var ky     = animation.BlindCoeff.Y;
            var a      = (int)((sx * kx + sy * ky) * (1 - e.CurrentTime));

            for (int x = 0; x < sx; x++)
            {
                for (int y = 0; y < sy; y++)
                {
                    int i = y * s + x * bytesPerPixel;
                    var d = x * kx + y * ky - a;
                    if (d >= 0)
                    {
                        pixels[i + 3] = (byte)0;
                    }
                }
            }
        }
コード例 #3
0
        protected virtual Bitmap OnNonLinearTransfromNeeded()
        {
            Bitmap bmp = null;

            if (CtrlBmp == null)
            {
                return(null);
            }

            try
            {
                bmp = new Bitmap(Width, Height);

                const int   bytesPerPixel = 4;
                PixelFormat pxf           = PixelFormat.Format32bppArgb;
                Rectangle   rect          = new Rectangle(0, 0, bmp.Width, bmp.Height);
                BitmapData  bmpData       = bmp.LockBits(rect, ImageLockMode.ReadWrite, pxf);
                IntPtr      ptr           = bmpData.Scan0;
                int         numBytes      = bmp.Width * bmp.Height * bytesPerPixel;
                byte[]      argbValues    = new byte[numBytes];

                Marshal.Copy(ptr, argbValues, 0, numBytes);

                var e = new NonLinearTransfromNeededEventArg()
                {
                    CurrentTime = CurrentTime, ClientRectangle = ClientRectangle, Pixels = argbValues, Stride = bmpData.Stride, SourcePixels = CtrlPixels, SourceClientRectangle = new Rectangle(Padding.Left, Padding.Top, DecoratedControl.Width, DecoratedControl.Height), SourceStride = CtrlStride
                };

                try
                {
                    if (NonLinearTransfromNeeded != null)
                    {
                        NonLinearTransfromNeeded(this, e);
                    }
                    else
                    {
                        e.UseDefaultTransform = true;
                    }

                    if (e.UseDefaultTransform)
                    {
                        switch (DecorationType)
                        {
                        case DecorationType.BottomMirror: TransfromHelper.DoBottomMirror(e); break;
                        }
                    }
                }catch {}

                Marshal.Copy(argbValues, 0, ptr, numBytes);
                bmp.UnlockBits(bmpData);
            }
            catch
            {
            }

            return(bmp);
        }
コード例 #4
0
ファイル: Controller.cs プロジェクト: yzwbrian/winform-ui
        protected virtual Bitmap OnNonLinearTransfromNeeded()
        {
            Bitmap bmp = null;

            if (ctrlBmp == null)
            {
                return(null);
            }

            try
            {
                bmp = (Bitmap)ctrlBmp.Clone();

                const int   bytesPerPixel = 4;
                PixelFormat pxf           = PixelFormat.Format32bppArgb;
                Rectangle   rect          = new Rectangle(0, 0, bmp.Width, bmp.Height);
                BitmapData  bmpData       = bmp.LockBits(rect, ImageLockMode.ReadWrite, pxf);
                IntPtr      ptr           = bmpData.Scan0;
                int         numBytes      = bmp.Width * bmp.Height * bytesPerPixel;
                byte[]      argbValues    = new byte[numBytes];

                System.Runtime.InteropServices.Marshal.Copy(ptr, argbValues, 0, numBytes);

                var e = new NonLinearTransfromNeededEventArg()
                {
                    CurrentTime = CurrentTime, ClientRectangle = DoubleBitmap.ClientRectangle, Pixels = argbValues, Stride = bmpData.Stride
                };

                if (NonLinearTransfromNeeded != null)
                {
                    NonLinearTransfromNeeded(this, e);
                }
                else
                {
                    e.UseDefaultTransform = true;
                }

                if (e.UseDefaultTransform)
                {
                    TransfromHelper.DoBlind(e, animation);
                    TransfromHelper.DoMosaic(e, animation, ref buffer, ref pixelsBuffer);

                    TransfromHelper.DoTransparent(e, animation);
                    TransfromHelper.DoLeaf(e, animation);
                }

                System.Runtime.InteropServices.Marshal.Copy(argbValues, 0, ptr, numBytes);
                bmp.UnlockBits(bmpData);
            }
            catch
            {
            }

            return(bmp);
        }
コード例 #5
0
 protected virtual void OnNonLinearTransfromNeeded(object sender, NonLinearTransfromNeededEventArg e)
 {
     if (NonLinearTransfromNeeded != null)
     {
         NonLinearTransfromNeeded(this, e);
     }
     else
     {
         e.UseDefaultTransform = true;
     }
 }
コード例 #6
0
        public static void DoLeaf(NonLinearTransfromNeededEventArg e, Animation animation)
        {
            if (animation.LeafCoeff == 0f)
            {
                return;
            }

            var pixels = e.Pixels;
            var sx     = e.ClientRectangle.Width;
            var sy     = e.ClientRectangle.Height;
            var s      = e.Stride;
            var a      = (int)((sx + sy) * (1 - e.CurrentTime * e.CurrentTime));

            var count = pixels.Length;

            for (int x = 0; x < sx; x++)
            {
                for (int y = 0; y < sy; y++)
                {
                    int i = y * s + x * bytesPerPixel;
                    if (x + y >= a)
                    {
                        var newX = a - y;
                        var newY = a - x;
                        var d    = a - x - y;
                        if (d < -20)
                        {
                            d = -20;
                        }

                        int newI = newY * s + newX * bytesPerPixel;
                        if (newX >= 0 && newY >= 0)
                        {
                            if (newI >= 0 && newI < count)
                            {
                                if (pixels[i + 3] > 0)
                                {
                                    pixels[newI + 0] = (byte)Math.Min(255, d + 250 + pixels[i + 0] / 10);
                                    pixels[newI + 1] = (byte)Math.Min(255, d + 250 + pixels[i + 1] / 10);
                                    pixels[newI + 2] = (byte)Math.Min(255, d + 250 + pixels[i + 2] / 10);
                                    pixels[newI + 3] = 230;
                                }
                            }
                        }
                        pixels[i + 3] = (byte)(0);
                    }
                }
            }
        }
コード例 #7
0
        /*
         * internal static void DoBottomShadow(NonLinearTransfromNeededEventArg e)
         * {
         *  var source = e.SourcePixels;
         *  var output = e.Pixels;
         *
         *  var s = e.Stride;
         *  var dy = 1;
         *  var beginY = e.SourceClientRectangle.Bottom + dy;
         *  var sy = e.ClientRectangle.Height;
         *  var beginX = e.SourceClientRectangle.Left;
         *  var endX = e.SourceClientRectangle.Right;
         *  var d = sy - beginY;
         *
         *  var bgG = source[0];
         *  var bgB = source[1];
         *  var bgR = source[2];
         *
         *  for (int x = beginX; x < endX; x++)
         *      for (int y = beginY; y < sy; y++)
         *      {
         *          var sourceY = (int)(beginY - 1 - dy - (y - beginY)*6);
         *          if (sourceY < 0)
         *              break;
         *          var sourceX = x;
         *          int sourceI = sourceY * s + sourceX * bytesPerPixel;
         *          int outI = y * s + x * bytesPerPixel;
         *          if (source[sourceI + 0] != bgG && source[sourceI + 1] != bgB && source[sourceI + 2] != bgR)
         *          {
         *              output[outI + 0] = 0;
         *              output[outI + 1] = 0;
         *              output[outI + 2] = 0;
         *              output[outI + 3] = (byte) ((1 - 1f*(y - beginY)/d)*90);
         *          }
         *      }
         * }*/

        public static void DoBlur(NonLinearTransfromNeededEventArg e, int r)
        {
            var output = e.Pixels;
            var source = e.SourcePixels;

            var s    = e.Stride;
            var sy   = e.ClientRectangle.Height;
            var sx   = e.ClientRectangle.Width;
            var maxI = source.Length - bytesPerPixel;

            for (int x = r; x < sx - r; x++)
            {
                for (int y = r; y < sy - r; y++)
                {
                    int outI = y * s + x * bytesPerPixel;

                    int R = 0, G = 0, B = 0, A = 0;
                    int counter = 0;
                    for (int xx = x - r; xx < x + r; xx++)
                    {
                        for (int yy = y - r; yy < y + r; yy++)
                        {
                            int srcI = yy * s + xx * bytesPerPixel;
                            if (srcI >= 0 && srcI < maxI)
                            {
                                if (source[srcI + 3] > 0)
                                {
                                    B += source[srcI + 0];
                                    G += source[srcI + 1];
                                    R += source[srcI + 2];
                                    A += source[srcI + 3];
                                    counter++;
                                }
                            }
                        }
                    }
                    if (outI < maxI && counter > 5)
                    {
                        output[outI + 0] = (byte)(B / counter);
                        output[outI + 1] = (byte)(G / counter);
                        output[outI + 2] = (byte)(R / counter);
                        output[outI + 3] = (byte)(A / counter);
                        //output[outI + 3] = 255; //(byte)((1 - 1f * (y - beginY) / d) * 90);
                    }
                }
            }
        }
コード例 #8
0
        public static void DoBlind(NonLinearTransfromNeededEventArg e, Animation animation)
        {
            if (animation.BlindCoeff == PointF.Empty)
                return;

            var pixels = e.Pixels;
            var sx = e.ClientRectangle.Width;
            var sy = e.ClientRectangle.Height;
            var s = e.Stride;
            var kx = animation.BlindCoeff.X;
            var ky = animation.BlindCoeff.Y;
            var a = (int)((sx * kx + sy * ky) * (1 - e.CurrentTime));

            for (int x = 0; x < sx; x++)
                for (int y = 0; y < sy; y++)
                {
                    int i = y * s + x * bytesPerPixel;
                    var d = x * kx + y * ky - a;
                    if (d >= 0)
                        pixels[i + 3] = (byte)0;
                }
        }
コード例 #9
0
        public static void DoTransparent(NonLinearTransfromNeededEventArg e, Animation animation)
        {
            if (animation.TransparencyCoeff == 0f)
            {
                return;
            }
            var opacity = 1f - animation.TransparencyCoeff * e.CurrentTime;

            if (opacity < 0f)
            {
                opacity = 0f;
            }
            if (opacity > 1f)
            {
                opacity = 1f;
            }

            var pixels = e.Pixels;

            for (int counter = 0; counter < pixels.Length; counter += bytesPerPixel)
            {
                pixels[counter + 3] = (byte)(pixels[counter + 3] * opacity);
            }
        }
コード例 #10
0
        public static void DoTransparent(NonLinearTransfromNeededEventArg e, Animation animation)
        {
            if (animation.TransparencyCoeff == 0f)
                return;
            var opacity = 1f - animation.TransparencyCoeff * e.CurrentTime;
            if (opacity < 0f)
                opacity = 0f;
            if (opacity > 1f)
                opacity = 1f;

            var pixels = e.Pixels;
            for (int counter = 0; counter < pixels.Length; counter += bytesPerPixel)
                pixels[counter + 3] = (byte)(pixels[counter + 3] * opacity);
        }
コード例 #11
0
        public static void DoMosaic(NonLinearTransfromNeededEventArg e, Animation animation, ref Point[] buffer, ref byte[] pixelsBuffer)
        {
            if (animation.MosaicCoeff == PointF.Empty || animation.MosaicSize == 0)
                return;

            var pixels = e.Pixels;
            var sx = e.ClientRectangle.Width;
            var sy = e.ClientRectangle.Height;
            var s = e.Stride;
            var a = e.CurrentTime;
            var count = pixels.Length;
            var opacity = 1 - e.CurrentTime;
            if (opacity < 0f) opacity = 0f;
            if (opacity > 1f) opacity = 1f;
            var mkx = animation.MosaicCoeff.X;
            var mky = animation.MosaicCoeff.Y;

            if (buffer == null)
            {
                buffer = new Point[pixels.Length];
                for (int i = 0; i < pixels.Length; i++)
                    buffer[i] = new Point((int)(mkx * (rnd.NextDouble() - 0.5)), (int)(mky * (rnd.NextDouble() - 0.5)));
            }

            if (pixelsBuffer == null)
                pixelsBuffer = (byte[])pixels.Clone();

            for (int i = 0; i < count; i += bytesPerPixel)
            {
                pixels[i + 0] = 255;
                pixels[i + 1] = 255;
                pixels[i + 2] = 255;
                pixels[i + 3] = 0;
            }

            var ms = animation.MosaicSize;
            var msx = animation.MosaicShift.X;
            var msy = animation.MosaicShift.Y;

            for (int y = 0; y < sy; y++)
                for (int x = 0; x < sx; x++)
                {
                    int yi = (y / ms);
                    int xi = (x / ms);
                    int i = y * s + x * bytesPerPixel;
                    int j = yi * s + xi * bytesPerPixel;

                    var newX = x + (int)(a * (buffer[j].X + xi * msx));
                    var newY = y + (int)(a * (buffer[j].Y + yi * msy));

                    if (newX >= 0 && newX < sx)
                        if (newY >= 0 && newY < sy)
                        {
                            int newI = newY * s + newX * bytesPerPixel;
                            pixels[newI + 0] = pixelsBuffer[i + 0];
                            pixels[newI + 1] = pixelsBuffer[i + 1];
                            pixels[newI + 2] = pixelsBuffer[i + 2];
                            pixels[newI + 3] = (byte)(pixelsBuffer[i + 3] * opacity);
                        }
                }
        }
コード例 #12
0
        public static void DoLeaf(NonLinearTransfromNeededEventArg e, Animation animation)
        {
            if (animation.LeafCoeff == 0f)
                return;

            var pixels = e.Pixels;
            var sx = e.ClientRectangle.Width;
            var sy = e.ClientRectangle.Height;
            var s = e.Stride;
            var a = (int)((sx + sy) * (1 - e.CurrentTime * e.CurrentTime));

            var count = pixels.Length;

            for (int x = 0; x < sx; x++)
                for (int y = 0; y < sy; y++)
                {
                    int i = y * s + x * bytesPerPixel;
                    if (x + y >= a)
                    {
                        var newX = a - y;
                        var newY = a - x;
                        var d = a - x - y;
                        if (d < -20)
                            d = -20;

                        int newI = newY * s + newX * bytesPerPixel;
                        if (newX >= 0 && newY >= 0)
                            if (newI >= 0 && newI < count)
                                if (pixels[i + 3] > 0)
                                {
                                    pixels[newI + 0] = (byte)Math.Min(255, d + 250 + pixels[i + 0] / 10);
                                    pixels[newI + 1] = (byte)Math.Min(255, d + 250 + pixels[i + 1] / 10);
                                    pixels[newI + 2] = (byte)Math.Min(255, d + 250 + pixels[i + 2] / 10);
                                    pixels[newI + 3] = 230;
                                }
                        pixels[i + 3] = (byte)(0);
                    }
                }
        }
コード例 #13
0
        public static void DoBottomMirror(NonLinearTransfromNeededEventArg e)
        {
            var source = e.SourcePixels;
            var output = e.Pixels;

            var s = e.Stride;
            var dy = 1;
            var beginY = e.SourceClientRectangle.Bottom + dy;
            var sy = e.ClientRectangle.Height;
            var beginX = e.SourceClientRectangle.Left;
            var endX = e.SourceClientRectangle.Right;
            var d = sy - beginY;

            for (int x = beginX; x < endX; x++)
            for (int y = beginY; y < sy; y++)
            {
                var sourceY = (int)(beginY - 1 - dy  - (y - beginY));
                if (sourceY < 0)
                    break;
                var sourceX = x;
                int sourceI = sourceY * s + sourceX * bytesPerPixel;
                int outI = y * s + x * bytesPerPixel;
                output[outI + 0] = source[sourceI + 0];
                output[outI + 1] = source[sourceI + 1];
                output[outI + 2] = source[sourceI + 2];
                output[outI + 3] = (byte)((1 - 1f*(y - beginY)/d)*90);
            }
        }
コード例 #14
0
        /*
        internal static void DoBottomShadow(NonLinearTransfromNeededEventArg e)
        {
            var source = e.SourcePixels;
            var output = e.Pixels;

            var s = e.Stride;
            var dy = 1;
            var beginY = e.SourceClientRectangle.Bottom + dy;
            var sy = e.ClientRectangle.Height;
            var beginX = e.SourceClientRectangle.Left;
            var endX = e.SourceClientRectangle.Right;
            var d = sy - beginY;

            var bgG = source[0];
            var bgB = source[1];
            var bgR = source[2];

            for (int x = beginX; x < endX; x++)
                for (int y = beginY; y < sy; y++)
                {
                    var sourceY = (int)(beginY - 1 - dy - (y - beginY)*6);
                    if (sourceY < 0)
                        break;
                    var sourceX = x;
                    int sourceI = sourceY * s + sourceX * bytesPerPixel;
                    int outI = y * s + x * bytesPerPixel;
                    if (source[sourceI + 0] != bgG && source[sourceI + 1] != bgB && source[sourceI + 2] != bgR)
                    {
                        output[outI + 0] = 0;
                        output[outI + 1] = 0;
                        output[outI + 2] = 0;
                        output[outI + 3] = (byte) ((1 - 1f*(y - beginY)/d)*90);
                    }
                }
        }*/
        public static void DoBlur(NonLinearTransfromNeededEventArg e, int r)
        {
            var output = e.Pixels;
            var source = e.SourcePixels;

            var s = e.Stride;
            var sy = e.ClientRectangle.Height;
            var sx = e.ClientRectangle.Width;
            var maxI = source.Length - bytesPerPixel;

            for (int x = r; x < sx - r; x++)
            for (int y = r; y < sy - r; y++)
            {
                int outI = y * s + x * bytesPerPixel;

                int R = 0, G = 0, B = 0, A = 0;
                int counter = 0;
                for (int xx = x - r; xx < x + r; xx++)
                for (int yy = y - r; yy < y + r; yy++)
                {
                    int srcI = yy * s + xx * bytesPerPixel;
                    if (srcI >= 0 && srcI < maxI)
                    if(source[srcI + 3] > 0)
                    {
                        B += source[srcI + 0];
                        G += source[srcI + 1];
                        R += source[srcI + 2];
                        A += source[srcI + 3];
                        counter++;
                    }
                }
                if (outI < maxI && counter > 5)
                {
                    output[outI + 0] = (byte)(B / counter);
                    output[outI + 1] = (byte)(G / counter);
                    output[outI + 2] = (byte)(R / counter);
                    output[outI + 3] = (byte)(A / counter);
                    //output[outI + 3] = 255; //(byte)((1 - 1f * (y - beginY) / d) * 90);
                }
            }
        }
コード例 #15
0
        protected virtual Bitmap OnNonLinearTransfromNeeded()
        {
            Bitmap bmp = null;
            if (CtrlBmp == null)
                return null;

            try
            {
                bmp = new Bitmap(Width, Height);

                const int bytesPerPixel = 4;
                PixelFormat pxf = PixelFormat.Format32bppArgb;
                Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
                BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, pxf);
                IntPtr ptr = bmpData.Scan0;
                int numBytes = bmp.Width * bmp.Height * bytesPerPixel;
                byte[] argbValues = new byte[numBytes];

                Marshal.Copy(ptr, argbValues, 0, numBytes);

                var e = new NonLinearTransfromNeededEventArg() { CurrentTime = CurrentTime, ClientRectangle = ClientRectangle, Pixels = argbValues, Stride = bmpData.Stride, SourcePixels = CtrlPixels, SourceClientRectangle = new Rectangle(Padding.Left, Padding.Top, DecoratedControl.Width, DecoratedControl.Height), SourceStride = CtrlStride };

                try
                {
                    if (NonLinearTransfromNeeded != null)
                        NonLinearTransfromNeeded(this, e);
                    else
                        e.UseDefaultTransform = true;

                    if (e.UseDefaultTransform)
                    {
                        switch (DecorationType)
                        {
                            case DecorationType.BottomMirror: TransfromHelper.DoBottomMirror(e); break;
                        }
                    }
                }catch{}

                Marshal.Copy(argbValues, 0, ptr, numBytes);
                bmp.UnlockBits(bmpData);
            }
            catch
            {
            }

            return bmp;
        }
コード例 #16
0
 protected virtual void OnNonLinearTransfromNeeded(object sender, NonLinearTransfromNeededEventArg e)
 {
     if (NonLinearTransfromNeeded != null)
         NonLinearTransfromNeeded(this, e);
     else
         e.UseDefaultTransform = true;
 }
コード例 #17
0
ファイル: Controller.cs プロジェクト: panshuiqing/winform-ui
        protected virtual Bitmap OnNonLinearTransfromNeeded()
        {
            Bitmap bmp = null;
            if (ctrlBmp == null)
                return null;

            try
            {
                bmp = (Bitmap)ctrlBmp.Clone();

                const int bytesPerPixel = 4;
                PixelFormat pxf = PixelFormat.Format32bppArgb;
                Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
                BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, pxf);
                IntPtr ptr = bmpData.Scan0;
                int numBytes = bmp.Width * bmp.Height * bytesPerPixel;
                byte[] argbValues = new byte[numBytes];

                System.Runtime.InteropServices.Marshal.Copy(ptr, argbValues, 0, numBytes);

                var e = new NonLinearTransfromNeededEventArg() { CurrentTime = CurrentTime, ClientRectangle = DoubleBitmap.ClientRectangle, Pixels = argbValues, Stride = bmpData.Stride };

                if (NonLinearTransfromNeeded != null)
                    NonLinearTransfromNeeded(this, e);
                else
                    e.UseDefaultTransform = true;

                if (e.UseDefaultTransform)
                {
                    TransfromHelper.DoBlind(e, animation);
                    TransfromHelper.DoMosaic(e, animation, ref buffer, ref pixelsBuffer);

                    TransfromHelper.DoTransparent(e, animation);
                    TransfromHelper.DoLeaf(e, animation);
                }

                System.Runtime.InteropServices.Marshal.Copy(argbValues, 0, ptr, numBytes);
                bmp.UnlockBits(bmpData);
            }
            catch
            {
            }

            return bmp;
        }
コード例 #18
0
        public static void DoMosaic(NonLinearTransfromNeededEventArg e, Animation animation, ref Point[] buffer, ref byte[] pixelsBuffer)
        {
            if (animation.MosaicCoeff == PointF.Empty || animation.MosaicSize == 0)
            {
                return;
            }

            var pixels  = e.Pixels;
            var sx      = e.ClientRectangle.Width;
            var sy      = e.ClientRectangle.Height;
            var s       = e.Stride;
            var a       = e.CurrentTime;
            var count   = pixels.Length;
            var opacity = 1 - e.CurrentTime;

            if (opacity < 0f)
            {
                opacity = 0f;
            }
            if (opacity > 1f)
            {
                opacity = 1f;
            }
            var mkx = animation.MosaicCoeff.X;
            var mky = animation.MosaicCoeff.Y;

            if (buffer == null)
            {
                buffer = new Point[pixels.Length];
                for (int i = 0; i < pixels.Length; i++)
                {
                    buffer[i] = new Point((int)(mkx * (rnd.NextDouble() - 0.5)), (int)(mky * (rnd.NextDouble() - 0.5)));
                }
            }

            if (pixelsBuffer == null)
            {
                pixelsBuffer = (byte[])pixels.Clone();
            }


            for (int i = 0; i < count; i += bytesPerPixel)
            {
                pixels[i + 0] = 255;
                pixels[i + 1] = 255;
                pixels[i + 2] = 255;
                pixels[i + 3] = 0;
            }

            var ms  = animation.MosaicSize;
            var msx = animation.MosaicShift.X;
            var msy = animation.MosaicShift.Y;

            for (int y = 0; y < sy; y++)
            {
                for (int x = 0; x < sx; x++)
                {
                    int yi = (y / ms);
                    int xi = (x / ms);
                    int i  = y * s + x * bytesPerPixel;
                    int j  = yi * s + xi * bytesPerPixel;

                    var newX = x + (int)(a * (buffer[j].X + xi * msx));
                    var newY = y + (int)(a * (buffer[j].Y + yi * msy));

                    if (newX >= 0 && newX < sx)
                    {
                        if (newY >= 0 && newY < sy)
                        {
                            int newI = newY * s + newX * bytesPerPixel;
                            pixels[newI + 0] = pixelsBuffer[i + 0];
                            pixels[newI + 1] = pixelsBuffer[i + 1];
                            pixels[newI + 2] = pixelsBuffer[i + 2];
                            pixels[newI + 3] = (byte)(pixelsBuffer[i + 3] * opacity);
                        }
                    }
                }
            }
        }