Fixed dithering for images with 8-bit alph-channel (closes #8), applied dithering on images loading step to generate previews using dithered image
parent
b5916ab5ba
commit
128a3fa33e
|
@ -4,42 +4,50 @@ namespace Resources.Image
|
|||
{
|
||||
public class ColorError
|
||||
{
|
||||
public const int LowLevel = 0x00;
|
||||
public const int HighLevel = 0xff;
|
||||
public const int Treshold = 0x80;
|
||||
public const byte LowLevel = 0x00;
|
||||
public const byte HighLevel = 0xff;
|
||||
public const byte Treshold = 0x80;
|
||||
|
||||
public ColorError(Color original)
|
||||
{
|
||||
var r = original.R < Treshold ? LowLevel : HighLevel;
|
||||
var g = original.G < Treshold ? LowLevel : HighLevel;
|
||||
var b = original.B < Treshold ? LowLevel : HighLevel;
|
||||
var a = NewValue(original.A);
|
||||
var r = NewValue(original.R);
|
||||
var g = NewValue(original.G);
|
||||
var b = NewValue(original.B);
|
||||
|
||||
NewColor = Color.FromArgb(original.A, r, g, b);
|
||||
NewColor = Color.FromArgb(a, r, g, b);
|
||||
|
||||
ErrorA = original.A - a;
|
||||
ErrorR = original.R - r;
|
||||
ErrorG = original.G - g;
|
||||
ErrorB = original.B - b;
|
||||
}
|
||||
|
||||
public Color NewColor { get; }
|
||||
public int ErrorA { get; }
|
||||
public int ErrorR { get; }
|
||||
public int ErrorG { get; }
|
||||
public int ErrorB { get; }
|
||||
public bool IsZero => ErrorR == 0 && ErrorG == 0 && ErrorB == 0;
|
||||
public bool IsZero => ErrorA == 0 && ErrorR == 0 && ErrorG == 0 && ErrorB == 0;
|
||||
|
||||
public Color ApplyError(Color color, int part, int total)
|
||||
{
|
||||
return Color.FromArgb(
|
||||
NewColor.A,
|
||||
CheckBounds(color.A + ErrorA * part / total),
|
||||
CheckBounds(color.R + ErrorR * part / total),
|
||||
CheckBounds(color.G + ErrorG * part / total),
|
||||
CheckBounds(color.B + ErrorB * part / total)
|
||||
);
|
||||
}
|
||||
|
||||
private byte CheckBounds(int value)
|
||||
private static byte NewValue(byte value)
|
||||
{
|
||||
return (byte) (value < 0 ? 0 : (value > 255 ? 255 : value));
|
||||
return value < Treshold ? LowLevel : HighLevel;
|
||||
}
|
||||
|
||||
private static byte CheckBounds(int value)
|
||||
{
|
||||
return (byte) (value < LowLevel ? LowLevel : (value > HighLevel ? HighLevel : value));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,7 +37,6 @@ namespace Resources.Image
|
|||
_width = (ushort) image.Width;
|
||||
_height = (ushort) image.Height;
|
||||
|
||||
ApplyDithering();
|
||||
ExtractPalette();
|
||||
|
||||
if (_bitsPerPixel == 3) _bitsPerPixel = 4;
|
||||
|
@ -57,17 +56,6 @@ namespace Resources.Image
|
|||
WriteImage();
|
||||
}
|
||||
|
||||
private void ApplyDithering()
|
||||
{
|
||||
var clone = new Bitmap(_image.Width, _image.Height, PixelFormat.Format32bppArgb);
|
||||
using (var gr = Graphics.FromImage(clone))
|
||||
{
|
||||
gr.DrawImage(_image, new Rectangle(0, 0, clone.Width, clone.Height));
|
||||
}
|
||||
FloydSteinbergDitherer.Process(clone);
|
||||
_image = clone;
|
||||
}
|
||||
|
||||
private void ExtractPalette()
|
||||
{
|
||||
Logger.Trace("Extracting palette...");
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using NLog;
|
||||
using Resources.Image;
|
||||
|
||||
namespace Resources
|
||||
{
|
||||
|
@ -27,11 +29,25 @@ namespace Resources
|
|||
continue;
|
||||
}
|
||||
|
||||
var image = (Bitmap) System.Drawing.Image.FromFile(fullFileName);
|
||||
Logger.Trace("Image was loaded from file {0}", fullFileName);
|
||||
return (Bitmap) System.Drawing.Image.FromFile(fullFileName);
|
||||
return ApplyDithering(image);
|
||||
}
|
||||
|
||||
throw new FileNotFoundException($"File referenced by index {index} not found.");
|
||||
}
|
||||
|
||||
private static Bitmap ApplyDithering(Bitmap image)
|
||||
{
|
||||
var clone = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb);
|
||||
using (var gr = Graphics.FromImage(clone))
|
||||
{
|
||||
gr.DrawImage(image, new Rectangle(0, 0, clone.Width, clone.Height));
|
||||
}
|
||||
|
||||
FloydSteinbergDitherer.Process(clone);
|
||||
clone.Save("tmp.png");
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue