Skip to content

Commit

Permalink
+improving UX and optimizing
Browse files Browse the repository at this point in the history
  • Loading branch information
bahstrike committed Mar 16, 2022
1 parent 67978a6 commit 0f4a7fe
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 44 deletions.
73 changes: 52 additions & 21 deletions DyeAtlas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,13 @@ public Size ExportDimensions
}
}


// for caching current bitmap (not pnt)
private string lastFilename = null;
private DateTime lastFileWrite = new DateTime();
private Bitmap lastBitmap = null;


public void OpenFile(string file)
{
if (string.IsNullOrEmpty(file) || !File.Exists(file))
Expand Down Expand Up @@ -173,40 +180,64 @@ public void OpenFile(string file)
case ".tga":
case ".tiff":
{
Bitmap bmp = (Bitmap)Bitmap.FromFile(file);
DateTime modifyTime = new FileInfo(file).LastWriteTimeUtc;

// powers-of-2 automatic rescale
int newWidth = (int)Math.Pow(2.0, Math.Ceiling(Math.Log((double)bmp.Width) / Math.Log(2.0)));
int newHeight = (int)Math.Pow(2.0, Math.Ceiling(Math.Log((double)bmp.Height) / Math.Log(2.0)));
// do we already have a file open?
if (!string.IsNullOrEmpty(lastFilename))
{
// check if different/modified.. if so then invalidate our existing entry
if (!string.Equals(file, lastFilename, StringComparison.InvariantCultureIgnoreCase) || !modifyTime.Equals(lastFileWrite))
{
lastFilename = null;
lastFileWrite = new DateTime();
lastBitmap = null;
}
}

// clamp to allowable export dimensions (assumed power-of-2)
newWidth = Math.Min(ExportDimensions.Width, newWidth);
newHeight = Math.Min(ExportDimensions.Height, newHeight);

// hold onto yerr hats, its time to rescale!
if (newWidth != bmp.Width || newHeight != bmp.Height)
// only load if we need to
if (lastBitmap == null)
{
Bitmap newBmp = new Bitmap(newWidth, newHeight, PixelFormat.Format32bppArgb);
newBmp.SetResolution(bmp.HorizontalResolution, bmp.VerticalResolution);
Bitmap bmp = (Bitmap)Bitmap.FromFile(file);

// powers-of-2 automatic rescale
int newWidth = (int)Math.Pow(2.0, Math.Ceiling(Math.Log((double)bmp.Width) / Math.Log(2.0)));
int newHeight = (int)Math.Pow(2.0, Math.Ceiling(Math.Log((double)bmp.Height) / Math.Log(2.0)));

// clamp to allowable export dimensions (assumed power-of-2)
newWidth = Math.Min(ExportDimensions.Width, newWidth);
newHeight = Math.Min(ExportDimensions.Height, newHeight);

using (Graphics gfx = Graphics.FromImage(newBmp))
// hold onto yerr hats, its time to rescale!
if (newWidth != bmp.Width || newHeight != bmp.Height)
{
gfx.CompositingMode = CompositingMode.SourceCopy;
gfx.InterpolationMode = InterpolationMode.NearestNeighbor;
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
Bitmap newBmp = new Bitmap(newWidth, newHeight, PixelFormat.Format32bppArgb);
newBmp.SetResolution(bmp.HorizontalResolution, bmp.VerticalResolution);

using (ImageAttributes wrapMode = new ImageAttributes())
using (Graphics gfx = Graphics.FromImage(newBmp))
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
gfx.DrawImage(bmp, new Rectangle(0, 0, newWidth, newHeight), 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, wrapMode);
gfx.CompositingMode = CompositingMode.SourceCopy;
gfx.InterpolationMode = InterpolationMode.NearestNeighbor;
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;

using (ImageAttributes wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
gfx.DrawImage(bmp, new Rectangle(0, 0, newWidth, newHeight), 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, wrapMode);
}
}

bmp.Dispose();
bmp = newBmp;
}

bmp.Dispose();
bmp = newBmp;

lastFilename = file;
lastFileWrite = modifyTime;
lastBitmap = bmp;
}

pnt = PNTImage.GenerateFromBitmap(palette, bmp, dithering.Checked, hsvcompare.Checked);
pnt = PNTImage.GenerateFromBitmap(palette, lastBitmap, dithering.Checked, hsvcompare.Checked);
}
break;
}
Expand Down
12 changes: 9 additions & 3 deletions HSVSlidersPopup.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 13 additions & 15 deletions HSVSlidersPopup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public HSVSlidersPopup(DyeAtlas _dyeAtlas)
InitializeComponent();
}

void UpdateValues(bool reprocess=true)
DateTime? ValuesUpdatedTime = null;
void UpdateValues()
{
// cheating with static values lol
Palette.HueImportance = (double)hueTrack.Value / (double)(hueTrack.Maximum - hueTrack.Minimum);
Expand All @@ -35,14 +36,7 @@ void UpdateValues(bool reprocess=true)
satLabel.Text = $"Saturation Importance: {Palette.SaturationImportance.ToString("0.0")}";
valLabel.Text = $"Brightness Importance: {Palette.ValueImportance.ToString("0.0")}";


// maybe reprocess
if (reprocess)
{
Update();// flush before slow

dyeAtlas.Reprocess();
}
ValuesUpdatedTime = DateTime.Now;
}

public bool updating = false;
Expand All @@ -57,19 +51,14 @@ private void HSVSlidersPopup_Load(object sender, EventArgs e)


// just update labels
UpdateValues(false);
UpdateValues();
}

private void HSVSlidersPopup_FormClosing(object sender, FormClosingEventArgs e)
{
dyeAtlas.hsvcompare.Checked = false;// we dont wanna use HSV anymore
}

private void Track_Scroll(object sender, EventArgs e)
{
UpdateValues(false);
}

private void Track_ValueChanged(object sender, EventArgs e)
{
if (updating)
Expand All @@ -88,5 +77,14 @@ private void resetButton_Click(object sender, EventArgs e)

UpdateValues();
}

private void timer1_Tick(object sender, EventArgs e)
{
if(ValuesUpdatedTime.HasValue && DateTime.Now.Subtract(ValuesUpdatedTime.Value).TotalMilliseconds > 350)
{
dyeAtlas.Reprocess();
ValuesUpdatedTime = null;
}
}
}
}
3 changes: 3 additions & 0 deletions HSVSlidersPopup.resx
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,7 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>
22 changes: 17 additions & 5 deletions Palette.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public static Palette LoadFromCSV(Stream s)
int.Parse(parts[2].Substring(3, 2), System.Globalization.NumberStyles.HexNumber),
int.Parse(parts[2].Substring(5, 2), System.Globalization.NumberStyles.HexNumber)
);
DyeAtlas.ColorConversion.ColorToHSV(pe.color, out pe.h, out pe.s, out pe.v);
pal.entries.Add(pe);
}

Expand All @@ -41,6 +42,9 @@ public class PaletteEntry
public int index;
public string name;
public Color color;

// HSV color
public double h, s, v;//precached for performance
}

public Color? Get(int index)
Expand All @@ -60,6 +64,16 @@ public class PaletteEntry
public static double SaturationImportance = 0.0;
public static double ValueImportance = 0.0;


private void RegenerateHSVCache()
{
foreach (PaletteEntry pe in entries)
{
double aHue, aSat, aVal;
DyeAtlas.ColorConversion.ColorToHSV(pe.color, out aHue, out aSat, out aVal);
}
}

public int FindClosestIndex(Color clr, bool hsvCompare)
{
if (clr.A == 0)
Expand All @@ -73,15 +87,13 @@ public int FindClosestIndex(Color clr, bool hsvCompare)

if (hsvCompare)
{
double aHue, aSat, aVal;
double bHue, bSat, bVal;
DyeAtlas.ColorConversion.ColorToHSV(pe.color, out aHue, out aSat, out aVal);
DyeAtlas.ColorConversion.ColorToHSV(clr, out bHue, out bSat, out bVal);


double hueDiff = DyeAtlas.AngleDiff.distance(aHue, bHue) / 180.0;
double satDiff = Math.Abs(aSat - bSat);
double valDiff = Math.Abs(aVal - bVal);
double hueDiff = DyeAtlas.AngleDiff.distance(pe.h, bHue) / 180.0;
double satDiff = Math.Abs(pe.s - bSat);
double valDiff = Math.Abs(pe.v - bVal);

#if false
// just use our HSV comparison directly later
Expand Down

0 comments on commit 0f4a7fe

Please sign in to comment.