如何創建包含多種尺寸的圖標文件?如何在C#中創建包含多種尺寸/圖像的圖標文件
我知道我使用Icon.FromHandle()
從位圖創建了一個圖標,但是如何將另一個圖像/大小添加到該圖標?
編輯:我需要在我的應用程序中這樣做,所以我不能執行外部應用程序來執行組合。
如何創建包含多種尺寸的圖標文件?如何在C#中創建包含多種尺寸/圖像的圖標文件
我知道我使用Icon.FromHandle()
從位圖創建了一個圖標,但是如何將另一個圖像/大小添加到該圖標?
編輯:我需要在我的應用程序中這樣做,所以我不能執行外部應用程序來執行組合。
快速CYA:我只是做了谷歌搜索,並沒有測試下面的方法。因人而異。
我發現this article,它提到了這樣做的類(儘管在VB.Net中,但很容易翻譯),並告訴他如何使用它。雖然線程指向的頁面不再顯示源代碼,但我確實找到了它的一個版本here.
你的谷歌foo比我的好多了。 :) – Geoff 2010-07-10 05:43:04
您不能使用System.Drawing
API創建圖標。它們是爲構建的,它訪問圖標文件中的特定圖標,但不適用於將返回多個圖標到.ico文件。
如果您只是想製作圖標,可以使用GIMP或其他圖像處理程序來創建.ico文件。否則,如果您確實需要以編程方式製作.ico文件,則可以使用png2ico(使用System.Diagnostics.Process.Start
調用)或類似的東西。
當然,你可以使任何圖像的圖標文件... http://www.go4expert.com/forums/showthread.php?t= 19250 – NickAldwin 2010-07-09 19:25:48
@NickAldwin:您可以保存單層圖標(如鏈接所示),但不能保存*多個*分層圖標。我已編輯澄清。 – 2010-07-09 20:27:04
只是想澄清一個可能的誤解,感謝編輯;) – NickAldwin 2010-07-09 20:44:13
使用IcoFX:http://icofx.ro/
它可以創建Windows圖標和多種尺寸和顏色存儲在1個ICO文件
這可以使用IconLib完成。您可以從CodeProject文章中獲得源代碼,或者您可以獲得compiled dll from my GitHub mirror。
public void Convert(string pngPath, string icoPath)
{
MultiIcon mIcon = new MultiIcon();
mIcon.Add("Untitled").CreateFrom(pngPath, IconOutputFormat.FromWin95);
mIcon.SelectedIndex = 0;
mIcon.Save(icoPath, MultiIconFormat.ICO);
}
CreateFrom
可以採取一個路徑,一個256x256 PNG或System.Drawing.Bitmap
對象。
太棒了。謝謝。 – Robinson 2016-01-19 18:21:51
我正在尋找一種方法來將.png文件組合成一個圖標,沒有任何花哨。我無法找到簡單的東西,並且這個問題成爲最熱門的搜索結果後,我創建了下面的代碼。
如果,對於每個圖像,該Image.RawFormat是ImageFormat.Png,將Image.PixelFormat是PixelFormat.Format32bppArgb
下面的代碼可以創建具有多種尺寸的圖標和尺寸是小於或等於256x256
:
/// <summary>
/// Provides methods for creating icons.
/// </summary>
public class IconFactory
{
#region constants
/// <summary>
/// Represents the max allowed width of an icon.
/// </summary>
public const int MaxIconWidth = 256;
/// <summary>
/// Represents the max allowed height of an icon.
/// </summary>
public const int MaxIconHeight = 256;
private const ushort HeaderReserved = 0;
private const ushort HeaderIconType = 1;
private const byte HeaderLength = 6;
private const byte EntryReserved = 0;
private const byte EntryLength = 16;
private const byte PngColorsInPalette = 0;
private const ushort PngColorPlanes = 1;
#endregion
#region methods
/// <summary>
/// Saves the specified <see cref="Bitmap"/> objects as a single
/// icon into the output stream.
/// </summary>
/// <param name="images">The bitmaps to save as an icon.</param>
/// <param name="stream">The output stream.</param>
/// <remarks>
/// The expected input for the <paramref name="images"/> parameter are
/// portable network graphic files that have a <see cref="Image.PixelFormat"/>
/// of <see cref="PixelFormat.Format32bppArgb"/> and where the
/// width is less than or equal to <see cref="IconFactory.MaxIconWidth"/> and the
/// height is less than or equal to <see cref="MaxIconHeight"/>.
/// </remarks>
/// <exception cref="InvalidOperationException">
/// Occurs if any of the input images do
/// not follow the required image format. See remarks for details.
/// </exception>
/// <exception cref="ArgumentNullException">
/// Occurs if any of the arguments are null.
/// </exception>
public static void SavePngsAsIcon(IEnumerable<Bitmap> images, Stream stream)
{
if (images == null)
throw new ArgumentNullException("images");
if (stream == null)
throw new ArgumentNullException("stream");
// validates the pngs
IconFactory.ThrowForInvalidPngs(images);
Bitmap[] orderedImages = images.OrderBy(i => i.Width)
.ThenBy(i => i.Height)
.ToArray();
using (var writer = new BinaryWriter(stream))
{
// write the header
writer.Write(IconFactory.HeaderReserved);
writer.Write(IconFactory.HeaderIconType);
writer.Write((ushort)orderedImages.Length);
// save the image buffers and offsets
Dictionary<uint, byte[]> buffers = new Dictionary<uint, byte[]>();
// tracks the length of the buffers as the iterations occur
// and adds that to the offset of the entries
uint lengthSum = 0;
uint baseOffset = (uint)(IconFactory.HeaderLength +
IconFactory.EntryLength * orderedImages.Length);
for (int i = 0; i < orderedImages.Length; i++)
{
Bitmap image = orderedImages[i];
// creates a byte array from an image
byte[] buffer = IconFactory.CreateImageBuffer(image);
// calculates what the offset of this image will be
// in the stream
uint offset = (baseOffset + lengthSum);
// writes the image entry
writer.Write(IconFactory.GetIconWidth(image));
writer.Write(IconFactory.GetIconHeight(image));
writer.Write(IconFactory.PngColorsInPalette);
writer.Write(IconFactory.EntryReserved);
writer.Write(IconFactory.PngColorPlanes);
writer.Write((ushort)Image.GetPixelFormatSize(image.PixelFormat));
writer.Write((uint)buffer.Length);
writer.Write(offset);
lengthSum += (uint)buffer.Length;
// adds the buffer to be written at the offset
buffers.Add(offset, buffer);
}
// writes the buffers for each image
foreach (var kvp in buffers)
{
// seeks to the specified offset required for the image buffer
writer.BaseStream.Seek(kvp.Key, SeekOrigin.Begin);
// writes the buffer
writer.Write(kvp.Value);
}
}
}
private static void ThrowForInvalidPngs(IEnumerable<Bitmap> images)
{
foreach (var image in images)
{
if (image.PixelFormat != PixelFormat.Format32bppArgb)
{
throw new InvalidOperationException
(string.Format("Required pixel format is PixelFormat.{0}.",
PixelFormat.Format32bppArgb.ToString()));
}
if (image.RawFormat.Guid != ImageFormat.Png.Guid)
{
throw new InvalidOperationException
("Required image format is a portable network graphic (png).");
}
if (image.Width > IconFactory.MaxIconWidth ||
image.Height > IconFactory.MaxIconHeight)
{
throw new InvalidOperationException
(string.Format("Dimensions must be less than or equal to {0}x{1}",
IconFactory.MaxIconWidth,
IconFactory.MaxIconHeight));
}
}
}
private static byte GetIconHeight(Bitmap image)
{
if (image.Height == IconFactory.MaxIconHeight)
return 0;
return (byte)image.Height;
}
private static byte GetIconWidth(Bitmap image)
{
if (image.Width == IconFactory.MaxIconWidth)
return 0;
return (byte)image.Width;
}
private static byte[] CreateImageBuffer(Bitmap image)
{
using (var stream = new MemoryStream())
{
image.Save(stream, image.RawFormat);
return stream.ToArray();
}
}
#endregion
}
用法:
using (var png16 = (Bitmap)Bitmap.FromFile(@"C:\Test\3dGlasses16.png"))
using (var png32 = (Bitmap)Bitmap.FromFile(@"C:\Test\3dGlasses32.png"))
using (var stream = new FileStream(@"C:\Test\Combined.ico", FileMode.Create))
{
IconFactory.SavePngsAsIcon(new[] { png16, png32 }, stream);
}
因爲我不認爲它回答你的問題,我會張貼這個評論。我使用名爲IcoFX的程序來創建圖標,並且通過重新採樣各種其他尺寸的原始256x256圖標(即64x64,32x32 ...),一次創建多個圖標大小非常方便。您可能會也可能不會找到它和相關的信息有用。網址:http://icofx.ro/ – JYelton 2010-07-09 15:20:06
我使用GIF Movie Gear。 – 2010-07-09 15:20:55
我使用axialis iconworkshop – iTEgg 2010-07-09 15:25:21