using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace Straightener
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window
{
bool dimensionsLocked = false;
WriteableBitmap overlayImage;
AddedImage currentImage;
byte[] overlayPixels;
int width, height;
string saveDir;
bool internalChange = false;//this stops any ValueChanged events
double[] overlayCalc;
public MainWindow()
{
InitializeComponent();
}
private void openRefButton_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
if (saveDir != null)
dlg.InitialDirectory = saveDir;
else
dlg.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
dlg.Filter = "Image files (*.jpg)|*.jpg|All Files (*.*)|*.*";
dlg.RestoreDirectory = true;
if (dlg.ShowDialog() != System.Windows.Forms.DialogResult.OK)
return;
string selectedFileName = dlg.FileName;
AddedImage ai = new AddedImage(selectedFileName);
if (dimensionsLocked)
{
if(ai.pixelWidth!=width || ai.pixelHeight != height)
{
System.Windows.MessageBox.Show("Image dimensions do not match previously loaded!");
return;
}
}
else
{
width = ai.pixelWidth;
height = ai.pixelHeight;
overlayCalc = new double[width * 3 * height];
overlayPixels = new byte[width * 3 * height];
overlayImage = new WriteableBitmap(width, height, ai.dpiX, ai.dpiY, PixelFormats.Rgb24, null);
MyCanvas.Width = width;
MyCanvas.Height = height;
dimensionsLocked = true;
}
PicsList.Items.Add(ai);
PicsList.SelectedItem = ai;
showOverlay.IsEnabled = true;
saveDir = System.IO.Path.GetDirectoryName(selectedFileName);
MyScrollViewer.Visibility = Visibility.Visible;
}
private void resetUI()
{
showOverlay.IsChecked = false;
useBackground.IsChecked = false;
scaleAdds.IsChecked = false;
}
private void straightenButton_Click(object sender, RoutedEventArgs g)
{
SaveFileDialog dlg = new SaveFileDialog();
dlg.InitialDirectory = saveDir;
dlg.Filter = "Image files (*.jpg)|*.jpg|All Files (*.*)|*.*";
dlg.RestoreDirectory = true;
if (dlg.ShowDialog() != System.Windows.Forms.DialogResult.OK)
return;
string selectedFileName = dlg.FileName;
using (System.IO.FileStream stream5 = new System.IO.FileStream(selectedFileName, System.IO.FileMode.Create))
{
JpegBitmapEncoder encoder5 = new JpegBitmapEncoder();
encoder5.Frames.Add(BitmapFrame.Create(overlayImage));
encoder5.Save(stream5);
stream5.Close();
}
}
private void calculateOverlay()
{
if (PicsList.Items.Count < 1)
return;
//Add up the images
AddedImage bg = ((AddedImage)PicsList.Items[0]);
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
overlayCalc[x * 3 + y * width * 3] = bg.imagePixels[x * 3 + y * width * 3] * bg.add_factor;
overlayCalc[x * 3 + y * width * 3 + 1] = bg.imagePixels[x * 3 + y * width * 3 + 1] * bg.add_factor;
overlayCalc[x * 3 + y * width * 3 + 2] = bg.imagePixels[x * 3 + y * width * 3 + 2] * bg.add_factor;
}
}
if (useBackground.IsChecked == true)
{
for (int img = 1; img < PicsList.Items.Count; img++)
{
AddedImage ai = ((AddedImage)PicsList.Items[img]);
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
overlayCalc[x * 3 + y * width * 3] += (ai.imagePixels[x * 3 + y * width * 3] - bg.imagePixels[x * 3 + y * width * 3]) * ai.add_factor;
overlayCalc[x * 3 + y * width * 3 + 1] += (ai.imagePixels[x * 3 + y * width * 3 + 1] - bg.imagePixels[x * 3 + y * width * 3 + 1]) * ai.add_factor;
overlayCalc[x * 3 + y * width * 3 + 2] += (ai.imagePixels[x * 3 + y * width * 3 + 2] - bg.imagePixels[x * 3 + y * width * 3 + 2]) * ai.add_factor;
}
}
}
}
else
{
for (int img = 1; img < PicsList.Items.Count; img++)
{
AddedImage ai = ((AddedImage)PicsList.Items[img]);
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
overlayCalc[x * 3 + y * width * 3] += ai.imagePixels[x * 3 + y * width * 3] * ai.add_factor;
overlayCalc[x * 3 + y * width * 3 + 1] += ai.imagePixels[x * 3 + y * width * 3 + 1] * ai.add_factor;
overlayCalc[x * 3 + y * width * 3 + 2] += ai.imagePixels[x * 3 + y * width * 3 + 2] * ai.add_factor;
}
}
}
}
double min = 0, max = 255, v;
if (scaleAdds.IsChecked == true)
{
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
for (int c = 0; c < 3; c++)
{
if (overlayCalc[x * 3 + y * width * 3 + c] < min)
min = overlayCalc[x * 3 + y * width * 3 + c];
if (overlayCalc[x * 3 + y * width * 3 + c] > max)
max = overlayCalc[x * 3 + y * width * 3 + c];
}
}
}
double irng;
irng = 255 / (max - min);
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
for (int c = 0; c < 3; c++)
{
v = overlayCalc[x * 3 + y * width * 3 + c];
overlayPixels[x * 3 + y * width * 3 + c] = (byte)((v - min) * irng);
}
}
}
}
else
{
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
for (int c = 0; c < 3; c++)
{
v = overlayCalc[x * 3 + y * width * 3 + c];
if (v < min)
{
overlayPixels[x * 3 + y * width * 3 + c] = 0;
}
else
{
if (v > max)
{
overlayPixels[x * 3 + y * width * 3 + c] = 255;
}
else
{
overlayPixels[x * 3 + y * width * 3 + c] = (byte)v;
}
}
}
}
}
}
overlayImage.WritePixels(new Int32Rect(0, 0, width, height), overlayPixels, 3 * width, 0);
ovrImage.Source = overlayImage;
ovrImage.Width = width;
ovrImage.Height = height;
}
private void useBackground_Checked(object sender, RoutedEventArgs e)
{
if (showOverlay.IsChecked == true)
{
calculateOverlay();
displayOverlay();
}
}
private void useBackground_Unchecked(object sender, RoutedEventArgs e)
{
if (showOverlay.IsChecked == true)
{
calculateOverlay();
displayOverlay();
}
}
private void scaleAdds_Checked(object sender, RoutedEventArgs e)
{
if (showOverlay.IsChecked == true)
{
calculateOverlay();
displayOverlay();
}
}
private void scaleAdds_Unchecked(object sender, RoutedEventArgs e)
{
if (showOverlay.IsChecked == true)
{
calculateOverlay();
displayOverlay();
}
}
private void ovrTrnSlider_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
ovrTrnSlider.Value = 0;
}
private void hideOverlay()
{
straightenButton.IsEnabled = false;
ovrImage.Visibility = Visibility.Hidden;
}
private void displayOverlay()
{
ovrImage.Visibility = Visibility.Visible;
straightenButton.IsEnabled = true;
}
private void ovrTrnSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
{
if (currentImage == null || internalChange)
return;
currentImage.add_factor = ovrTrnSlider.Value;
if (showOverlay.IsChecked == true)
{
calculateOverlay();
displayOverlay();
}
}
private void PicsList_MouseWheel(object sender, MouseWheelEventArgs e)
{
if (currentImage == null)
return;
double v = ovrTrnSlider.Value;
v = v + e.Delta * 1e-4;
if (v > ovrTrnSlider.Maximum)
v = ovrTrnSlider.Maximum;
if (v < ovrTrnSlider.Minimum)
v = ovrTrnSlider.Minimum;
ovrTrnSlider.Value = v;
}
private void PicsList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
currentImage = (AddedImage)PicsList.SelectedItem;
if (currentImage == null)
return;
internalChange = true;
ovrTrnSlider.Value = currentImage.add_factor;
internalChange = false;
undrImage.Source = currentImage.referenceImage;
undrImage.Width = width;
undrImage.Height = height;
}
private void showOverlay_Checked(object sender, RoutedEventArgs e)
{
calculateOverlay();
displayOverlay();
}
private void showOverlay_Unchecked(object sender, RoutedEventArgs e)
{
hideOverlay();
if (currentImage == null)
return;
}
}
}