Pokud potřebujeme zobrazit v aplikaci např. bitmapu nebo iconu apod., většinou jí umístíme do projektu jako resource a přes ResourceManager načteme. Někdy ale pokud vytváříme samostatný .NET control, componentu nebo klidně jen nějakou obecnou sdílenou třídu, tak se může hodit možnost umístit takovýto zdroj jako je bitmapa nebo icona přímo do kódu, a tím nebude třída závislá na konkrétním projektu nebo namespace resourcu.
Jak na to? K tomu aby jsme grafický zdroj lehce umístili do kódu použijeme Base64String formát, který nám obecně bitová data umožní zapsat do konstanty typu string.
Požadovaný string tedy získáme tímto kódem:
System.Diagnostics.Debug.WriteLine(Convert.ToBase64String(System.IO.File.ReadAllBytes(@"soubor")));
Pozn.: Base64String formát je také používán pokud se ve Windows.Forms ukládají binární data do XML v .resx souboru např. formuláře. Pokud tedy například požadovanou iconu máme jako ikonu na formuláři, můžeme ve Visual Studiu otevřít soubor resx volbou Open With a zvolit XML (Text) Editor. Base64String poté z XML editoru vykopírujeme z elementu value patřičného resource (element Data).
Po získání požadovaného stringu již stačí vložit do kódu jako konstantu a poté pomoci metody Convert.FromBase64String převést zpět na pole bajtů.
Celé si to ukážeme na příkladu, následující třída vrací metodou VistaTools.GetNonVistaUacShieldImage ikonku shieldu pro operaci vyžadující Administrátorská práva jako je v systému Vista. Icona je převedena ze stringu na pole bajtů a poté pomoci MemoryStreamu načtena a vrácena jako typ System.Drawing.Bitmap.
public static class VistaTools
{
#region constants
private const string cUACShieldIconDataVista =
@"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAo5JREFUOE+Fk+9Lk1EUx5O99UV/iS97YUQLSgKN5g+WKW4FhbUSLabTzYb47JlOJcd0q40VS8xETQofgua2F+qG5aaPs5jGTCwSC92sZ04nuG/3jjaUHurCgcu53/M55557bt4JkcWy7Nn8/PzhdDp9khznSSSSWCKRkGq12k9i+pyPBJ5xuVxzTqcz6fV6U/Pz8xmje7vdniRnIaI5/ReEONvMZvMWsaTf709RO1xdxqGHw8QbFr1TrZidnc34qcZisWzQmKOZd0KhUCab8JbDQTiIg3dTSI0+w+DrRnTNNKNzUgPdaB2ohmoJIJEDGI1GYWFhIbXheIyfz534NT6AxJN+CIwOfYM3oPGq0MTVouHFNdy0V2YgJGb3GIA6Nx+asN1vwlanFtu11xGTycA65Kh6VQ7FSCmUTy+jordIHEAriHe3I8GqEa+WQSgsRJKY3l6Oi+NluDomh2JIjlJriSggzvN86jPThi/36rBSfAnR8yVYl11Bj6MKtydroHYroeEUUA2UZgHxo00M0wqa2Qno21+iSTeIO41DqG8dgf+9CdGvtYiu3UV0WYUVfyUCgQDtQeQoYNjtdu+rHgVRbApBZgniXFcQF3rmwPO9gNAAxDTAphrgq8FxnEBeYSwH6OjokFqt1h3aSDkzjRrTNMqM06gwzeBjmADi94EfOmCtDvQJbTbblsFgOHVsoAjxG72G1uqD3OBHOTODis4AlhYJINYCfNdACN/KAIh2RWwaC+hw0CpaHAHU9AShNAcRXuwjV+jG7po+2zxafoHonyBlPSDN2aMQOrb1rg+IRByg+z/Ds0c1//xQWYjP58t9Jo/HQ7v+/+AsmWGYIlLmOrF9EkjvvEp8UrHMvwG3rxBXyWqXRgAAAABJRU5ErkJggg==";
#endregion
#region member varible and default property initialization
private static System.Drawing.Bitmap sNonVistaUacShieldBitmap;
#endregion
#region action methods
/// <summary>
/// Get Vista UAC Shield image for Windows XP or lower
/// </summary>
public static System.Drawing.Bitmap GetNonVistaUacShieldImage()
{
if (sNonVistaUacShieldBitmap == null)
{
var data = new System.IO.MemoryStream(Convert.FromBase64String(cUACShieldIconDataVista));
sNonVistaUacShieldBitmap = new System.Drawing.Bitmap(data);
}
return sNonVistaUacShieldBitmap;
}
#endregion
}
(Tuto třídu berte jen jako příklad pro ukázání načtení Bitmap zdroje z konstanty, reálné použití této konkrétní funkce je pouze pro operační systémy nižší než Vista, ve Windows Vista a Windows 7 jsou k získání shield icony jiné možnosti)
Závěrem bych ještě rád napsal, že ačkoliv je kód v příkladu pro Windows Forms technologii, tento postup můžeme použít i jinde např. ve WPF, kde obdobně přes memory stream můžeme string konstantu načíst do objektu typu BitmapSource.