Esempio n. 1
0
    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);
            }
        }
    }