ImageConverter
ImageConverter is a class that can be used to convert Image objects from one data type to another. Access this class through the TypeDescriptor object.
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Runtime.CompilerServices;
using Windows.Win32.Foundation;
namespace System.Drawing
{
[NullableContext(2)]
[Nullable(0)]
public class ImageConverter : TypeConverter
{
[NullableContext(0)]
private enum FMTID : uint
{
FMTID_LINK = 1,
FMTID_EMBED = 2,
FMTID_STATIC = 3,
FMTID_PRES = 5
}
[NullableContext(0)]
private enum OleObjectType : uint
{
OT_LINK = 1,
OT_EMBEDDED,
OT_STATIC
}
[NullableContext(0)]
private struct OLEOBJHEADER
{
public const ushort OLEOBJID = 7189;
public ushort typ;
public ushort cbHdr;
public OleObjectType oot;
public ushort cchName;
public ushort cchClass;
public ushort ibName;
public ushort ibClass;
public POINTS ptSize;
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (!(sourceType == typeof(byte[])))
return sourceType == typeof(Icon);
return true;
}
public override bool CanConvertTo(ITypeDescriptorContext context, [NotNullWhen(true)] Type destinationType)
{
if (!(destinationType == typeof(byte[])))
return destinationType == typeof(string);
return true;
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, [Nullable(1)] object value)
{
Icon icon = value as Icon;
if (icon != null)
return icon.ToBitmap();
byte[] array = value as byte[];
if (array != null)
return Image.FromStream(GetBitmapStream(array) ?? new MemoryStream(array));
return base.ConvertFrom(context, culture, value);
}
[return: Nullable(1)]
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, [Nullable(1)] Type destinationType)
{
if (destinationType == typeof(string)) {
if (value == null)
return System.SR.none;
if (value is Image)
return value.ToString();
} else if (destinationType == typeof(byte[])) {
if (value == null)
return Array.Empty<byte>();
Image image = value as Image;
if (image != null) {
using (MemoryStream memoryStream = new MemoryStream()) {
image.Save(memoryStream);
return memoryStream.ToArray();
}
}
}
throw GetConvertFromException(value);
}
[RequiresUnreferencedCode("The Type of value cannot be statically discovered. The public parameterless constructor or the 'Default' static field may be trimmed from the Attribute's Type.")]
[return: Nullable(1)]
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, [Nullable(new byte[] {
2,
1
})] Attribute[] attributes)
{
return TypeDescriptor.GetProperties(typeof(Image), attributes);
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true;
}
[NullableContext(0)]
[return: Nullable(2)]
private unsafe static MemoryStream GetBitmapStream(ReadOnlySpan<byte> rawData)
{
SpanReader<byte> spanReader = new SpanReader<byte>(rawData);
if (!spanReader.TryRead(out OLEOBJHEADER value))
return null;
if (value.typ != 7189 || value.oot != OleObjectType.OT_EMBEDDED || value.ibName != sizeof(OLEOBJHEADER) || value.ibClass != sizeof(OLEOBJHEADER) + value.cchName || value.cbHdr != sizeof(OLEOBJHEADER) + value.cchClass + value.cchName || (Point)value.ptSize != new Point(-1, -1) || !spanReader.TryRead(value.cchName, out ReadOnlySpan<byte> _) || !spanReader.TryRead(value.cchClass, out ReadOnlySpan<byte> _))
return null;
int value6;
int value5;
ReadOnlySpan<byte> span3;
int value4;
if (!spanReader.TryRead(out uint _) || !spanReader.TryRead(out FMTID value3) || value3 != FMTID.FMTID_EMBED || !spanReader.TryRead(out value4) || !spanReader.TryRead(value4, out span3) || !span3.SequenceEqual(new ReadOnlySpan<byte>(&global::<PrivateImplementationDetails>.084CB602926C6034E521333AC4E3B9740EDAC4DF45773FAAC151F660ABF3772A, 7)) || !spanReader.TryRead(out value5) || value5 != 0 || !spanReader.TryRead(out value6) || value6 != 0)
return null;
if (!spanReader.TryRead(out int value7) || !spanReader.TryRead(value7, out ReadOnlySpan<byte> span4))
return null;
return new MemoryStream(span4.ToArray());
}
}
}