@@ -7,13 +7,16 @@ namespace Discord | |||||
public struct Image | public struct Image | ||||
{ | { | ||||
public Stream Stream { get; } | public Stream Stream { get; } | ||||
public ImageFormat Format { get; } | |||||
/// <summary> | /// <summary> | ||||
/// Create the image with a Stream. | /// Create the image with a Stream. | ||||
/// </summary> | /// </summary> | ||||
/// <param name="stream">This must be some type of stream with the contents of a file in it.</param> | /// <param name="stream">This must be some type of stream with the contents of a file in it.</param> | ||||
public Image(Stream stream) | |||||
public Image(Stream stream, ImageFormat format = ImageFormat.Jpeg) | |||||
{ | { | ||||
Stream = stream; | Stream = stream; | ||||
Format = format; | |||||
} | } | ||||
#if FILESYSTEM | #if FILESYSTEM | ||||
/// <summary> | /// <summary> | ||||
@@ -23,9 +26,10 @@ namespace Discord | |||||
/// This file path is NOT validated, and is passed directly into a <see cref="File.OpenRead(string)"/> | /// This file path is NOT validated, and is passed directly into a <see cref="File.OpenRead(string)"/> | ||||
/// </remarks> | /// </remarks> | ||||
/// <param name="path">The path to the file.</param> | /// <param name="path">The path to the file.</param> | ||||
public Image(string path) | |||||
public Image(string path, ImageFormat format = ImageFormat.Jpeg) | |||||
{ | { | ||||
Stream = File.OpenRead(path); | Stream = File.OpenRead(path); | ||||
Format = format; | |||||
} | } | ||||
#endif | #endif | ||||
} | } | ||||
@@ -5,16 +5,19 @@ namespace Discord.API | |||||
internal struct Image | internal struct Image | ||||
{ | { | ||||
public Stream Stream { get; } | public Stream Stream { get; } | ||||
public ImageFormat StreamFormat { get; } | |||||
public string Hash { get; } | public string Hash { get; } | ||||
public Image(Stream stream) | |||||
public Image(Stream stream, ImageFormat format) | |||||
{ | { | ||||
Stream = stream; | Stream = stream; | ||||
StreamFormat = format; | |||||
Hash = null; | Hash = null; | ||||
} | } | ||||
public Image(string hash) | public Image(string hash) | ||||
{ | { | ||||
Stream = null; | Stream = null; | ||||
StreamFormat = ImageFormat.Jpeg; | |||||
Hash = hash; | Hash = hash; | ||||
} | } | ||||
} | } | ||||
@@ -114,7 +114,7 @@ namespace Discord.Rest | |||||
public static API.Image ToModel(this Image entity) | public static API.Image ToModel(this Image entity) | ||||
{ | { | ||||
return new API.Image(entity.Stream); | |||||
return new API.Image(entity.Stream, entity.Format); | |||||
} | } | ||||
public static Overwrite ToEntity(this API.Overwrite model) | public static Overwrite ToEntity(this API.Overwrite model) | ||||
@@ -1,12 +1,52 @@ | |||||
using System.Text.Json; | |||||
using System; | |||||
using System.Text.Json; | |||||
namespace Discord.Serialization.Json.Converters | namespace Discord.Serialization.Json.Converters | ||||
{ | { | ||||
internal class ImagePropertyConverter : IJsonPropertyConverter<API.Image> | internal class ImagePropertyConverter : IJsonPropertyConverter<API.Image> | ||||
{ | { | ||||
public API.Image Read(PropertyMap map, ref JsonReader reader, bool isTopLevel) | public API.Image Read(PropertyMap map, ref JsonReader reader, bool isTopLevel) | ||||
=> throw new System.NotImplementedException(); | |||||
{ | |||||
if (isTopLevel) | |||||
reader.Read(); | |||||
if (reader.ValueType != JsonValueType.String) | |||||
throw new SerializationException("Bad input, expected String"); | |||||
return new API.Image(reader.ParseString()); | |||||
} | |||||
public void Write(PropertyMap map, ref JsonWriter writer, API.Image value, bool isTopLevel) | public void Write(PropertyMap map, ref JsonWriter writer, API.Image value, bool isTopLevel) | ||||
=> throw new System.NotImplementedException(); | |||||
{ | |||||
string str; | |||||
if (value.Stream != null) | |||||
{ | |||||
byte[] bytes = new byte[value.Stream.Length - value.Stream.Position]; | |||||
value.Stream.Read(bytes, 0, bytes.Length); | |||||
string base64 = Convert.ToBase64String(bytes); | |||||
switch (value.StreamFormat) | |||||
{ | |||||
case ImageFormat.Jpeg: | |||||
str = $"data:image/jpeg;base64,{base64}"; | |||||
break; | |||||
case ImageFormat.Png: | |||||
str = $"data:image/png;base64,{base64}"; | |||||
break; | |||||
case ImageFormat.Gif: | |||||
str = $"data:image/gif;base64,{base64}"; | |||||
break; | |||||
case ImageFormat.WebP: | |||||
str = $"data:image/webp;base64,{base64}"; | |||||
break; | |||||
default: | |||||
throw new SerializationException($"Unable to serialize an {nameof(Image)} with a format of {value.StreamFormat}"); | |||||
} | |||||
} | |||||
else | |||||
str = value.Hash; | |||||
if (isTopLevel) | |||||
writer.WriteAttribute(map.Key, str); | |||||
else | |||||
writer.WriteValue(str); | |||||
} | |||||
} | } | ||||
} | } |