Added automatic bit depth detection for PNG encoding

This commit is contained in:
Jaex 2017-06-18 13:47:37 +03:00
parent 7d0040b61c
commit 34da140789
5 changed files with 99 additions and 20 deletions

View file

@ -36,6 +36,16 @@ public enum EDataType
URL
}
public enum PNGBitDepth // TODO: Translate
{
[Description("Automatically detect")]
Automatic,
[Description("32 bit (Supports transparency)")]
Bit32,
[Description("24 bit")]
Bit24
}
public enum GIFQuality // Localized
{
Default,

View file

@ -674,6 +674,14 @@ public static bool IsImagesEqual(Bitmap bmp1, Bitmap bmp2)
}
}
public static bool IsImageTransparent(Bitmap bmp)
{
using (UnsafeBitmap unsafeBitmap = new UnsafeBitmap(bmp, true, ImageLockMode.ReadOnly))
{
return unsafeBitmap.IsTransparent();
}
}
public static bool AddMetadata(Image img, int id, string text)
{
PropertyItem pi;

View file

@ -36,13 +36,7 @@ public unsafe class UnsafeBitmap : IDisposable
public int Width { get; private set; }
public int Height { get; private set; }
public int PixelCount
{
get
{
return Width * Height;
}
}
public int PixelCount => Width * Height;
private Bitmap bitmap;
private BitmapData bitmapData;
@ -129,6 +123,25 @@ public static bool Compare(UnsafeBitmap bmp1, UnsafeBitmap bmp2)
return true;
}
public bool IsTransparent()
{
int pixelCount = PixelCount;
ColorBgra* pointer = Pointer;
for (int i = 0; i < pixelCount; i++)
{
if (pointer->Alpha < 255)
{
return true;
}
pointer++;
}
return false;
}
public ColorBgra GetPixel(int i)
{
return Pointer[i];

View file

@ -288,29 +288,22 @@ public static string CreateThumbnail(Image img, string folder, string filename,
public static MemoryStream SaveImageAsStream(Image img, EImageFormat imageFormat, TaskSettings taskSettings)
{
return SaveImageAsStream(img, imageFormat, taskSettings.ImageSettings.ImageJPEGQuality, taskSettings.ImageSettings.ImageGIFQuality);
return SaveImageAsStream(img, imageFormat, taskSettings.ImageSettings.ImagePNGBitDepth,
taskSettings.ImageSettings.ImageJPEGQuality, taskSettings.ImageSettings.ImageGIFQuality);
}
public static MemoryStream SaveImageAsStream(Image img, EImageFormat imageFormat, int jpegQuality = 90, GIFQuality gifQuality = GIFQuality.Default)
public static MemoryStream SaveImageAsStream(Image img, EImageFormat imageFormat, PNGBitDepth pngBitDepth = PNGBitDepth.Automatic,
int jpegQuality = 90, GIFQuality gifQuality = GIFQuality.Default)
{
MemoryStream stream = new MemoryStream();
switch (imageFormat)
{
case EImageFormat.PNG:
img.Save(stream, ImageFormat.Png);
SaveImageAsPNGStream(img, stream, pngBitDepth);
break;
case EImageFormat.JPEG:
try
{
img = (Image)img.Clone();
img = ImageHelpers.FillBackground(img, Color.White);
img.SaveJPG(stream, jpegQuality);
}
finally
{
if (img != null) img.Dispose();
}
SaveImageAsJPEGStream(img, stream, jpegQuality);
break;
case EImageFormat.GIF:
img.SaveGIF(stream, gifQuality);
@ -326,6 +319,60 @@ public static MemoryStream SaveImageAsStream(Image img, EImageFormat imageFormat
return stream;
}
private static void SaveImageAsPNGStream(Image img, Stream stream, PNGBitDepth bitDepth)
{
if (bitDepth == PNGBitDepth.Automatic)
{
if (ImageHelpers.IsImageTransparent((Bitmap)img))
{
bitDepth = PNGBitDepth.Bit32;
}
else
{
bitDepth = PNGBitDepth.Bit24;
}
}
if (bitDepth == PNGBitDepth.Bit32)
{
if (img.PixelFormat != PixelFormat.Format32bppArgb && img.PixelFormat != PixelFormat.Format32bppRgb)
{
using (Bitmap bmpNew = ((Bitmap)img).Clone(new Rectangle(0, 0, img.Width, img.Height), PixelFormat.Format32bppArgb))
{
bmpNew.Save(stream, ImageFormat.Png);
return;
}
}
}
else if (bitDepth == PNGBitDepth.Bit24)
{
if (img.PixelFormat != PixelFormat.Format24bppRgb)
{
using (Bitmap bmpNew = ((Bitmap)img).Clone(new Rectangle(0, 0, img.Width, img.Height), PixelFormat.Format24bppRgb))
{
bmpNew.Save(stream, ImageFormat.Png);
return;
}
}
}
img.Save(stream, ImageFormat.Png);
}
private static void SaveImageAsJPEGStream(Image img, Stream stream, int jpegQuality)
{
try
{
img = (Image)img.Clone();
img = ImageHelpers.FillBackground(img, Color.White);
img.SaveJPG(stream, jpegQuality);
}
finally
{
if (img != null) img.Dispose();
}
}
public static void SaveImageAsFile(Image img, TaskSettings taskSettings)
{
using (ImageData imageData = PrepareImage(img, taskSettings))

View file

@ -272,6 +272,7 @@ public class TaskSettingsImage
#region Image / General
public EImageFormat ImageFormat = EImageFormat.PNG;
public PNGBitDepth ImagePNGBitDepth = PNGBitDepth.Automatic;
public int ImageJPEGQuality = 90;
public GIFQuality ImageGIFQuality = GIFQuality.Default;
public bool ImageAutoUseJPEG = true;