/// <summary> /// Applies the pixelate effect in given frame. /// </summary> /// <param name="image">The image to pixelate.</param> /// <param name="rectangle">The area to pixelate.</param> /// <param name="pixelateSize">The size of the pixel.</param> /// <returns>A pixelated Bitmap.</returns> public static Bitmap Pixelate2(Bitmap image, Rectangle rectangle, int pixelateSize) { var pixelated = new Bitmap(image); var pixelUtil = new PixelUtilOld(pixelated); pixelUtil.LockBits(); // look at every pixel in the rectangle while making sure we're within the image bounds for (var xx = rectangle.X; xx < rectangle.X + rectangle.Width && xx < image.Width; xx += pixelateSize) { for (var yy = rectangle.Y; yy < rectangle.Y + rectangle.Height && yy < image.Height; yy += pixelateSize) { var offsetX = pixelateSize / 2; var offsetY = pixelateSize / 2; // make sure that the offset is within the boundry of the image while (xx + offsetX >= image.Width) { offsetX--; } while (yy + offsetY >= image.Height) { offsetY--; } // get the pixel color in the center of the soon to be pixelated area var pixel = pixelUtil.GetPixel(xx + offsetX, yy + offsetY); // for each pixel in the pixelate size, set it to the center color for (var x = xx; x < xx + pixelateSize && x < image.Width; x++) { for (var y = yy; y < yy + pixelateSize && y < image.Height; y++) { pixelUtil.SetPixel(x, y, pixel); } } } } pixelUtil.UnlockBits(); return(pixelated); }
/// <summary> /// Analizes all frames (from the end to the start) and paints all unchanged pixels with a given color, /// after, it cuts the image to reduce filesize. /// </summary> /// <param name="listToEncode">The list of frames to analize.</param> /// <param name="transparent">The color to paint the unchanged pixels.</param> /// <param name="id">The Id of the current Task.</param> /// <param name="tokenSource">The cancelation token source.</param> /// <returns>A List contaning all frames and its cut points</returns> public static List <FrameInfo> PaintTransparentAndCut(List <FrameInfo> listToEncode, Color transparent, int id, CancellationTokenSource tokenSource) { //First frame rect. var size = listToEncode[0].Path.ScaledSize(); listToEncode[0].Rect = new Int32Rect(0, 0, (int)size.Width, (int)size.Height); //End to start FOR for (var index = listToEncode.Count - 1; index > 0; index--) { #region Cancellation if (tokenSource.Token.IsCancellationRequested) { Windows.Other.Encoder.SetStatus(Status.Canceled, id); break; } #endregion #region For each Frame, from the end to the start Windows.Other.Encoder.Update(id, index - 1); //First frame is ignored. if (index <= 0) { continue; } #region Get Image Info var imageAux1 = listToEncode[index - 1].Path.From(); var imageAux2 = listToEncode[index].Path.From(); var startY = new bool[imageAux1.Height]; var startX = new bool[imageAux1.Width]; var image1 = new PixelUtilOld(imageAux1); //Previous image var image2 = new PixelUtilOld(imageAux2); //Actual image image1.LockBits(); image2.LockBits(); var height = imageAux1.Height; var width = imageAux1.Width; #endregion //Only use Parallel if the image is big enough. if (width * height > 150000) { #region Parallel Loop //x - width - sides Parallel.For(0, width, x => { //y - height - up/down for (var y = 0; y < height; y++) { if (image1.GetPixel(x, y) == image2.GetPixel(x, y)) { image2.SetPixel(x, y, transparent); } else { #region Get the Changed Pixels startX[x] = true; startY[y] = true; #endregion } } }); //SPEEEEEED, alot! #endregion } else { #region Sequential Loop //x - width - sides for (var x = 0; x < width; x++) { //y - height - up/down for (var y = 0; y < height; y++) { #region For each Pixel if (image1.GetPixel(x, y) == image2.GetPixel(x, y)) { image2.SetPixel(x, y, transparent); } else { #region Get the Changed Pixels startX[x] = true; startY[y] = true; #endregion } #endregion } } #endregion } image1.UnlockBits(); image2.UnlockBits(); #region Verify positions var firstX = startX.ToList().FindIndex(x => x); var lastX = startX.ToList().FindLastIndex(x => x); if (firstX == -1) { firstX = 0; } if (lastX == -1) { lastX = imageAux1.Width; } var firstY = startY.ToList().FindIndex(x => x); var lastY = startY.ToList().FindLastIndex(x => x); if (lastY == -1) { lastY = imageAux1.Height; } if (firstY == -1) { firstY = 0; } if (lastX < firstX) { var aux = lastX; lastX = firstX; firstX = aux; } if (lastY < firstY) { var aux = lastY; lastY = firstY; firstY = aux; } #endregion #region Get the Width and Height var heightCut = Math.Abs(lastY - firstY); var widthCut = Math.Abs(lastX - firstX); //If nothing changed, shift the delay. if (heightCut + widthCut == height + width) { //TODO: Maximum of 2 bytes, 255 x 100: 25.500 ms listToEncode[index - 1].Delay += listToEncode[index].Delay; listToEncode[index].Rect = new Int32Rect(0, 0, 0, 0); GC.Collect(1); continue; } if (heightCut != height) { heightCut++; } if (widthCut != width) { widthCut++; } listToEncode[index].Rect = new Int32Rect(firstX, firstY, widthCut, heightCut); #endregion #region Update Image //Cut the images and get the new values. var imageSave2 = new Bitmap(imageAux2.Clone( new Rectangle(firstX, firstY, widthCut, heightCut), imageAux2.PixelFormat)); imageAux2.Dispose(); imageAux1.Dispose(); imageSave2.Save(listToEncode[index].Path); #endregion GC.Collect(1); #endregion } return(listToEncode); }
/// <summary> /// Calculates the difference between one given frame and another. /// </summary> /// <param name="first">The first frame to compare.</param> /// <param name="second">The second frame to compare.</param> /// <returns>The similarity between the two frames in percentage.</returns> public static double CalculateDifference(FrameInfo first, FrameInfo second) { #region Get Image Info var imageAux1 = first.Path.From(); var imageAux2 = second.Path.From(); var image1 = new PixelUtilOld(imageAux1); //First image var image2 = new PixelUtilOld(imageAux2); //Last image image1.LockBits(); image2.LockBits(); var height = imageAux1.Height; var width = imageAux1.Width; var equalCount = 0; #endregion //Only use Parallel if the image is big enough. if (width * height > 150000) { #region Parallel Loop //x - width - sides Parallel.For(0, width, x => { //y - height - up/down for (var y = 0; y < height; y++) { if (image1.GetPixel(x, y) == image2.GetPixel(x, y)) { Interlocked.Increment(ref equalCount); } //equalCount = equalCount + (image1.GetPixel(x, y) == image2.GetPixel(x, y) ? 1 : 0); } }); #endregion } else { #region Sequential Loop //x - width - sides for (var x = 0; x < width; x++) { //y - height - up/down for (var y = 0; y < height; y++) { equalCount = equalCount + (image1.GetPixel(x, y) == image2.GetPixel(x, y) ? 1 : 0); } } #endregion } image1.UnlockBits(); image2.UnlockBits(); GC.Collect(1); return(Other.CrossMultiplication(width * height, equalCount, null)); }