//saves the image as a .png image private async void SavePNG(object sender, RoutedEventArgs e) { LDRImage HDRPreview = new LDRImage(); await HDRPreview.LoadFromBytes(HDRI.Transform(), HDRI.Width, HDRI.Height); HDRPreview.SaveFile(); }
//Called when the play button is pressed private async void Recalculate(object sender, TappedRoutedEventArgs e) { //Re-renders the HDR image based on the new slider value HDRI = Blending.Blend(sliderValue / 100f, underExp, regExp, overExp); //Creates and displays a preview LDR image based off of the HDR image HDRPreview = new LDRImage(); await HDRPreview.LoadFromBytes(HDRI.Transform(), HDRI.Width, HDRI.Height); HDRImage.Source = HDRPreview.GetBitmapImage(); RecalculateButton.IsEnabled = false; }
/// <summary> /// Shows a specified channel in the loaded <see cref="HDRI"/> /// </summary> /// <param name="channel">I think 0 is red?</param> private async void ShowChannel(int channel) { SaveButton.IsEnabled = false; RecalculateButton.IsEnabled = false; BlenderSlider.IsEnabled = false; if (HDRI == null) { return; } calculated = new LDRImage(); await calculated.LoadFromBytes(HDRI.TransformChannel(channel), HDRI.Width, HDRI.Height); ShowCalculated(); }
//initially called when this page is loaded, will recieve the 3 LDR images loaded from the previous page in a List as a parameter protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); //loads the LDR images into the properities of this page List <LDRImage> LDRImages = (List <LDRImage>)e.Parameter; underExp = LDRImages[0]; regExp = LDRImages[1]; overExp = LDRImages[2]; //Renders the HDR image Recalculate(this, null); RecalculateButton.IsEnabled = false; }
//Loads overexposed image private async void LoadOverExp(object sender, TappedRoutedEventArgs e) { overExp = new LDRImage(); await overExp.Load(); if (overExp.GetBitmapImage() != null) { OverExp.Source = overExp.GetBitmapImage(); OverExpText.Opacity = 0.0; //activates the HDR rendering button if the other two images are loaded as well if (regExp != null && underExp != null) { HDRButton.IsEnabled = true; } } }
//------------------------------------------------------------------------// //blends the 3 different exposures //percent: percentage of underexposed pixels in the blend (float from 0 to 1) //top: how much to blend in the top layer (float from 0 to 1) public static void BlendOld (float percent, float top, LDRImage underExp, LDRImage regExp, LDRImage overExp, out byte[] bytes) { bytes = new Byte[regExp.GetDecoder().PixelHeight *regExp.GetDecoder().PixelWidth * 4]; //will contain the calculated brightness of all pixels in the underexposed image List <float> brightness = new List <float>(); // calcuates brightness for all pixels in the under exposed image, // then stores these brightness values in the brightness list for (int i = 0; i < underExp.GetDecoder().PixelHeight; i++) { for (int g = 0; g < underExp.GetDecoder().PixelWidth; g++) { int h = (i * (int)underExp.GetDecoder().PixelWidth + g) * 4; float bright = (float)Math.Sqrt((.299 * (underExp.GetBytes()[h] * underExp.GetBytes()[h]) + .587 * (underExp.GetBytes()[h + 1] * underExp.GetBytes()[h + 1]) + .114 * (underExp.GetBytes()[h + 2] * underExp.GetBytes()[h + 2]))); brightness.Add(bright); } } //sorts the brightness list from least to greatest brightness.Sort(); // Using the percent argument, find the appropriate value within the // sorted brightness array in order to come up with a partitioning // value int pixels = (int)underExp.GetDecoder().PixelWidth *(int)underExp.GetDecoder().PixelHeight; int partitionIndex = (int)(percent * pixels); float partition = brightness[partitionIndex]; // For each pixel in the overexposed image, find the corresponding underexposed // image pixel and use the partitioning value in order to determine whether or // not to replace it with the corresponding overexposed image pixel for (int i = 0; i < overExp.GetDecoder().PixelHeight; i++) { for (int g = 0; g < overExp.GetDecoder().PixelWidth; g++) { int h = (i * (int)overExp.GetDecoder().PixelWidth + g) * 4; if (partition < (float)Math.Sqrt((.299 * (underExp.GetBytes()[h] * underExp.GetBytes()[h]) + .587 * (underExp.GetBytes()[h + 1] * underExp.GetBytes()[h + 1]) + .114 * (underExp.GetBytes()[h + 2] * underExp.GetBytes()[h + 2])))) { for (int k = 0; k < 4; k++) { bytes[h + k] = underExp.GetBytes()[h + k]; } } else { for (int k = 0; k < 4; k++) { bytes[h + k] = overExp.GetBytes()[h + k]; } } } } // Blend the regular exposed image on top of the blended image // using the top argument for (int i = 0; i < regExp.GetDecoder().PixelHeight; i++) { for (int g = 0; g < regExp.GetDecoder().PixelWidth; g++) { int h = (i * (int)regExp.GetDecoder().PixelWidth + g) * 4; for (int k = 0; k < 3; k++) { float avg = (regExp.GetBytes()[h + k] - bytes[h + k]) * top; bytes[h + k] += (byte)avg; } } } }