/// <summary>
        /// 内部使用
        /// </summary>
        private async Task <ISharedImageMessage> InternalUploadPictureAsync(InternalSessionInfo session, UploadTarget type, Stream imgStream, bool disposeStream, CancellationToken token = default)
        {
            // 使用 disposeStream 目的是不使上层 caller 创建多余的状态机
            if (session.ApiVersion <= new Version(1, 7, 0))
            {
                Guid         guid = Guid.NewGuid();
                MemoryStream ms   = new MemoryStream(8192); // 无论如何都做一份copy
                await imgStream.CopyToAsync(ms, 81920, token).ConfigureAwait(false);

                ImageHttpListener.RegisterImage(guid, ms);
                return(new ImageMessage(null, $"http://127.0.0.1:{ImageHttpListener.Port}/fetch?guid={guid:n}", null));
            }
            Stream?internalStream  = null;
            bool   internalCreated = false;
            long   pervious        = 0;

            if (!imgStream.CanSeek || imgStream.CanTimeout) // 对于 CanTimeOut 的 imgStream, 或者无法Seek的, 一律假定其读取行为是阻塞的
                                                            // 为其创建一个内部缓存先行异步读取
            {
                internalStream  = new MemoryStream(8192);
                internalCreated = true;
                await imgStream.CopyToAsync(internalStream, 81920, token);

                internalStream.Seek(0, SeekOrigin.Begin);
            }
            else // 否则不创建副本, 避免多余的堆分配
            {
                internalStream = imgStream;
                pervious       = imgStream.Position;
            }
            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 SKManagedStream skstream = new SKManagedStream(internalStream, false);
            using (SKCodec codec = SKCodec.Create(skstream)) // 已经把数据读到非托管内存里边了, 就不用管input的死活了
            {
                var skformat = codec.EncodedFormat;
                format = skformat.ToString().ToLower();
                switch (skformat)
                {
                case SKEncodedImageFormat.Gif:
                case SKEncodedImageFormat.Jpeg:
                case SKEncodedImageFormat.Png:
                    break;

                default:
                {
                    skstream.Seek(0);
                    using (SKBitmap bitmap = SKBitmap.Decode(skstream))
                    {
                        if (!internalCreated)
                        {
                            internalStream  = new MemoryStream(8192);
                            internalCreated = true;
                        }
                        else
                        {
                            internalStream.Seek(0, SeekOrigin.Begin);
                        }
                        bitmap.Encode(internalStream, SKEncodedImageFormat.Png, 100);
                    }
                    format = "png";
                    break;
                }
                }
            }
            if (internalCreated)
            {
                internalStream.Seek(0, SeekOrigin.Begin);
            }
            else // internalStream == imgStream
            {
                internalStream.Seek(pervious - internalStream.Position, SeekOrigin.Current);
            }
            HttpContent imageContent = new StreamContent(internalStream);

            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
            {
                CreateLinkedUserSessionToken(session.Token, token, out CancellationTokenSource? cts, out token);
                return(await _client.PostAsync($"{_options.BaseUrl}/uploadImage", contents, token)
                       .AsApiRespAsync <ISharedImageMessage, ImageMessage>(token)
                       .DisposeWhenCompleted(cts)
                       .ContinueWith(t => t.IsFaulted && t.Exception !.InnerException is JsonException ? throw new NotSupportedException("当前版本的mirai-api-http无法发送图片。") : t, TaskContinuationOptions.ExecuteSynchronously).Unwrap().ConfigureAwait(false));

                //  ^-- 处理 JsonException 到 NotSupportedException, https://github.com/mamoe/mirai-api-http/issues/85
                // internalStream 是 MemoryStream, 内部为全托管字段不需要 Dispose
            }
            finally
            {
                if (disposeStream)
                {
                    imgStream.Dispose();
                }
            }
        }