[WIP] Using single BItmap Generator

Changed to use a single bitmap generator
to try and simplify and standardise the way
that images are extracted from the games.
Have tried to use every method to extract
icons from icon files and from exes, but it's
still not quite right :(
This commit is contained in:
Terry MacDonald 2021-05-15 21:58:46 +12:00
parent 1366ef0ab2
commit 94d9da1b7c
4 changed files with 287 additions and 252 deletions

View File

@ -540,7 +540,7 @@ namespace DisplayMagician
var myIcon = System.Drawing.Icon.FromHandle(hIcon); var myIcon = System.Drawing.Icon.FromHandle(hIcon);
//myIcon.Dispose(); //myIcon.Dispose();
DestroyIcon(hIcon); //DestroyIcon(hIcon);
//CloseHandle(hIcon); //CloseHandle(hIcon);
return myIcon; return myIcon;

View File

@ -1,11 +1,15 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.Linq; using System.Linq;
using System.Drawing.IconLib;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using TsudaKageyu;
using DisplayMagicianShared;
namespace DisplayMagician namespace DisplayMagician
{ {
@ -126,9 +130,9 @@ namespace DisplayMagician
return newBitmap; return newBitmap;
} }
public static Bitmap ToLargeBitmap(string fileNameAndPath) /* public static Bitmap ToLargeBitmap(string fileNameAndPath)
{ {
Bitmap bm = null; Bitmap bmToReturn = null;
try try
{ {
@ -140,19 +144,42 @@ namespace DisplayMagician
if (fileNameAndPath.EndsWith(".ico")) if (fileNameAndPath.EndsWith(".ico"))
{ {
logger.Trace($"ShortcutItem/ToLargeBitmap: The file we want to get the image from is an icon file. Attempting to load the icon file from {fileNameAndPath}."); logger.Trace($"ShortcutItem/ToLargeBitmap: The file we want to get the image from is an icon file. Attempting to extract the icon file from {fileNameAndPath}.");
Icon icoIcon = new Icon(fileNameAndPath, 256, 256);
logger.Trace($"ShortcutItem/ToLargeBitmap: Attempting to convert the icon file {fileNameAndPath} to a bitmap."); Icon myIcon = new Icon(fileNameAndPath,128,128);
bm = icoIcon.ToBitmap(); bmToReturn = myIcon.ToBitmap();
logger.Trace($"ShortcutItem/ToLargeBitmap: Emptying the memory area used but the icon to stop memory leaks."); MultiIcon myMultiIcon = new MultiIcon();
icoIcon.Dispose(); SingleIcon mySingleIcon = myMultiIcon.Add("Icon1");
//mySingleIcon.CreateFrom(fileNameAndPath,IconOutputFormat.Vista);
mySingleIcon.Load(fileNameAndPath);
Bitmap bm = null;
foreach (IconImage myIconImage in mySingleIcon)
{
bm = myIconImage.Image;
if (bm.Width > bmToReturn.Width && bm.Height > bmToReturn.Height)
{
bmToReturn = bm;
logger.Trace($"ShortcutItem/ToLargeBitmap: This new bitmap from the icon file {fileNameAndPath} is larger than the previous one at {bm.Width} x {bm.Height}, so using that instead.");
}
}
} }
else else
{ {
Icon myIcon = Icon.ExtractAssociatedIcon(fileNameAndPath);
bmToReturn = myIcon.ToBitmap();
logger.Trace($"ShortcutItem/ToLargeBitmap: The file {fileNameAndPath} isn't an Icon file, so trying to use GetLargeBitmapFromFile to extract the image."); logger.Trace($"ShortcutItem/ToLargeBitmap: The file {fileNameAndPath} isn't an Icon file, so trying to use GetLargeBitmapFromFile to extract the image.");
bm = IconFromFile.GetLargeBitmapFromFile(fileNameAndPath, true, false); Bitmap bm = null;
bm = IconFromFile.GetLargeBitmapFromFile(fileNameAndPath, false, false);
if (bm.Width > bmToReturn.Width && bm.Height > bmToReturn.Height)
{
bmToReturn = bm;
logger.Trace($"ShortcutItem/ToLargeBitmap: This new bitmap from the icon file {fileNameAndPath} is larger than the previous one at {bm.Width} x {bm.Height}, so using that instead.");
} }
return bm; }
return bmToReturn;
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -160,8 +187,8 @@ namespace DisplayMagician
try try
{ {
logger.Trace($"ShortcutItem/ToLargeBitmap: Attempt2. The file {fileNameAndPath} isn't an Icon file, so trying to use GetLargeBitmapFromFile to extract the image."); logger.Trace($"ShortcutItem/ToLargeBitmap: Attempt2. The file {fileNameAndPath} isn't an Icon file, so trying to use GetLargeBitmapFromFile to extract the image.");
bm = IconFromFile.GetLargeBitmapFromFile(fileNameAndPath, true, false); bmToReturn = IconFromFile.GetLargeBitmapFromFile(fileNameAndPath, true, false);
return bm; return bmToReturn;
} }
catch (Exception innerex) catch (Exception innerex)
{ {
@ -171,7 +198,7 @@ namespace DisplayMagician
} }
} }
public static Bitmap ToLargeBitmap(List<string> fileNamesAndPaths) public static Bitmap ToLargeBitmap(ArrayList fileNamesAndPaths)
{ {
Bitmap bmToReturn = null; Bitmap bmToReturn = null;
@ -183,46 +210,7 @@ namespace DisplayMagician
} }
foreach (string fileNameAndPath in fileNamesAndPaths) foreach (string fileNameAndPath in fileNamesAndPaths)
{ {
Bitmap bm = null; Bitmap bm = ToLargeBitmap(fileNameAndPath);
try
{
if (String.IsNullOrWhiteSpace(fileNameAndPath))
{
logger.Warn($"ShortcutItem/ToLargeBitmap2: Bitmap fileNameAndPath is empty! Trying next file in fileNamesAndPaths list.");
continue;
}
if (fileNameAndPath.EndsWith(".ico"))
{
logger.Trace($"ShortcutItem/ToLargeBitmap2: The file we want to get the image from is an icon file. Attempting to load the icon file from {fileNameAndPath}.");
Icon icoIcon = new Icon(fileNameAndPath, 256, 256);
logger.Trace($"ShortcutItem/ToLargeBitmap2: Attempting to convert the icon file {fileNameAndPath} to a bitmap.");
bm = icoIcon.ToBitmap();
logger.Trace($"ShortcutItem/ToLargeBitmap2: Emptying the memory area used but the icon to stop memory leaks.");
icoIcon.Dispose();
}
else
{
logger.Trace($"ShortcutItem/ToLargeBitmap2: The file {fileNameAndPath} isn't an Icon file, so trying to use GetLargeBitmapFromFile to extract the image.");
bm = IconFromFile.GetLargeBitmapFromFile(fileNameAndPath, true, true);
}
}
catch (Exception ex)
{
logger.Warn(ex, $"ShortcutItem/ToLargeBitmap2: Exception while trying to save the Shortcut icon initially. Trying again with GetLargeBitmapFromFile.");
try
{
logger.Trace($"ShortcutItem/ToLargeBitmap2: Attempt2. The file {fileNameAndPath} isn't an Icon file, so trying to use GetLargeBitmapFromFile to extract the image.");
bm = IconFromFile.GetLargeBitmapFromFile(fileNameAndPath, true, true);
bmToReturn = bm;
}
catch (Exception innerex)
{
logger.Warn(innerex, $"ShortcutItem/ToLargeBitmap2: Exception while trying to save the Shortcut icon a second time. Giving up.");
continue;
}
}
if (bmToReturn == null) if (bmToReturn == null)
{ {
@ -235,11 +223,11 @@ namespace DisplayMagician
} }
return bmToReturn; return bmToReturn;
} }*/
public static Bitmap ToSmallBitmap(string fileNameAndPath) public static Bitmap GetMeABitmapFromFile(string fileNameAndPath)
{ {
Bitmap bm = null; Bitmap bmToReturn = null;
try try
{ {
@ -249,30 +237,69 @@ namespace DisplayMagician
return null; return null;
} }
Icon myIcon = null;
Bitmap bm = null;
if (fileNameAndPath.EndsWith(".ico")) if (fileNameAndPath.EndsWith(".ico"))
{ {
logger.Trace($"ShortcutItem/ToSmallBitmap: The file we want to get the image from is an icon file. Attempting to load the icon file from {fileNameAndPath}."); logger.Trace($"ShortcutItem/ToSmallBitmap: The file we want to get the image from is an icon file. Attempting to extract the icon file from {fileNameAndPath}.");
Size iconSize = new Size(128, 128); myIcon = new Icon(fileNameAndPath, 128, 128);
Icon iconToReturn = new Icon(fileNameAndPath, iconSize); //Icon myIcon = Icon.ExtractAssociatedIcon(fileNameAndPath);
/*if (iconToReturn.Size.Width < iconSize.Width || iconToReturn.Size.Height < iconSize.Height) bmToReturn = myIcon.ToBitmap();
MultiIcon myMultiIcon = new MultiIcon();
SingleIcon mySingleIcon = myMultiIcon.Add("Icon1");
mySingleIcon.CreateFrom(fileNameAndPath, IconOutputFormat.Vista);
foreach (IconImage myIconImage in mySingleIcon)
{ {
// If the Icon is too small then we should try the Exe itself to see if its bigger bm = myIconImage.Image;
bm = IconFromFile.GetSmallBitmapFromFile(fileNameAndPath, false, false, false);
}*/ if (bm.Width > bmToReturn.Width && bm.Height > bmToReturn.Height)
//Icon iconToReturn = IconFromFile.GetLargeIconFromFile(fileNameAndPath, true, true); {
//Icon iconToReturn = IconUtil.TryGetIcon(myIcon,iconSize,24,true,true); bmToReturn = bm;
logger.Trace($"ShortcutItem/ToSmallBitmap: Attempting to convert the icon file {fileNameAndPath} to a bitmap."); logger.Trace($"ShortcutItem/ToSmallBitmap: This new bitmap from the icon file {fileNameAndPath} is larger than the previous one at {bm.Width} x {bm.Height}, so using that instead.");
bm = iconToReturn.ToBitmap(); }
logger.Trace($"ShortcutItem/ToSmallBitmap: Emptying the memory area used but the icon to stop memory leaks."); }
iconToReturn.Dispose();
myIcon = Icon.ExtractAssociatedIcon(fileNameAndPath);
bm = myIcon.ToBitmap();
if (bm.Width > bmToReturn.Width && bm.Height > bmToReturn.Height)
{
bmToReturn = bm;
logger.Trace($"ShortcutItem/ToSmallBitmap: This new bitmap from the icon file {fileNameAndPath} is larger than the previous one at {bm.Width} x {bm.Height}, so using that instead.");
}
} }
else else
{ {
logger.Trace($"ShortcutItem/ToSmallBitmap: The file {fileNameAndPath} isn't an Icon file, so trying to use GetSmallBitmapFromFile to extract the image."); myIcon = Icon.ExtractAssociatedIcon(fileNameAndPath);
bmToReturn = myIcon.ToBitmap();
logger.Trace($"ShortcutItem/ToSmallBitmap: The file {fileNameAndPath} isn't an Icon file, so trying to use GetLargeBitmapFromFile to extract the image.");
//bm = IconFromFile.GetSmallBitmapFromFile(fileNameAndPath, false, false, false);
bm = IconFromFile.GetSmallBitmapFromFile(fileNameAndPath, false, false, false); bm = IconFromFile.GetSmallBitmapFromFile(fileNameAndPath, false, false, false);
if (bm.Width > bmToReturn.Width && bm.Height > bmToReturn.Height)
{
bmToReturn = bm;
logger.Trace($"ShortcutItem/ToSmallBitmap: This new bitmap from the icon file {fileNameAndPath} is larger than the previous one at {bm.Width} x {bm.Height}, so using that instead.");
} }
return bm;
IconExtractor ie = new IconExtractor(fileNameAndPath);
Icon[] allIcons = ie.GetAllIcons();
foreach (Icon myExtractedIcon in allIcons)
{
bm = myExtractedIcon.ToBitmap();
if (bm.Width > bmToReturn.Width && bm.Height > bmToReturn.Height)
{
bmToReturn = bm;
logger.Trace($"ShortcutItem/ToSmallBitmap: This new bitmap from the icon file {fileNameAndPath} is larger than the previous one at {bm.Width} x {bm.Height}, so using that instead.");
}
}
}
return bmToReturn;
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -280,8 +307,8 @@ namespace DisplayMagician
try try
{ {
logger.Trace($"ShortcutItem/ToSmallBitmap: Attempt2. The file {fileNameAndPath} isn't an Icon file, so trying to use GetSmallBitmapFromFile to extract the image."); logger.Trace($"ShortcutItem/ToSmallBitmap: Attempt2. The file {fileNameAndPath} isn't an Icon file, so trying to use GetSmallBitmapFromFile to extract the image.");
bm = IconFromFile.GetSmallBitmapFromFile(fileNameAndPath, false, false, false); bmToReturn = IconFromFile.GetSmallBitmapFromFile(fileNameAndPath, false, false, false);
return bm; return bmToReturn;
} }
catch (Exception innerex) catch (Exception innerex)
{ {
@ -291,7 +318,7 @@ namespace DisplayMagician
} }
} }
public static Bitmap ToSmallBitmap(List<string> fileNamesAndPaths) public static Bitmap GetMeABitmapFromFile(ArrayList fileNamesAndPaths)
{ {
Bitmap bmToReturn = null; Bitmap bmToReturn = null;
@ -303,46 +330,7 @@ namespace DisplayMagician
} }
foreach (string fileNameAndPath in fileNamesAndPaths) foreach (string fileNameAndPath in fileNamesAndPaths)
{ {
Bitmap bm = null; Bitmap bm = GetMeABitmapFromFile(fileNameAndPath);
try
{
if (String.IsNullOrWhiteSpace(fileNameAndPath))
{
logger.Warn($"ShortcutItem/ToSmallBitmap2: Bitmap fileNameAndPath is empty! Trying next file in fileNamesAndPaths list.");
continue;
}
if (fileNameAndPath.EndsWith(".ico"))
{
logger.Trace($"ShortcutItem/ToSmallBitmap2: The file we want to get the image from is an icon file. Attempting to load the icon file from {fileNameAndPath}.");
Icon icoIcon = new Icon(fileNameAndPath, 128, 128);
logger.Trace($"ShortcutItem/ToSmallBitmap2: Attempting to convert the icon file {fileNameAndPath} to a bitmap.");
bm = icoIcon.ToBitmap();
logger.Trace($"ShortcutItem/ToSmallBitmap2: Emptying the memory area used but the icon to stop memory leaks.");
icoIcon.Dispose();
}
else
{
logger.Trace($"ShortcutItem/ToSmallBitmap2: The file {fileNameAndPath} isn't an Icon file, so trying to use GetLargeBitmapFromFile to extract the image.");
bm = IconFromFile.GetLargeBitmapFromFile(fileNameAndPath, true, false);
}
}
catch (Exception ex)
{
logger.Warn(ex, $"ShortcutItem/ToSmallBitmap2: Exception while trying to save the Shortcut icon initially. Trying again with GetLargeBitmapFromFile.");
try
{
logger.Trace($"ShortcutItem/ToSmallBitmap2: Attempt2. The file {fileNameAndPath} isn't an Icon file, so trying to use GetLargeBitmapFromFile to extract the image.");
bm = IconFromFile.GetLargeBitmapFromFile(fileNameAndPath, true, false);
bmToReturn = bm;
}
catch (Exception innerex)
{
logger.Warn(innerex, $"ShortcutItem/ToSmallBitmap2: Exception while trying to save the Shortcut icon a second time. Giving up.");
continue;
}
}
if (bmToReturn == null) if (bmToReturn == null)
{ {
@ -359,5 +347,136 @@ namespace DisplayMagician
return bmToReturn; return bmToReturn;
} }
public static Bitmap ToBitmapOverlay(Bitmap originalBitmap, Bitmap overlayBitmap, int width, int height, PixelFormat format = PixelFormat.Format32bppArgb)
{
if (originalBitmap == null)
{
logger.Trace($"ShortcutItem/ToBitmapOverlay: OriginalBitmap is null, so we'll try to make the BitmapOverlay using GameLibrary Icon.");
return null;
} }
if (overlayBitmap == null)
{
logger.Trace($"ShortcutItem/ToBitmapOverlay: overlayBitmap is null, so we'll just return the original bitmap without a profile overlay.");
return originalBitmap;
}
if (width <= 0 || width > 256)
{
logger.Trace($"ShortcutItem/ToBitmapOverlay: Width is out of range so setting to 256.");
width = 256;
}
if (height <= 0 || height > 256)
{
logger.Trace($"ShortcutItem/ToBitmapOverlay: Height is out of range so setting to 256.");
height = 256;
}
// Figure out sizes and positions
try
{
Size targetSize = new Size(width, height);
logger.Trace($"ShortcutItem/ToBitmapOverlay: TargetSize is {targetSize.Width}px x {targetSize.Height}px.");
Size originalBitmapCurrentSize = new Size(originalBitmap.Width, originalBitmap.Height);
logger.Trace($"ShortcutItem/ToBitmapOverlay: originalBitmapCurrentSize is {originalBitmapCurrentSize.Width}px x {originalBitmapCurrentSize.Height}px.");
Size overlaylBitmapCurrentSize = new Size(overlayBitmap.Width, overlayBitmap.Height);
logger.Trace($"ShortcutItem/ToBitmapOverlay: overlaylBitmapCurrentSize is {overlaylBitmapCurrentSize.Width}px x {overlaylBitmapCurrentSize.Height}px.");
// Make a new empty bitmap of the wanted size
logger.Trace($"ShortcutItem/ToBitmapOverlay: Making a new combined bitmap as the base for the image.");
var combinedBitmap = new Bitmap(targetSize.Width, targetSize.Height, format);
combinedBitmap.MakeTransparent();
using (var g = Graphics.FromImage(combinedBitmap))
{
logger.Trace($"ShortcutItem/ToBitmapOverlay: Setting smoothing mode, Interpolation mode, pixel offset mode and compositing quality.");
g.SmoothingMode = SmoothingMode.None;
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.AssumeLinear;
// Resize the originalBitmap if needed then draw it
Size originalBitmapNewSize = ResizeDrawing.FitWithin(originalBitmapCurrentSize, targetSize);
logger.Trace($"ShortcutItem/ToBitmapOverlay: Resizing the original bitmap to fit in the new combined bitmap. Size is now {originalBitmapNewSize.Width}px x {originalBitmapNewSize.Height}px");
Point originalBitmapNewLocation = ResizeDrawing.AlignCenter(originalBitmapNewSize, targetSize);
logger.Trace($"ShortcutItem/ToBitmapOverlay: Drawing the original bitmap into the new combined bitmap at position {originalBitmapNewLocation.X},{originalBitmapNewLocation.Y}..");
g.DrawImage(originalBitmap, originalBitmapNewLocation.X, originalBitmapNewLocation.Y, originalBitmapNewSize.Width, originalBitmapNewSize.Height);
// Resize the overlayBitmap if needed then draw it in the bottom-right corner
Size overlayBitmapMaxSize = ResizeDrawing.FitWithin(overlaylBitmapCurrentSize, targetSize);
Size overlayBitmapNewSize = ResizeDrawing.MakeSmaller(overlayBitmapMaxSize, 70);
logger.Trace($"ShortcutItem/ToBitmapOverlay: Resize the overlay bitmap to fit in the bottom right corner of the new combined bitmap. Size is now {overlayBitmapNewSize.Width}px x {overlayBitmapNewSize.Height}px");
Point overlayBitmapNewLocation = ResizeDrawing.AlignBottomRight(overlayBitmapNewSize, targetSize);
logger.Trace($"ShortcutItem/ToBitmapOverlay: Drawing the overlay bitmap into the new combined bitmap at position {overlayBitmapNewLocation.X},{overlayBitmapNewLocation.Y}.");
g.DrawImage(overlayBitmap, overlayBitmapNewLocation.X, overlayBitmapNewLocation.Y, overlayBitmapNewSize.Width, overlayBitmapNewSize.Height);
}
return combinedBitmap;
}
catch (Exception ex)
{
logger.Warn(ex, $"ShortcutItem/ToBitmapOverlay: Exception while trying to add the overlay to the Bitmap. Returning null");
return null;
}
}
#pragma warning disable CS3002 // Return type is not CLS-compliant
public static MultiIcon ToIconOverlay(Bitmap originalBitmap, Bitmap overlayBitmap)
#pragma warning restore CS3002 // Return type is not CLS-compliant
{
try
{
Size[] iconSizes = new[]
{
new Size(256, 256),
new Size(64, 64),
new Size(48, 48),
new Size(32, 32),
new Size(24, 24),
new Size(16, 16)
};
logger.Trace($"ShortcutItem/ToIconOverlay: Creating the new Multi image Icon.");
MultiIcon multiIcon = new MultiIcon();
logger.Trace($"ShortcutItem/ToIconOverlay: Adding a single icon to the multi image icon.");
SingleIcon icon = multiIcon.Add("Icon1");
foreach (Size size in iconSizes)
{
logger.Trace($"ShortcutItem/ToIconOverlay: Creating a new image layer of size {size.Width}px x {size.Height}px.");
Bitmap bitmapOverlay = ToBitmapOverlay(originalBitmap, overlayBitmap, size.Width, size.Height);
if (bitmapOverlay == null)
{
logger.Warn($"ShortcutItem/ToIconOverlay: bitmapOverlay is null, so we can't turn it into an Icon Overlay. Returning null");
return null;
}
logger.Trace($"ShortcutItem/ToIconOverlay: Adding the new image layer of size {size.Width}px x {size.Height}px to the multi image icon.");
icon.Add(bitmapOverlay);
if (size.Width >= 256 && size.Height >= 256)
{
logger.Trace($"ShortcutItem/ToIconOverlay: The image is > 256px x 256px so making it a PNG layer in the icon file.");
icon[icon.Count - 1].IconImageFormat = IconImageFormat.PNG;
}
logger.Trace($"ShortcutItem/ToIconOverlay: Disposing of the Bitmap data we just used as the source (stops memory leaks).");
bitmapOverlay.Dispose();
}
logger.Trace($"ShortcutItem/ToIconOverlay: Make the top layer image of the Multi image icon the default one.");
multiIcon.SelectedIndex = 0;
return multiIcon;
}
catch (Exception ex)
{
logger.Warn(ex, $"ShortcutItem/ToIconOverlay: Exeception occurred while trying to convert the Shortcut Bitmap to an Icon Overlay to store in the shortcut cache directory. Returning null");
return null;
}
}
}
} }

View File

@ -17,6 +17,7 @@ using DesktopNotifications;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using NLog.Config; using NLog.Config;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections;
namespace DisplayMagician { namespace DisplayMagician {
@ -880,11 +881,14 @@ namespace DisplayMagician {
Bitmap bm = null; Bitmap bm = null;
try try
{ {
List<string> filesToSearchForIcon = new List<string>() { }; /*ArrayList filesToSearchForIcon = new ArrayList();
filesToSearchForIcon.Add(game.IconPath);
filesToSearchForIcon.Add(game.ExePath); filesToSearchForIcon.Add(game.ExePath);
filesToSearchForIcon.Add(game.IconPath);
bm = ImageUtils.ToSmallBitmap(filesToSearchForIcon); bm = ImageUtils.ToSmallBitmap(filesToSearchForIcon);*/
bm = ImageUtils.GetMeABitmapFromFile(game.IconPath);
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -116,7 +116,7 @@ namespace DisplayMagician
private ShortcutValidity _isValid; private ShortcutValidity _isValid;
private List<ShortcutError> _shortcutErrors = new List<ShortcutError>(); private List<ShortcutError> _shortcutErrors = new List<ShortcutError>();
private List<StartProgram> _startPrograms; private List<StartProgram> _startPrograms;
private Bitmap _shortcutBitmap, _originalLargeBitmap, _originalSmallBitmap; private Bitmap _shortcutBitmap, _originalLargeBitmap;
[JsonIgnore] [JsonIgnore]
#pragma warning disable CS3008 // Identifier is not CLS-compliant #pragma warning disable CS3008 // Identifier is not CLS-compliant
public string _originalIconPath; public string _originalIconPath;
@ -203,8 +203,9 @@ namespace DisplayMagician
_profileUuid = profile.UUID; _profileUuid = profile.UUID;
// We create the OriginalLargeBitmap from the IconPath // We create the OriginalLargeBitmap from the IconPath
_originalLargeBitmap = ToLargeBitmap(_originalIconPath); //_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
_originalSmallBitmap = ToSmallBitmap(_originalIconPath); //_originalSmallBitmap = ToSmallBitmap(_originalIconPath);
_originalLargeBitmap = ImageUtils.GetMeABitmapFromFile(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
@ -273,7 +274,8 @@ namespace DisplayMagician
} }
// We create the OriginalBitmap from the IconPath // We create the OriginalBitmap from the IconPath
_originalLargeBitmap = ToLargeBitmap(_originalIconPath); //_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
_originalLargeBitmap = ImageUtils.GetMeABitmapFromFile(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
@ -349,8 +351,9 @@ namespace DisplayMagician
_profileUuid = profile.UUID; _profileUuid = profile.UUID;
// We create the OriginalLargeBitmap from the IconPath // We create the OriginalLargeBitmap from the IconPath
_originalLargeBitmap = ToLargeBitmap(_originalIconPath); //_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
_originalSmallBitmap = ToSmallBitmap(_originalIconPath); //_originalSmallBitmap = ToSmallBitmap(_originalIconPath);
_originalLargeBitmap = ImageUtils.GetMeABitmapFromFile(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
@ -418,7 +421,8 @@ namespace DisplayMagician
_profileUuid = profile.UUID; _profileUuid = profile.UUID;
// We create the OriginalBitmap from the IconPath // We create the OriginalBitmap from the IconPath
_originalLargeBitmap = ToLargeBitmap(_originalIconPath); //_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
_originalLargeBitmap = ImageUtils.GetMeABitmapFromFile(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
@ -499,7 +503,8 @@ namespace DisplayMagician
} }
// We create the OriginalBitmap from the IconPath // We create the OriginalBitmap from the IconPath
_originalLargeBitmap = ToLargeBitmap(_originalIconPath); //_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
_originalLargeBitmap = ImageUtils.GetMeABitmapFromFile(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
@ -569,7 +574,8 @@ namespace DisplayMagician
_profileUuid = profile.UUID; _profileUuid = profile.UUID;
// We create the OriginalBitmap from the IconPath // We create the OriginalBitmap from the IconPath
_originalLargeBitmap = ToLargeBitmap(_originalIconPath); //_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
_originalLargeBitmap = ImageUtils.GetMeABitmapFromFile(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
@ -635,7 +641,8 @@ namespace DisplayMagician
_profileUuid = profile.UUID; _profileUuid = profile.UUID;
// We create the OriginalBitmap from the IconPath // We create the OriginalBitmap from the IconPath
_originalLargeBitmap = ToLargeBitmap(_originalIconPath); //_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
_originalLargeBitmap = ImageUtils.GetMeABitmapFromFile(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
@ -712,18 +719,8 @@ namespace DisplayMagician
} }
// We create the OriginalBitmap from the IconPath // We create the OriginalBitmap from the IconPath
if (_originalIconPath.EndsWith(".ico")) //_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
{ _originalLargeBitmap = ImageUtils.GetMeABitmapFromFile(_originalIconPath);
Icon icoIcon = new Icon(_originalIconPath, 256, 256);
//_originalBitmap = ExtractVistaIcon(biggestIcon);
_originalLargeBitmap = icoIcon.ToBitmap();
icoIcon.Dispose();
}
else
{
_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
}
_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
@ -1315,8 +1312,8 @@ namespace DisplayMagician
_profileUuid = profile.UUID; _profileUuid = profile.UUID;
// We create the OriginalLargeBitmap from the IconPath // We create the OriginalLargeBitmap from the IconPath
_originalLargeBitmap = ToLargeBitmap(_originalIconPath); //_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
_originalSmallBitmap = ToSmallBitmap(_originalIconPath); _originalLargeBitmap = ImageUtils.GetMeABitmapFromFile(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
@ -1386,7 +1383,8 @@ namespace DisplayMagician
} }
// We create the OriginalBitmap from the IconPath // We create the OriginalBitmap from the IconPath
_originalLargeBitmap = ToLargeBitmap(_originalIconPath); //_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
_originalLargeBitmap = ImageUtils.GetMeABitmapFromFile(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
@ -1463,8 +1461,9 @@ namespace DisplayMagician
_profileUuid = profile.UUID; _profileUuid = profile.UUID;
// We create the OriginalLargeBitmap from the IconPath // We create the OriginalLargeBitmap from the IconPath
_originalLargeBitmap = ToLargeBitmap(_originalIconPath); //_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
_originalSmallBitmap = ToSmallBitmap(_originalIconPath); //_originalSmallBitmap = ToSmallBitmap(_originalIconPath);
_originalLargeBitmap = ImageUtils.GetMeABitmapFromFile(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
@ -1533,7 +1532,8 @@ namespace DisplayMagician
_profileUuid = profile.UUID; _profileUuid = profile.UUID;
// We create the OriginalBitmap from the IconPath // We create the OriginalBitmap from the IconPath
_originalLargeBitmap = ToLargeBitmap(_originalIconPath); //_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
_originalLargeBitmap = ImageUtils.GetMeABitmapFromFile(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
@ -1614,7 +1614,8 @@ namespace DisplayMagician
} }
// We create the OriginalBitmap from the IconPath // We create the OriginalBitmap from the IconPath
_originalLargeBitmap = ToLargeBitmap(_originalIconPath); //_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
_originalLargeBitmap = ImageUtils.GetMeABitmapFromFile(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
@ -1685,7 +1686,8 @@ namespace DisplayMagician
_profileUuid = profile.UUID; _profileUuid = profile.UUID;
// We create the OriginalBitmap from the IconPath // We create the OriginalBitmap from the IconPath
_originalLargeBitmap = ToLargeBitmap(_originalIconPath); //_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
_originalLargeBitmap = ImageUtils.GetMeABitmapFromFile(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
@ -1752,7 +1754,8 @@ namespace DisplayMagician
_profileUuid = profile.UUID; _profileUuid = profile.UUID;
// We create the OriginalBitmap from the IconPath // We create the OriginalBitmap from the IconPath
_originalLargeBitmap = ToLargeBitmap(_originalIconPath); //_originalLargeBitmap = ToLargeBitmap(_originalIconPath);
_originalLargeBitmap = ImageUtils.GetMeABitmapFromFile(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
@ -1830,7 +1833,7 @@ namespace DisplayMagician
} }
// We create the OriginalBitmap from the IconPath // We create the OriginalBitmap from the IconPath
if (_originalIconPath.EndsWith(".ico")) /*if (_originalIconPath.EndsWith(".ico"))
{ {
Icon icoIcon = new Icon(_originalIconPath, 256, 256); Icon icoIcon = new Icon(_originalIconPath, 256, 256);
//_originalBitmap = ExtractVistaIcon(biggestIcon); //_originalBitmap = ExtractVistaIcon(biggestIcon);
@ -1840,7 +1843,8 @@ namespace DisplayMagician
else else
{ {
_originalLargeBitmap = ToLargeBitmap(_originalIconPath); _originalLargeBitmap = ToLargeBitmap(_originalIconPath);
} }*/
_originalLargeBitmap = ImageUtils.GetMeABitmapFromFile(_originalIconPath);
// We create the ShortcutBitmap from the OriginalBitmap // We create the ShortcutBitmap from the OriginalBitmap
// (We only do it if there is a valid profile) // (We only do it if there is a valid profile)
@ -1990,7 +1994,7 @@ namespace DisplayMagician
} }
public static Bitmap ToLargeBitmap(string fileNameAndPath) /*public static Bitmap ToLargeBitmap(string fileNameAndPath)
{ {
Bitmap bm = null; Bitmap bm = null;
@ -2033,9 +2037,9 @@ namespace DisplayMagician
return null; return null;
} }
} }
} }*/
public static Bitmap ToSmallBitmap(string fileNameAndPath) /*public static Bitmap ToSmallBitmap(string fileNameAndPath)
{ {
Bitmap bm = null; Bitmap bm = null;
try try
@ -2053,11 +2057,11 @@ namespace DisplayMagician
logger.Trace($"ShortcutItem/ToSmallBitmap: The file we want to get the image from is an icon file. Attempting to load the icon file from {fileNameAndPath}."); logger.Trace($"ShortcutItem/ToSmallBitmap: The file we want to get the image from is an icon file. Attempting to load the icon file from {fileNameAndPath}.");
Size iconSize = new Size(128, 128); Size iconSize = new Size(128, 128);
Icon iconToReturn = new Icon(fileNameAndPath, iconSize); Icon iconToReturn = new Icon(fileNameAndPath, iconSize);
/*if (iconToReturn.Size.Width < iconSize.Width || iconToReturn.Size.Height < iconSize.Height) *//*if (iconToReturn.Size.Width < iconSize.Width || iconToReturn.Size.Height < iconSize.Height)
{ {
// If the Icon is too small then we should try the Exe itself to see if its bigger // If the Icon is too small then we should try the Exe itself to see if its bigger
bm = IconFromFile.GetSmallBitmapFromFile(fileNameAndPath, false, false, false); bm = IconFromFile.GetSmallBitmapFromFile(fileNameAndPath, false, false, false);
}*/ }*//*
//Icon iconToReturn = IconFromFile.GetLargeIconFromFile(fileNameAndPath, true, true); //Icon iconToReturn = IconFromFile.GetLargeIconFromFile(fileNameAndPath, true, true);
//Icon iconToReturn = IconUtil.TryGetIcon(myIcon,iconSize,24,true,true); //Icon iconToReturn = IconUtil.TryGetIcon(myIcon,iconSize,24,true,true);
logger.Trace($"ShortcutItem/ToSmallBitmap: Attempting to convert the icon file {fileNameAndPath} to a bitmap."); logger.Trace($"ShortcutItem/ToSmallBitmap: Attempting to convert the icon file {fileNameAndPath} to a bitmap.");
@ -2087,7 +2091,7 @@ namespace DisplayMagician
return null; return null;
} }
} }
} }*/
public Bitmap ToBitmapOverlay(Bitmap originalBitmap, Bitmap overlayBitmap, int width, int height, PixelFormat format = PixelFormat.Format32bppArgb) public Bitmap ToBitmapOverlay(Bitmap originalBitmap, Bitmap overlayBitmap, int width, int height, PixelFormat format = PixelFormat.Format32bppArgb)
{ {
@ -2129,52 +2133,7 @@ namespace DisplayMagician
height = 256; height = 256;
} }
// Figure out sizes and positions return ImageUtils.ToBitmapOverlay(originalBitmap, overlayBitmap, width, height, format);
try
{
Size targetSize = new Size(width, height);
logger.Trace($"ShortcutItem/ToBitmapOverlay: TargetSize is {targetSize.Width}px x {targetSize.Height}px.");
Size originalBitmapCurrentSize = new Size(originalBitmap.Width, originalBitmap.Height);
logger.Trace($"ShortcutItem/ToBitmapOverlay: originalBitmapCurrentSize is {originalBitmapCurrentSize.Width}px x {originalBitmapCurrentSize.Height}px.");
Size overlaylBitmapCurrentSize = new Size(overlayBitmap.Width, overlayBitmap.Height);
logger.Trace($"ShortcutItem/ToBitmapOverlay: overlaylBitmapCurrentSize is {overlaylBitmapCurrentSize.Width}px x {overlaylBitmapCurrentSize.Height}px.");
// Make a new empty bitmap of the wanted size
logger.Trace($"ShortcutItem/ToBitmapOverlay: Making a new combined bitmap as the base for the image.");
var combinedBitmap = new Bitmap(targetSize.Width, targetSize.Height, format);
combinedBitmap.MakeTransparent();
using (var g = Graphics.FromImage(combinedBitmap))
{
logger.Trace($"ShortcutItem/ToBitmapOverlay: Setting smoothing mode, Interpolation mode, pixel offset mode and compositing quality.");
g.SmoothingMode = SmoothingMode.None;
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.AssumeLinear;
// Resize the originalBitmap if needed then draw it
Size originalBitmapNewSize = ResizeDrawing.FitWithin(originalBitmapCurrentSize, targetSize);
logger.Trace($"ShortcutItem/ToBitmapOverlay: Resizing the original bitmap to fit in the new combined bitmap. Size is now {originalBitmapNewSize.Width}px x {originalBitmapNewSize.Height}px");
Point originalBitmapNewLocation = ResizeDrawing.AlignCenter(originalBitmapNewSize, targetSize);
logger.Trace($"ShortcutItem/ToBitmapOverlay: Drawing the original bitmap into the new combined bitmap at position {originalBitmapNewLocation.X},{originalBitmapNewLocation.Y}..");
g.DrawImage(originalBitmap, originalBitmapNewLocation.X, originalBitmapNewLocation.Y, originalBitmapNewSize.Width, originalBitmapNewSize.Height);
// Resize the overlayBitmap if needed then draw it in the bottom-right corner
Size overlayBitmapMaxSize = ResizeDrawing.FitWithin(overlaylBitmapCurrentSize, targetSize);
Size overlayBitmapNewSize = ResizeDrawing.MakeSmaller(overlayBitmapMaxSize, 70);
logger.Trace($"ShortcutItem/ToBitmapOverlay: Resize the overlay bitmap to fit in the bottom right corner of the new combined bitmap. Size is now {overlayBitmapNewSize.Width}px x {overlayBitmapNewSize.Height}px");
Point overlayBitmapNewLocation = ResizeDrawing.AlignBottomRight(overlayBitmapNewSize, targetSize);
logger.Trace($"ShortcutItem/ToBitmapOverlay: Drawing the overlay bitmap into the new combined bitmap at position {overlayBitmapNewLocation.X},{overlayBitmapNewLocation.Y}.");
g.DrawImage(overlayBitmap, overlayBitmapNewLocation.X, overlayBitmapNewLocation.Y, overlayBitmapNewSize.Width, overlayBitmapNewSize.Height);
}
return combinedBitmap;
}
catch (Exception ex)
{
logger.Warn(ex, $"ShortcutItem/ToBitmapOverlay: Exception while trying to add the overlay to the Bitmap. Returning null");
return null;
}
} }
@ -2182,54 +2141,7 @@ namespace DisplayMagician
public MultiIcon ToIconOverlay() public MultiIcon ToIconOverlay()
#pragma warning restore CS3002 // Return type is not CLS-compliant #pragma warning restore CS3002 // Return type is not CLS-compliant
{ {
try return ImageUtils.ToIconOverlay(_originalLargeBitmap, ProfileToUse.ProfileTightestBitmap);
{
Size[] iconSizes = new[]
{
new Size(256, 256),
new Size(64, 64),
new Size(48, 48),
new Size(32, 32),
new Size(24, 24),
new Size(16, 16)
};
logger.Trace($"ShortcutItem/ToIconOverlay: Creating the new Multi image Icon.");
MultiIcon multiIcon = new MultiIcon();
logger.Trace($"ShortcutItem/ToIconOverlay: Adding a single icon to the multi image icon.");
SingleIcon icon = multiIcon.Add("Icon1");
foreach (Size size in iconSizes)
{
logger.Trace($"ShortcutItem/ToIconOverlay: Creating a new image layer of size {size.Width}px x {size.Height}px.");
Bitmap bitmapOverlay = ToBitmapOverlay(_originalLargeBitmap, ProfileToUse.ProfileTightestBitmap, size.Width, size.Height);
if (bitmapOverlay == null)
{
logger.Warn($"ShortcutItem/ToIconOverlay: bitmapOverlay is null, so we can't turn it into an Icon Overlay. Returning null");
return null;
}
logger.Trace($"ShortcutItem/ToIconOverlay: Adding the new image layer of size {size.Width}px x {size.Height}px to the multi image icon.");
icon.Add(bitmapOverlay);
if (size.Width >= 256 && size.Height >= 256)
{
logger.Trace($"ShortcutItem/ToIconOverlay: The image is > 256px x 256px so making it a PNG layer in the icon file.");
icon[icon.Count - 1].IconImageFormat = IconImageFormat.PNG;
}
logger.Trace($"ShortcutItem/ToIconOverlay: Disposing of the Bitmap data we just used as the source (stops memory leaks).");
bitmapOverlay.Dispose();
}
logger.Trace($"ShortcutItem/ToIconOverlay: Make the top layer image of the Multi image icon the default one.");
multiIcon.SelectedIndex = 0;
return multiIcon;
}
catch (Exception ex)
{
logger.Warn(ex, $"ShortcutItem/ToIconOverlay: Exeception occurred while trying to convert the Shortcut Bitmap to an Icon Overlay to store in the shortcut cache directory. Returning null");
return null;
}
} }
public void RefreshValidity() public void RefreshValidity()