private async Task <ImageMessage> InternalUploadPictureAsync(PictureTarget type, Stream image) { HttpContent sessionKeyContent = new StringContent(SessionInfo.SessionKey); sessionKeyContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "sessionKey" }; HttpContent typeContent = new StringContent(type.ToString().ToLower()); typeContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "type" }; HttpContent imageContent = new StreamContent(image); typeContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "img" }; HttpContent[] contents = new HttpContent[] { sessionKeyContent, typeContent, imageContent }; using JsonDocument j = await HttpHelper.HttpPostAsync($"{SessionInfo.Options.BaseUrl}/uploadImage", contents); JsonElement root = j.RootElement; int code = root.GetProperty("code").GetInt32(); if (code == 0) { return(Utils.Deserialize <ImageMessage>(in root)); } return(ThrowCommonException <ImageMessage>(code, in root)); }
private async Task <ImageMessage> InternalUploadPictureAsync(PictureTarget type, Stream imgStream) { if (ApiVersion <= new Version(1, 7, 0)) { Guid guid = Guid.NewGuid(); ImageHttpListener.RegisterImage(guid, imgStream); return(new ImageMessage(null, $"http://127.0.0.1:{ImageHttpListener.Port}/fetch?guid={guid:n}", null)); } HttpContent sessionKeyContent = new StringContent(SessionInfo.SessionKey); sessionKeyContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "sessionKey" }; HttpContent typeContent = new StringContent(type.ToString().ToLower()); typeContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "type" }; string format; using (Image img = Image.FromStream(imgStream)) { format = img.RawFormat.ToString(); switch (format) { case nameof(ImageFormat.Jpeg): case nameof(ImageFormat.Png): case nameof(ImageFormat.Gif): { format = format.ToLower(); break; } default: // 不是以上三种类型的图片就强转为Png { MemoryStream ms = new MemoryStream(); img.Save(ms, ImageFormat.Png); imgStream.Dispose(); imgStream = ms; format = "png"; break; } } } imgStream.Seek(0, SeekOrigin.Begin); HttpContent imageContent = new StreamContent(imgStream); imageContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "img", FileName = $"{Guid.NewGuid():n}.{format}" }; imageContent.Headers.ContentType = new MediaTypeHeaderValue("image/" + format); HttpContent[] contents = new HttpContent[] { sessionKeyContent, typeContent, imageContent }; try { using JsonDocument j = await HttpHelper.HttpPostAsync($"{SessionInfo.Options.BaseUrl}/uploadImage", contents).GetJsonAsync(token: SessionInfo.Canceller.Token); JsonElement root = j.RootElement; if (root.TryGetProperty("code", out JsonElement code)) // 正常返回是没有code的 { return(ThrowCommonException <ImageMessage>(code.GetInt32(), in root)); } return(Utils.Deserialize <ImageMessage>(in root)); } catch (JsonException) // https://github.com/mamoe/mirai-api-http/issues/85 { throw new NotSupportedException("当前版本的mirai-api-http无法发送图片。"); } }
/// <summary> /// 内部使用 /// </summary> /// <exception cref="InvalidOperationException"/> /// <param name="type">目标类型</param> /// <param name="imgStream">图片流</param> /// <remarks> /// 注意: 当 mirai-api-http 的版本小于等于v1.7.0时, 本方法返回的将是一个只有 Url 有值的 <see cref="ImageMessage"/> /// </remarks> /// <returns>一个 <see cref="ImageMessage"/> 实例, 可用于以后的消息发送</returns> private Task <ImageMessage> InternalUploadPictureAsync(InternalSessionInfo session, PictureTarget type, Stream imgStream) { if (session.ApiVersion <= new Version(1, 7, 0)) { Guid guid = Guid.NewGuid(); ImageHttpListener.RegisterImage(guid, imgStream); return(Task.FromResult(new ImageMessage(null, $"http://127.0.0.1:{ImageHttpListener.Port}/fetch?guid={guid:n}", null))); } HttpContent sessionKeyContent = new StringContent(session.SessionKey); sessionKeyContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "sessionKey" }; HttpContent typeContent = new StringContent(type.ToString().ToLower()); typeContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "type" }; string format; using (Image img = Image.FromStream(imgStream)) { format = img.RawFormat.ToString(); switch (format) { case nameof(ImageFormat.Jpeg): case nameof(ImageFormat.Png): case nameof(ImageFormat.Gif): { format = format.ToLower(); break; } default: // 不是以上三种类型的图片就强转为Png { MemoryStream ms = new MemoryStream(); img.Save(ms, ImageFormat.Png); imgStream.Dispose(); imgStream = ms; format = "png"; break; } } } imgStream.Seek(0, SeekOrigin.Begin); HttpContent imageContent = new StreamContent(imgStream); imageContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { Name = "img", FileName = $"{Guid.NewGuid():n}.{format}" }; imageContent.Headers.ContentType = new MediaTypeHeaderValue("image/" + format); HttpContent[] contents = new HttpContent[] { sessionKeyContent, typeContent, imageContent }; return(InternalHttpPostNoSuccCodeAsync <ImageMessage, ImageMessage>(session.Client, $"{session.Options.BaseUrl}/uploadImage", contents, session.Token) .ContinueWith(t => t.IsFaulted && t.Exception !.InnerException is JsonException ? Task.FromException <ImageMessage>(new NotSupportedException("当前版本的mirai-api-http无法发送图片。")) : t, TaskContinuationOptions.ExecuteSynchronously).Unwrap()); // ^-- 处理 JsonException 到 NotSupportedException, https://github.com/mamoe/mirai-api-http/issues/85 }