void ComputeHistogram() { // Current camera MonoBehaviour target = (MonoBehaviour)this.target; CC_Levels comp = (CC_Levels)target.GetComponent <CC_Levels>(); Camera camera = target.GetComponent <Camera>(); // Grab the screen pixels comp.enabled = false; RenderTexture renderTexture = new RenderTexture(Screen.width, Screen.height, 24); camera.targetTexture = renderTexture; RenderTexture.active = renderTexture; camera.Render(); Texture2D screenTexture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false); screenTexture.filterMode = FilterMode.Point; screenTexture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0, false); Color32[] pixels = screenTexture.GetPixels32(); comp.enabled = true; // Compute the histogram int[] histogram = new int[256]; int l = pixels.Length; if (currentTab == 0) // Lum { for (int i = 0; i < l; i++) { histogram[(int)(pixels[i].r * 0.3f + pixels[i].g * 0.59f + pixels[i].b * 0.11f)]++; } } else if (currentTab == 1) // Red { for (int i = 0; i < l; i++) { histogram[pixels[i].r]++; } } else if (currentTab == 2) // Green { for (int i = 0; i < l; i++) { histogram[pixels[i].g]++; } } else if (currentTab == 3) // Blue { for (int i = 0; i < l; i++) { histogram[pixels[i].b]++; } } // Find max histogram value float max = 0; for (int i = 0; i < 256; i++) { max = (max < histogram[i]) ? histogram[i] : max; } float maxLog = Mathf.Log10(max); float factor = 128 / ((logarithmic) ? maxLog : max); // Blit the histogram texture pixels = histogramTexture.GetPixels32(); int index = 0; if (logarithmic) { for (int y = 0; y < 128; y++) { for (int x = 0; x < 256; x++) { pixels[index] = (((histogram[x] == 0) ? 0 : (int)(Mathf.Log10(histogram[x]) * factor)) >= y) ? fillColor : new Color32(0, 0, 0, 0); index++; } } } else { for (int y = 0; y < 128; y++) { for (int x = 0; x < 256; x++) { pixels[index] = ((histogram[x] * factor) >= y) ? fillColor : new Color32(0, 0, 0, 0); index++; } } } histogramTexture.SetPixels32(pixels); histogramTexture.Apply(); // Cleanup time RenderTexture.active = null; camera.targetTexture = null; DestroyImmediate(screenTexture); DestroyImmediate(renderTexture); }
void ComputeHistogram() { int channel = !p_isRGB.boolValue ? 0 : p_currentChannel.intValue + 1; // Current camera MonoBehaviour target = (MonoBehaviour)this.target; CC_Levels comp = (CC_Levels)target.GetComponent <CC_Levels>(); Camera camera = target.GetComponent <Camera>(); if (camera == null || !camera.enabled || !target.enabled || !target.gameObject.activeInHierarchy) { return; } // Prepare the texture to render the camera to. Base width will be 640 pixels (precision should be good enough // to get an histogram) and the height depends on the camera aspect ratio Texture2D cameraTexture = new Texture2D(640, (int)(640f * camera.aspect), TextureFormat.ARGB32, false, IsLinear); cameraTexture.hideFlags = HideFlags.HideAndDontSave; cameraTexture.filterMode = FilterMode.Point; RenderTexture rt = RenderTexture.GetTemporary(cameraTexture.width, cameraTexture.height, 24, RenderTextureFormat.ARGB32); // Backup the current states bool prevCompEnabled = comp.enabled; RenderTexture prevTargetTexture = camera.targetTexture; // Disable the current CC_Levels component, we don't want it to be applied before getting the histogram data comp.enabled = false; // Render camera.targetTexture = rt; RenderTexture.active = rt; camera.Render(); cameraTexture.ReadPixels(new Rect(0, 0, cameraTexture.width, cameraTexture.height), 0, 0, false); cameraTexture.Apply(); Color32[] pixels = cameraTexture.GetPixels32(); // Cleanup camera.targetTexture = prevTargetTexture; RenderTexture.active = null; RenderTexture.ReleaseTemporary(rt); DestroyImmediate(cameraTexture); comp.enabled = prevCompEnabled; // Gets the histogram for the given channel histogram = new int[256]; int l = pixels.Length; if (channel == 0) // Lum { for (int i = 0; i < l; i++) { histogram[(int)(pixels[i].r * 0.3f + pixels[i].g * 0.59f + pixels[i].b * 0.11f)]++; } } else if (channel == 1) // Red { for (int i = 0; i < l; i++) { histogram[pixels[i].r]++; } } else if (channel == 2) // Green { for (int i = 0; i < l; i++) { histogram[pixels[i].g]++; } } else if (channel == 3) // Blue { for (int i = 0; i < l; i++) { histogram[pixels[i].b]++; } } // Scale the histogram values float max = histogram.Max(); if (p_logarithmic.boolValue) // Log { float factor = 126f / Mathf.Log10(max); for (int i = 0; i < 256; i++) { histogram[i] = (histogram[i] == 0) ? 0 : (int)Mathf.Round(Mathf.Log10(histogram[i]) * factor); } } else // Linear { float factor = 126f / max; for (int i = 0; i < 256; i++) { histogram[i] = (int)Mathf.Round(histogram[i] * factor); } } }