public void SetPhoto(Texture2D photo) { Reset(); ColorBuffer32 oldPixelBuffer = pixelBuffer; pixelBuffer = new ColorBuffer32(photo.width, photo.height, photo.GetPixels32()); Texture oldtexture = photoRenderer.material.GetTexture("_MainTex"); Texture2D newTexture = new Texture2D(photo.width, photo.height, TextureFormat.RGB24, false); newTexture.SetPixels32(pixelBuffer.data); newTexture.Apply(); photoRenderer.material.SetTexture("_MainTex", newTexture); //pixelBuffer.data = BilateralFilterTexture.Process(photo); Debug.Log(string.Format("Pixel buffer size: {0}x{1}", newTexture.width, newTexture.height)); currentProject.SetPhoto(photo); ResetView(); FingerCanvas.Instance.SetupCanvas(); FingerCanvas.Instance.SaveUndo(); // We should wait for the UI to complete layout setup or will get wrong coordinates Invoke("ResetView", .01f); // Release old texture memory DestroyImmediate(oldPixelBuffer); DestroyImmediate(oldtexture, true); Resources.UnloadUnusedAssets(); System.GC.Collect(); }
public static ColorBuffer32 MedianFilter(ColorBuffer32 image, int size) { ColorBuffer32 newImage = new ColorBuffer32(image.width, image.height, new Color32[image.width * image.height]); int apertureMin = -(size / 2); int apertureMax = (size / 2); for (int x = 0; x < newImage.width; ++x) { for (int y = 0; y < newImage.height; ++y) { List <byte> rValues = new List <byte>(); List <byte> gValues = new List <byte>(); List <byte> bValues = new List <byte>(); for (int x2 = apertureMin; x2 < apertureMax; ++x2) { int tempX = x + x2; if (tempX >= 0 && tempX < newImage.width) { for (int y2 = apertureMin; y2 < apertureMax; ++y2) { int tempY = y + y2; if (tempY >= 0 && tempY < newImage.height) { Color32 tempColor = image[tempX, tempY]; rValues.Add(tempColor.r); gValues.Add(tempColor.g); bValues.Add(tempColor.b); } } } } rValues.Sort(); gValues.Sort(); bValues.Sort(); Color32 medianPixel = new Color32(rValues[rValues.Count / 2], gValues[gValues.Count / 2], bValues[bValues.Count / 2], (byte)255); newImage[x, y] = medianPixel; } } return(newImage); }
override public void TouchUp(Vector2 pos) { FingerCanvas.Instance.SetVisible(false); // Get the photo pixel buffer ColorBuffer32 picelBuffer = DecoratorPanel.Instance.GetPixelBuffer(); // Grab render texture pixels RenderTexture renderTexture = FingerCanvas.Instance.renderTexture; RenderTexture.active = renderTexture; if (masksTexture == null) { masksTexture = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.ARGB32, false); } masksTexture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0); masksTexture.Apply(); if (masksPixelBuffer == null) { masksPixelBuffer = new ColorBuffer32(masksTexture.width, masksTexture.height, masksTexture.GetPixels32()); } else { masksPixelBuffer.data = masksTexture.GetPixels32(); } // Do a flood fill only when the stroke is really short, (Tapping) if (GetStrokeRadius(strokePoints) < 10) { //FloodFillScanLine(startCanvasPosition, maskColors[ColorsManager.Instance.GetCurrentColor()], 0.2f, 0.35f, 0.025f, picelBuffer, masksPixelBuffer); StartCoroutine(FloodFill(startCanvasPosition, maskColors[ColorsManager.Instance.GetCurrentColor()], 0.2f, 0.35f, 0.025f, picelBuffer, masksPixelBuffer)); } else { Stroke(masksPixelBuffer, ColorsManager.Instance.GetCurrentColor()); UpdateMaskPixels(); } strokePoints.Clear(); }
private void Stroke(ColorBuffer32 masksBuffer, int currentColor) { switch (currentColor) { case 0: for (int i = 0; i < masksBuffer.data.Length; i++) { masksBuffer.data[i].r = (byte)Mathf.Clamp(masksBuffer.data[i].r + masksBuffer.data[i].a, 0, 255); } break; case 1: for (int i = 0; i < masksBuffer.data.Length; i++) { masksBuffer.data[i].g = (byte)Mathf.Clamp(masksBuffer.data[i].g + masksBuffer.data[i].a, 0, 255); } break; case 2: for (int i = 0; i < masksBuffer.data.Length; i++) { masksBuffer.data[i].b = (byte)Mathf.Clamp(masksBuffer.data[i].b + masksBuffer.data[i].a, 0, 255); } break; } }
IEnumerator FloodFill(Vector2 startPos, Color maskColor, float hueTolerance, float saturationTolerance, float valueTolerance, ColorBuffer32 pixelBuffer, ColorBuffer32 masksBuffer) { startTime = Time.time; DecoratorPanel.Instance.progressIndicator.SetActive(true); yield return(new WaitForEndOfFrame()); yield return(null); Color32 startColor = pixelBuffer[(int)startPos.x, (int)startPos.y]; Debug.Log(HSVColor.FromColor(startColor).ToString()); Point start = new Point((int)startPos.x, (int)startPos.y, startColor); ColorBuffer32 copyBmp = new ColorBuffer32(pixelBuffer.width, pixelBuffer.height, (Color32[])pixelBuffer.data.Clone()); copyBmp[start.x, start.y] = maskColor; Queue <Point> openNodes = new Queue <Point>(); openNodes.Enqueue(start); int i = 0; int emergency = pixelBuffer.width * pixelBuffer.height; while (openNodes.Count > 0) { i++; if (i > emergency) { yield break; } Point current = openNodes.Dequeue(); int x = current.x; int y = current.y; Color32 currentColor = current.color; if (x > 0 && copyBmp[x - 1, y] != Color.black && masksBuffer[x - 1, y] != maskColor) { ProcessPixel(x - 1, y, ref currentColor, startColor, maskColor, hueTolerance, saturationTolerance, valueTolerance, openNodes, pixelBuffer, masksBuffer, copyBmp); } if (x < pixelBuffer.width - 1 && copyBmp[x + 1, y] != Color.black && masksBuffer[x + 1, y] != maskColor) { ProcessPixel(x + 1, y, ref currentColor, startColor, maskColor, hueTolerance, saturationTolerance, valueTolerance, openNodes, pixelBuffer, masksBuffer, copyBmp); } if (y > 0 && copyBmp[x, y - 1] != Color.black && masksBuffer[x, y - 1] != maskColor) { ProcessPixel(x, y - 1, ref currentColor, startColor, maskColor, hueTolerance, saturationTolerance, valueTolerance, openNodes, pixelBuffer, masksBuffer, copyBmp); } if (y < pixelBuffer.height - 1 && copyBmp[x, y + 1] != Color.black && masksBuffer[x, y + 1] != maskColor) { ProcessPixel(x, y + 1, ref currentColor, startColor, maskColor, hueTolerance, saturationTolerance, valueTolerance, openNodes, pixelBuffer, masksBuffer, copyBmp); } } UpdateMaskPixels(); DecoratorPanel.Instance.progressIndicator.SetActive(false); Debug.Log(Time.time - startTime); }
void FloodFillScanLine(Vector2 startPos, Color maskColor, float hueTolerance, float saturationTolerance, float valueTolerance, ColorBuffer32 pixelBuffer, ColorBuffer32 masksBuffer) { Color32 targetColor = pixelBuffer[(int)startPos.x, (int)startPos.y]; Point start = new Point((int)startPos.x, (int)startPos.y, targetColor); ColorBuffer32 copyBmp = new ColorBuffer32(pixelBuffer.width, pixelBuffer.height, (Color32[])pixelBuffer.data.Clone()); Stack <Point> pixels = new Stack <Point>(); pixels.Push(start); float tolerance = 0.5f; while (pixels.Count != 0) { Point temp = pixels.Pop(); int y1 = temp.y; while (y1 >= 0 && ColorTest2(copyBmp[temp.x, y1], targetColor, targetColor, tolerance) == true) { y1--; } y1++; bool spanLeft = false; bool spanRight = false; while (y1 < pixelBuffer.height && ColorTest2(copyBmp[temp.x, y1], targetColor, targetColor, tolerance) == true) { copyBmp[temp.x, y1] = Color.black; masksBuffer[temp.x, y1] = maskColor; // Span left if (spanLeft == false && temp.x > 0 && ColorTest2(copyBmp[temp.x - 1, y1], targetColor, targetColor, tolerance) == true) { pixels.Push(new Point(temp.x - 1, y1)); spanLeft = true; } else if (spanLeft == true && temp.x > 0 && ColorTest2(copyBmp[temp.x - 1, y1], targetColor, targetColor, tolerance) != true) { spanLeft = false; } // Span right if (spanRight == false && temp.x < pixelBuffer.width - 1 && ColorTest2(copyBmp[temp.x + 1, y1], targetColor, targetColor, tolerance) == true) { pixels.Push(new Point(temp.x + 1, y1)); spanRight = true; } else if (spanRight == true && temp.x < pixelBuffer.width - 1 && ColorTest2(copyBmp[temp.x + 1, y1], targetColor, targetColor, tolerance) != true) { spanRight = false; } y1++; } } UpdateMaskPixels(); DecoratorPanel.Instance.progressIndicator.SetActive(false); }
private void ProcessPixel(int x, int y, ref Color32 currentColor, Color32 startColor, Color maskColor, float hueTolerance, float saturationTolerance, float valueTolerance, Queue <Point> openNodes, ColorBuffer32 pixelBuffer, ColorBuffer32 masksBuffer, ColorBuffer32 copyBmp) { Color32 pixel = copyBmp[x, y]; if (ColorTest(pixel, currentColor, startColor, 1) == true) { currentColor = pixel; copyBmp[x, y] = Color.black; masksBuffer[x, y] = maskColor; openNodes.Enqueue(new Point(x, y, currentColor)); } }