I'm working on page speed and Google PageSpeed Insights is telling me that my PNGs are just way too large. Sadly .NET does not provide any way to optimize PNG images so there is no easy fix - just unmanaged libraries and command line tools.
I have an allergy to manual processes so I've lashed up some code to automatically find and optimize PNGs in my App_Data folder using PNGCRUSH . I can call CrushAllImages() to fix up everything or CrushImage() when I need to fix up a specific PNG. Code below:
public static void CrushAllImages()
{
try
{
string appDataRoot = HostingEnvironment.MapPath("~/App_Data");
if (appDataRoot == null)
{
return;
}
DirectoryInfo directoryInfo = new DirectoryInfo(appDataRoot);
FileInfo[] pngs = directoryInfo.GetFiles("*.png", SearchOption.AllDirectories);
foreach (FileInfo png in pngs)
{
CrushImage(png.FullName);
}
}
catch (Exception ex)
{
//...
}
}
public static void CrushImage(string fullPath)
{
if (string.IsNullOrEmpty(fullPath))
{
return;
}
try
{
string markerPath = Path.ChangeExtension(fullPath, ".cng");
if (File.Exists(markerPath))
{
return;
}
string crushExe = HostingEnvironment.MapPath("~/App_Data/pngcrush_1_7_77_w32.exe");
ProcessStartInfo psi = new ProcessStartInfo(crushExe, string.Format(CultureInfo.InvariantCulture, "\"{0}\" \"{1}\"", fullPath, markerPath));
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
psi.LoadUserProfile = false;
psi.WorkingDirectory = HostingEnvironment.MapPath("~/App_Data");
Process p = Process.Start(psi);
if (p == null)
{
throw new InvalidOperationException("No Process!");
}
p.WaitForExit();
if (File.Exists(markerPath))
{
if (p.ExitCode == 0)
{
File.Copy(markerPath, fullPath, true);
File.WriteAllText(markerPath, "Processed");
}
else
{
SiteLog.Log.Add(LogSeverity.Error, "CrushImage Failed (non-0 exit code) for " + fullPath);
File.Delete(markerPath);
}
}
}
catch (Exception ex)
{
// ...
}
}
Add your comment...
Related Posts
(All Code Posts )
(Published to the Fediverse as:
Crushing PNGs in .NET #code #png #compression #crush #asp.net #mvc How to automatically reduce the size of PNG images for a .NET website using PNGCRUSH.
)