using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.IO;
namespace _20180127_8色に減色パターンディザ
{
<summary>
</summary>
public partial class MainWindow : Window
{
BitmapSource OriginBitmap;
string ImageFileFullPath;
string PatternName;
public MainWindow()
{
InitializeComponent();
this.Title = this.ToString();
this.AllowDrop = true;
this.Drop += MainWindow_Drop;
ButtonOrigin.Click += ButtonOrigin_Click;
ButtonTest1.Click += ButtonTest1_Click;
ButtonTest2.Click += ButtonTest2_Click;
ButtonTest3.Click += ButtonTest3_Click;
ButtonTest4.Click += ButtonTest4_Click;
ButtonTest5.Click += ButtonTest5_Click;
ButtonNotDithering.Click += ButtonNotDithering_Click;
NumericScrollBar.ValueChanged += NumericScrollBar_ValueChanged;
NumericTextBox.TextChanged += NumericTextBox_TextChanged;
ButtonSave.Click += ButtonSave_Click;
}
private void ButtonSave_Click(object sender, RoutedEventArgs e)
{
if (OriginBitmap == null) { return; }
SaveImage();
}
private void ButtonTest5_Click(object sender, RoutedEventArgs e)
{
if (OriginBitmap == null) { return; }
Matrix3x3_1();
PatternName = nameof(Matrix3x3_1);
}
private void ButtonTest4_Click(object sender, RoutedEventArgs e)
{
if (OriginBitmap == null) { return; }
Matrix4x4_1();
PatternName = nameof(Matrix4x4_1);
}
private void ButtonTest3_Click(object sender, RoutedEventArgs e)
{
if (OriginBitmap == null) { return; }
Matrix2x2_3();
PatternName = nameof(Matrix2x2_3);
}
private void ButtonTest2_Click(object sender, RoutedEventArgs e)
{
if (OriginBitmap == null) { return; }
Matrix2x2_2();
PatternName = nameof(Matrix2x2_2);
}
private void ButtonTest1_Click(object sender, RoutedEventArgs e)
{
if (OriginBitmap == null) { return; }
Matrix2x2_1();
PatternName = nameof(Matrix2x2_1);
}
private void ButtonNotDithering_Click(object sender, RoutedEventArgs e)
{
if (OriginBitmap == null) { return; }
MatrixThreshold();
}
private void NumericTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = (TextBox)sender;
double d;
if (!double.TryParse(textBox.Text, out d))
{
textBox.Text = System.Text.RegularExpressions.Regex.Replace(textBox.Text, "[^0-9]", "");
}
}
private void NumericScrollBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (OriginBitmap == null) { return; }
MatrixThreshold();
}
private void ButtonOrigin_Click(object sender, RoutedEventArgs e)
{
if (OriginBitmap == null) { return; }
MyImage.Source = OriginBitmap;
}
private void MainWindow_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop) == false) { return; }
string[] filePath = (string[])e.Data.GetData(DataFormats.FileDrop);
OriginBitmap = GetBitmapSourceWithChangePixelFormat2(filePath[0], PixelFormats.Pbgra32, 96, 96);
if (OriginBitmap == null)
{
MessageBox.Show("not Image");
}
else
{
MyImage.Source = OriginBitmap;
ImageFileFullPath = System.IO.Path.GetFullPath(filePath[0]);
}
}
private void MatrixThreshold()
{
double[][] thresholdMap = new double[][]
{
new double[] { NumericScrollBar.Value / 255 }
};
Change8ColorsWithDithering(thresholdMap);
}
private void Matrix2x2_1()
{
double[][] thresholdMap = new double[][]
{
new double[] { 1f / 5f, 3f / 5f },
new double[] { 4f / 5f, 2f / 5f }
};
Change8ColorsWithDithering(thresholdMap);
}
private void Matrix2x2_2()
{
double[][] thresholdMap = new double[][]
{
new double[] { 1f / 5f, 3f / 5f },
new double[] { 2f / 5f, 4f / 5f }
};
Change8ColorsWithDithering(thresholdMap);
}
private void Matrix2x2_3()
{
double[][] thresholdMap = new double[][]
{
new double[] { 1f / 5f, 2f / 5f },
new double[] { 3f / 5f, 4f / 5f }
};
Change8ColorsWithDithering(thresholdMap);
}
private void Matrix4x4_1()
{
double[][] thresholdMap = new double[][]
{
new double[] { 1f / 17f, 13f / 17f, 4f / 17f, 16f / 17f },
new double[] { 9f / 17f, 5f / 17f, 12f / 17f, 8f / 17f },
new double[] { 3f / 17f, 15f / 17f, 2f / 17f, 14f / 17f },
new double[] { 11f / 17f, 7f / 17f, 10f / 17f, 6f / 17f }
};
Change8ColorsWithDithering(thresholdMap);
}
private void Matrix3x3_1()
{
double[][] thresholdMap = new double[][]
{
new double[] { 1f / 10f, 9f / 10f, 5f / 10f },
new double[] { 8f / 10f, 2f / 10f, 6f / 10f },
new double[] { 4f / 10f, 7f / 10f, 3f / 10f }
};
Change8ColorsWithDithering(thresholdMap);
}
private void Change8ColorsWithDithering(double[][] thresholdMap)
{
var wb = new WriteableBitmap(OriginBitmap);
int h = wb.PixelHeight;
int w = wb.PixelWidth;
int stride = wb.BackBufferStride;
byte[] pixels = new byte[h * stride];
wb.CopyPixels(pixels, stride, 0);
long p = 0;
int xx = thresholdMap[0].Length;
int yy = thresholdMap.Length;
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
p = y * stride + (x * 4);
for (int i = 0; i < 3; ++i)
{
if ((double)pixels[p + i] / 256 < thresholdMap[y % yy][x % xx])
{ pixels[p + i] = 0; }
else { pixels[p + i] = 255; }
}
}
}
wb.WritePixels(new Int32Rect(0, 0, w, h), pixels, stride, 0);
MyImage.Source = wb;
}
private void SaveImage()
{
var saveFileDialog = new Microsoft.Win32.SaveFileDialog();
saveFileDialog.Filter = "*.png(index4)|*.png|*.bmp(index4)|*.bmp|*.tiff(index4)|*.tiff|*.wdp(index4)|*.wdp;*jxr|" +
"*.png|*.png|*.bmp|*.bmp|*.gif|*.gif|*.tiff|*.tiff|*.wdp|*.wdp;*jxr";
saveFileDialog.AddExtension = true;
saveFileDialog.InitialDirectory = System.IO.Path.GetDirectoryName(ImageFileFullPath);
saveFileDialog.FileName = System.IO.Path.GetFileNameWithoutExtension(ImageFileFullPath) + "_" + PatternName;
if (saveFileDialog.ShowDialog() == true)
{
BitmapEncoder encoder = null;
switch (saveFileDialog.FilterIndex)
{
case 1:
case 5:
encoder = new PngBitmapEncoder();
break;
case 2:
case 6:
encoder = new BmpBitmapEncoder();
break;
case 7:
encoder = new GifBitmapEncoder();
break;
case 3:
case 8:
var tiff = new TiffBitmapEncoder();
encoder = tiff;
break;
case 4:
case 9:
var wmp = new WmpBitmapEncoder();
wmp.ImageQualityLevel = 1.0f;
encoder = wmp;
break;
default:
break;
}
switch (saveFileDialog.FilterIndex)
{
case 1:
case 2:
case 3:
case 4:
encoder.Frames.Add(BitmapFrame.Create(new FormatConvertedBitmap((BitmapSource)MyImage.Source, PixelFormats.Indexed4, null, 0)));
break;
case 5:
case 6:
case 7:
case 8:
case 9:
encoder.Frames.Add(BitmapFrame.Create((BitmapSource)MyImage.Source));
break;
default:
break;
}
using (var fs = new FileStream(saveFileDialog.FileName, FileMode.Create, FileAccess.Write))
{
encoder.Save(fs);
}
}
}
private BitmapSource GetBitmapSourceWithChangePixelFormat2(
string filePath, PixelFormat pixelFormat, double dpiX = 0, double dpiY = 0)
{
BitmapSource source = null;
try
{
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
var bf = BitmapFrame.Create(fs);
var convertedBitmap = new FormatConvertedBitmap(bf, pixelFormat, null, 0);
int w = convertedBitmap.PixelWidth;
int h = convertedBitmap.PixelHeight;
int stride = (w * pixelFormat.BitsPerPixel + 7) / 8;
byte[] pixels = new byte[h * stride];
convertedBitmap.CopyPixels(pixels, stride, 0);
if (dpiX == 0) { dpiX = bf.DpiX; }
if (dpiY == 0) { dpiY = bf.DpiY; }
source = BitmapSource.Create(
w, h, dpiX, dpiY,
convertedBitmap.Format,
convertedBitmap.Palette, pixels, stride);
};
}
catch (Exception)
{
}
return source;
}
}
}