mirror of
https://github.com/jayfunc/BetterLyrics.git
synced 2026-01-12 19:24:55 +08:00
chores:
- Add album text in lyrics render - Improve song info update and draw algo - Upgrade to .NET 10
This commit is contained in:
@@ -20,12 +20,12 @@ namespace ColorThiefDotNet
|
||||
|
||||
public List<QuantizedColor> GeneratePalette()
|
||||
{
|
||||
if(palette == null)
|
||||
if (palette == null)
|
||||
{
|
||||
palette = (from vBox in vboxes
|
||||
let rgb = vBox.Avg(false)
|
||||
let color = FromRgb(rgb[0], rgb[1], rgb[2])
|
||||
select new QuantizedColor(color, vBox.Count(false))).ToList();
|
||||
let rgb = vBox.Avg(false)
|
||||
let color = FromRgb(rgb[0], rgb[1], rgb[2])
|
||||
select new QuantizedColor(color, vBox.Count(false))).ToList();
|
||||
}
|
||||
|
||||
return palette;
|
||||
@@ -38,7 +38,7 @@ namespace ColorThiefDotNet
|
||||
|
||||
public int[] Map(int[] color)
|
||||
{
|
||||
foreach(var vbox in vboxes.Where(vbox => vbox.Contains(color)))
|
||||
foreach (var vbox in vboxes.Where(vbox => vbox.Contains(color)))
|
||||
{
|
||||
return vbox.Avg(false);
|
||||
}
|
||||
@@ -50,13 +50,13 @@ namespace ColorThiefDotNet
|
||||
var d1 = double.MaxValue;
|
||||
int[] pColor = null;
|
||||
|
||||
foreach(var t in vboxes)
|
||||
foreach (var t in vboxes)
|
||||
{
|
||||
var vbColor = t.Avg(false);
|
||||
var d2 = Math.Sqrt(Math.Pow(color[0] - vbColor[0], 2)
|
||||
+ Math.Pow(color[1] - vbColor[1], 2)
|
||||
+ Math.Pow(color[2] - vbColor[2], 2));
|
||||
if(d2 < d1)
|
||||
if (d2 < d1)
|
||||
{
|
||||
d1 = d2;
|
||||
pColor = vbColor;
|
||||
@@ -71,20 +71,20 @@ namespace ColorThiefDotNet
|
||||
double maxValue = 0;
|
||||
var highestPopulation = vboxes.Select(p => p.Count(false)).Max();
|
||||
|
||||
foreach(var swatch in vboxes)
|
||||
foreach (var swatch in vboxes)
|
||||
{
|
||||
var avg = swatch.Avg(false);
|
||||
var hsl = FromRgb(avg[0], avg[1], avg[2]).ToHsl();
|
||||
var sat = hsl.S;
|
||||
var luma = hsl.L;
|
||||
|
||||
if(sat >= minSaturation && sat <= maxSaturation &&
|
||||
if (sat >= minSaturation && sat <= maxSaturation &&
|
||||
luma >= minLuma && luma <= maxLuma)
|
||||
{
|
||||
var thisValue = Mmcq.CreateComparisonValue(sat, targetSaturation, luma, targetLuma,
|
||||
swatch.Count(false), highestPopulation);
|
||||
|
||||
if(max == null || thisValue > maxValue)
|
||||
if (max == null || thisValue > maxValue)
|
||||
{
|
||||
max = swatch;
|
||||
maxValue = thisValue;
|
||||
|
||||
@@ -43,25 +43,25 @@ namespace ColorThiefDotNet
|
||||
double h1;
|
||||
|
||||
// ReSharper disable CompareOfFloatsByEqualityOperator
|
||||
if(chroma == 0)
|
||||
if (chroma == 0)
|
||||
{
|
||||
h1 = 0;
|
||||
}
|
||||
else if(max == r)
|
||||
else if (max == r)
|
||||
{
|
||||
h1 = (g - b) / chroma % 6;
|
||||
}
|
||||
else if(max == g)
|
||||
else if (max == g)
|
||||
{
|
||||
h1 = 2 + (b - r) / chroma;
|
||||
}
|
||||
else //if (max == b)
|
||||
{
|
||||
h1 = 4 + (r - g)/chroma;
|
||||
h1 = 4 + (r - g) / chroma;
|
||||
}
|
||||
|
||||
var lightness = 0.5 * (max - min);
|
||||
var saturation = chroma == 0 ? 0 : chroma / (1 - Math.Abs(2*lightness - 1));
|
||||
var saturation = chroma == 0 ? 0 : chroma / (1 - Math.Abs(2 * lightness - 1));
|
||||
HslColor ret;
|
||||
ret.H = 60 * h1;
|
||||
ret.S = saturation;
|
||||
@@ -83,7 +83,7 @@ namespace ColorThiefDotNet
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if(A == 255)
|
||||
if (A == 255)
|
||||
{
|
||||
return ToHexString();
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace ColorThiefDotNet
|
||||
{
|
||||
var pixelArray = await GetPixelsFast(sourceImage, quality, ignoreWhite);
|
||||
var cmap = GetColorMap(pixelArray, colorCount);
|
||||
if(cmap != null)
|
||||
if (cmap != null)
|
||||
{
|
||||
var colors = cmap.GeneratePalette();
|
||||
return colors;
|
||||
@@ -70,13 +70,13 @@ namespace ColorThiefDotNet
|
||||
|
||||
private async Task<byte[][]> GetPixelsFast(BitmapDecoder sourceImage, int quality, bool ignoreWhite)
|
||||
{
|
||||
if(quality < 1)
|
||||
if (quality < 1)
|
||||
{
|
||||
quality = DefaultQuality;
|
||||
}
|
||||
|
||||
var pixels = await GetIntFromPixel(sourceImage);
|
||||
var pixelCount = sourceImage.PixelWidth*sourceImage.PixelHeight;
|
||||
var pixelCount = sourceImage.PixelWidth * sourceImage.PixelHeight;
|
||||
|
||||
return ConvertPixels(pixels, Convert.ToInt32(pixelCount), quality, ignoreWhite);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows10.0.26100.0</TargetFramework>
|
||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||
<TargetFramework>net10.0-windows10.0.26100.0</TargetFramework>
|
||||
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
|
||||
<RootNamespace>ColorThief.WinUI3</RootNamespace>
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
|
||||
<UseWinUI>true</UseWinUI>
|
||||
|
||||
@@ -31,10 +31,10 @@ namespace ColorThiefDotNet
|
||||
|
||||
private byte[][] ConvertPixels(byte[] pixels, int pixelCount, int quality, bool ignoreWhite)
|
||||
{
|
||||
|
||||
|
||||
|
||||
var expectedDataLength = pixelCount * ColorDepth;
|
||||
if(expectedDataLength != pixels.Length)
|
||||
if (expectedDataLength != pixels.Length)
|
||||
{
|
||||
throw new ArgumentException("(expectedDataLength = "
|
||||
+ expectedDataLength + ") != (pixels.length = "
|
||||
@@ -52,7 +52,7 @@ namespace ColorThiefDotNet
|
||||
var numUsedPixels = 0;
|
||||
var pixelArray = new byte[numRegardedPixels][];
|
||||
|
||||
for(var i = 0; i < pixelCount; i += quality)
|
||||
for (var i = 0; i < pixelCount; i += quality)
|
||||
{
|
||||
var offset = i * ColorDepth;
|
||||
var b = pixels[offset];
|
||||
@@ -61,9 +61,9 @@ namespace ColorThiefDotNet
|
||||
var a = pixels[offset + 3];
|
||||
|
||||
// If pixel is mostly opaque and not white
|
||||
if(a >= 125 && !(ignoreWhite && r > 250 && g > 250 && b > 250))
|
||||
if (a >= 125 && !(ignoreWhite && r > 250 && g > 250 && b > 250))
|
||||
{
|
||||
pixelArray[numUsedPixels] = new[] {r, g, b};
|
||||
pixelArray[numUsedPixels] = new[] { r, g, b };
|
||||
numUsedPixels++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace ColorThiefDotNet
|
||||
{
|
||||
var histo = new int[Histosize];
|
||||
|
||||
foreach(var pixel in pixels)
|
||||
foreach (var pixel in pixels)
|
||||
{
|
||||
var rval = pixel[0] >> Rshift;
|
||||
var gval = pixel[1] >> Rshift;
|
||||
@@ -51,36 +51,36 @@ namespace ColorThiefDotNet
|
||||
|
||||
// find min/max
|
||||
var numPixels = pixels.Count;
|
||||
for(var i = 0; i < numPixels; i++)
|
||||
for (var i = 0; i < numPixels; i++)
|
||||
{
|
||||
var pixel = pixels[i];
|
||||
var rval = pixel[0] >> Rshift;
|
||||
var gval = pixel[1] >> Rshift;
|
||||
var bval = pixel[2] >> Rshift;
|
||||
|
||||
if(rval < rmin)
|
||||
if (rval < rmin)
|
||||
{
|
||||
rmin = rval;
|
||||
}
|
||||
else if(rval > rmax)
|
||||
else if (rval > rmax)
|
||||
{
|
||||
rmax = rval;
|
||||
}
|
||||
|
||||
if(gval < gmin)
|
||||
if (gval < gmin)
|
||||
{
|
||||
gmin = gval;
|
||||
}
|
||||
else if(gval > gmax)
|
||||
else if (gval > gmax)
|
||||
{
|
||||
gmax = gval;
|
||||
}
|
||||
|
||||
if(bval < bmin)
|
||||
if (bval < bmin)
|
||||
{
|
||||
bmin = bval;
|
||||
}
|
||||
else if(bval > bmax)
|
||||
else if (bval > bmax)
|
||||
{
|
||||
bmax = bval;
|
||||
}
|
||||
@@ -94,7 +94,7 @@ namespace ColorThiefDotNet
|
||||
int vboxDim1;
|
||||
int vboxDim2;
|
||||
|
||||
switch(color)
|
||||
switch (color)
|
||||
{
|
||||
case 'r':
|
||||
vboxDim1 = vbox.R1;
|
||||
@@ -110,9 +110,9 @@ namespace ColorThiefDotNet
|
||||
break;
|
||||
}
|
||||
|
||||
for(var i = vboxDim1; i <= vboxDim2; i++)
|
||||
for (var i = vboxDim1; i <= vboxDim2; i++)
|
||||
{
|
||||
if(partialsum[i] > total / 2)
|
||||
if (partialsum[i] > total / 2)
|
||||
{
|
||||
var vbox1 = vbox.Clone();
|
||||
var vbox2 = vbox.Clone();
|
||||
@@ -125,18 +125,18 @@ namespace ColorThiefDotNet
|
||||
: Math.Max(vboxDim1, Math.Abs(Convert.ToInt32(i - 1 - left / 2.0)));
|
||||
|
||||
// avoid 0-count boxes
|
||||
while(d2 < 0 || partialsum[d2] <= 0)
|
||||
while (d2 < 0 || partialsum[d2] <= 0)
|
||||
{
|
||||
d2++;
|
||||
}
|
||||
var count2 = lookaheadsum[d2];
|
||||
while(count2 == 0 && d2 > 0 && partialsum[d2 - 1] > 0)
|
||||
while (count2 == 0 && d2 > 0 && partialsum[d2 - 1] > 0)
|
||||
{
|
||||
count2 = lookaheadsum[--d2];
|
||||
}
|
||||
|
||||
// set dimensions
|
||||
switch(color)
|
||||
switch (color)
|
||||
{
|
||||
case 'r':
|
||||
vbox1.R2 = d2;
|
||||
@@ -152,7 +152,7 @@ namespace ColorThiefDotNet
|
||||
break;
|
||||
}
|
||||
|
||||
return new[] {vbox1, vbox2};
|
||||
return new[] { vbox1, vbox2 };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,13 +161,13 @@ namespace ColorThiefDotNet
|
||||
|
||||
private static VBox[] MedianCutApply(IList<int> histo, VBox vbox)
|
||||
{
|
||||
if(vbox.Count(false) == 0)
|
||||
if (vbox.Count(false) == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if(vbox.Count(false) == 1)
|
||||
if (vbox.Count(false) == 1)
|
||||
{
|
||||
return new[] {vbox.Clone(), null};
|
||||
return new[] { vbox.Clone(), null };
|
||||
}
|
||||
|
||||
// only one pixel, no split
|
||||
@@ -181,28 +181,28 @@ namespace ColorThiefDotNet
|
||||
var total = 0;
|
||||
var partialsum = new int[VboxLength];
|
||||
// -1 = not set / 0 = 0
|
||||
for(var l = 0; l < partialsum.Length; l++)
|
||||
for (var l = 0; l < partialsum.Length; l++)
|
||||
{
|
||||
partialsum[l] = -1;
|
||||
}
|
||||
|
||||
// -1 = not set / 0 = 0
|
||||
var lookaheadsum = new int[VboxLength];
|
||||
for(var l = 0; l < lookaheadsum.Length; l++)
|
||||
for (var l = 0; l < lookaheadsum.Length; l++)
|
||||
{
|
||||
lookaheadsum[l] = -1;
|
||||
}
|
||||
|
||||
int i, j, k, sum, index;
|
||||
|
||||
if(maxw == rw)
|
||||
if (maxw == rw)
|
||||
{
|
||||
for(i = vbox.R1; i <= vbox.R2; i++)
|
||||
for (i = vbox.R1; i <= vbox.R2; i++)
|
||||
{
|
||||
sum = 0;
|
||||
for(j = vbox.G1; j <= vbox.G2; j++)
|
||||
for (j = vbox.G1; j <= vbox.G2; j++)
|
||||
{
|
||||
for(k = vbox.B1; k <= vbox.B2; k++)
|
||||
for (k = vbox.B1; k <= vbox.B2; k++)
|
||||
{
|
||||
index = GetColorIndex(i, j, k);
|
||||
sum += histo[index];
|
||||
@@ -212,14 +212,14 @@ namespace ColorThiefDotNet
|
||||
partialsum[i] = total;
|
||||
}
|
||||
}
|
||||
else if(maxw == gw)
|
||||
else if (maxw == gw)
|
||||
{
|
||||
for(i = vbox.G1; i <= vbox.G2; i++)
|
||||
for (i = vbox.G1; i <= vbox.G2; i++)
|
||||
{
|
||||
sum = 0;
|
||||
for(j = vbox.R1; j <= vbox.R2; j++)
|
||||
for (j = vbox.R1; j <= vbox.R2; j++)
|
||||
{
|
||||
for(k = vbox.B1; k <= vbox.B2; k++)
|
||||
for (k = vbox.B1; k <= vbox.B2; k++)
|
||||
{
|
||||
index = GetColorIndex(j, i, k);
|
||||
sum += histo[index];
|
||||
@@ -231,12 +231,12 @@ namespace ColorThiefDotNet
|
||||
}
|
||||
else /* maxw == bw */
|
||||
{
|
||||
for(i = vbox.B1; i <= vbox.B2; i++)
|
||||
for (i = vbox.B1; i <= vbox.B2; i++)
|
||||
{
|
||||
sum = 0;
|
||||
for(j = vbox.R1; j <= vbox.R2; j++)
|
||||
for (j = vbox.R1; j <= vbox.R2; j++)
|
||||
{
|
||||
for(k = vbox.G1; k <= vbox.G2; k++)
|
||||
for (k = vbox.G1; k <= vbox.G2; k++)
|
||||
{
|
||||
index = GetColorIndex(j, k, i);
|
||||
sum += histo[index];
|
||||
@@ -247,9 +247,9 @@ namespace ColorThiefDotNet
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < VboxLength; i++)
|
||||
for (i = 0; i < VboxLength; i++)
|
||||
{
|
||||
if(partialsum[i] != -1)
|
||||
if (partialsum[i] != -1)
|
||||
{
|
||||
lookaheadsum[i] = total - partialsum[i];
|
||||
}
|
||||
@@ -273,10 +273,10 @@ namespace ColorThiefDotNet
|
||||
var ncolors = 1;
|
||||
var niters = 0;
|
||||
|
||||
while(niters < MaxIterations)
|
||||
while (niters < MaxIterations)
|
||||
{
|
||||
var vbox = lh[lh.Count - 1];
|
||||
if(vbox.Count(false) == 0)
|
||||
if (vbox.Count(false) == 0)
|
||||
{
|
||||
lh.Sort(comparator);
|
||||
niters++;
|
||||
@@ -290,25 +290,25 @@ namespace ColorThiefDotNet
|
||||
var vbox1 = vboxes[0];
|
||||
var vbox2 = vboxes[1];
|
||||
|
||||
if(vbox1 == null)
|
||||
if (vbox1 == null)
|
||||
{
|
||||
throw new Exception(
|
||||
"vbox1 not defined; shouldn't happen!");
|
||||
}
|
||||
|
||||
lh.Add(vbox1);
|
||||
if(vbox2 != null)
|
||||
if (vbox2 != null)
|
||||
{
|
||||
lh.Add(vbox2);
|
||||
ncolors++;
|
||||
}
|
||||
lh.Sort(comparator);
|
||||
|
||||
if(ncolors >= target)
|
||||
if (ncolors >= target)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(niters++ > MaxIterations)
|
||||
if (niters++ > MaxIterations)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -318,7 +318,7 @@ namespace ColorThiefDotNet
|
||||
public static CMap Quantize(byte[][] pixels, int maxcolors)
|
||||
{
|
||||
// short-circuit
|
||||
if(pixels.Length == 0 || maxcolors < 2 || maxcolors > 256)
|
||||
if (pixels.Length == 0 || maxcolors < 2 || maxcolors > 256)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
@@ -327,7 +327,7 @@ namespace ColorThiefDotNet
|
||||
|
||||
// get the beginning vbox from the colors
|
||||
var vbox = VboxFromPixels(pixels, histo);
|
||||
var pq = new List<VBox> {vbox};
|
||||
var pq = new List<VBox> { vbox };
|
||||
|
||||
// Round up to have the same behaviour as in JavaScript
|
||||
var target = (int)Math.Ceiling(FractByPopulation * maxcolors);
|
||||
@@ -347,7 +347,7 @@ namespace ColorThiefDotNet
|
||||
|
||||
// calculate the actual colors
|
||||
var cmap = new CMap();
|
||||
foreach(var vb in pq)
|
||||
foreach (var vb in pq)
|
||||
{
|
||||
cmap.Push(vb);
|
||||
}
|
||||
@@ -367,7 +367,7 @@ namespace ColorThiefDotNet
|
||||
double sum = 0;
|
||||
double sumWeight = 0;
|
||||
|
||||
for(var i = 0; i < values.Length; i += 2)
|
||||
for (var i = 0; i < values.Length; i += 2)
|
||||
{
|
||||
var value = values[i];
|
||||
var weight = values[i + 1];
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace ColorThiefDotNet
|
||||
|
||||
public int Volume(bool force)
|
||||
{
|
||||
if(volume == null || force)
|
||||
if (volume == null || force)
|
||||
{
|
||||
volume = (R2 - R1 + 1) * (G2 - G1 + 1) * (B2 - B1 + 1);
|
||||
}
|
||||
@@ -43,18 +43,18 @@ namespace ColorThiefDotNet
|
||||
|
||||
public int Count(bool force)
|
||||
{
|
||||
if(count == null || force)
|
||||
if (count == null || force)
|
||||
{
|
||||
var npix = 0;
|
||||
int i;
|
||||
|
||||
for(i = R1; i <= R2; i++)
|
||||
for (i = R1; i <= R2; i++)
|
||||
{
|
||||
int j;
|
||||
for(j = G1; j <= G2; j++)
|
||||
for (j = G1; j <= G2; j++)
|
||||
{
|
||||
int k;
|
||||
for(k = B1; k <= B2; k++)
|
||||
for (k = B1; k <= B2; k++)
|
||||
{
|
||||
var index = Mmcq.GetColorIndex(i, j, k);
|
||||
npix += histo[index];
|
||||
@@ -75,7 +75,7 @@ namespace ColorThiefDotNet
|
||||
|
||||
public int[] Avg(bool force)
|
||||
{
|
||||
if(avg == null || force)
|
||||
if (avg == null || force)
|
||||
{
|
||||
var ntot = 0;
|
||||
|
||||
@@ -85,13 +85,13 @@ namespace ColorThiefDotNet
|
||||
|
||||
int i;
|
||||
|
||||
for(i = R1; i <= R2; i++)
|
||||
for (i = R1; i <= R2; i++)
|
||||
{
|
||||
int j;
|
||||
for(j = G1; j <= G2; j++)
|
||||
for (j = G1; j <= G2; j++)
|
||||
{
|
||||
int k;
|
||||
for(k = B1; k <= B2; k++)
|
||||
for (k = B1; k <= B2; k++)
|
||||
{
|
||||
var histoindex = Mmcq.GetColorIndex(i, j, k);
|
||||
var hval = histo[histoindex];
|
||||
@@ -103,7 +103,7 @@ namespace ColorThiefDotNet
|
||||
}
|
||||
}
|
||||
|
||||
if(ntot > 0)
|
||||
if (ntot > 0)
|
||||
{
|
||||
avg = new[]
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user