【问题标题】:Telegram Bot C# - Send object BitmapTelegram Bot C# - 发送对象位图
【发布时间】:2018-09-01 20:59:46
【问题描述】:

我必须“生成”一个 png 文件并通过 SeendDocumentAsync 的 SendPhotoAsync 将其发送到 Telegram 机器人。

这是我的一段 C# 代码:

...
Bitmap speedometer = new Bitmap(@"C:\Immagini\bot\speedometer.png");
Bitmap pointer = new Bitmap(@"C:\Immagini\bot\pointer.png");
Bitmap finalImage = new Bitmap(speedometer);
using (Graphics graphics = Graphics.FromImage(finalImage))
{
    Bitmap rotatedPointer = RotateImage(pointer, efficienza_int * (float)1.8);
    rotatedPointer.MakeTransparent(Color.White);
    graphics.SmoothingMode = SmoothingMode.HighQuality;
    graphics.DrawImage(rotatedPointer, 0, 0);
    ?????????????
}

现在,我想发送我的 finalImage 而不使用 Save 方法将其保存在磁盘上。 我该怎么办?

感谢您的建议!

【问题讨论】:

    标签: c# image bitmap send telegram-bot


    【解决方案1】:

    将其保存到MemoryStream,然后将您的呼叫中的MemoryStream 发送给机器人,如下所示:

    using (MemoryStream ms = new MemoryStream())
    using (Bitmap finalImage = new Bitmap(speedometer))
    {
        using (Graphics graphics = Graphics.FromImage(finalImage))
        {
            // ... stuff
        }
        finalImage.Save(ms, ImageFormat.Png);
        // This is important: otherwise anything reading the stream
        // will start at the point AFTER the written image.
        ms.Position = 0;
        Bot.SendPhotoAsync(/* send 'ms' here. Whatever the exact args are */);
    }
    

    异步发送可能需要流保持打开状态。不过,通常情况下,当你有这样一个异步发送时,你可以指定一个在发送完成后应该调用的函数。

    在这种情况下,您应该MemoryStream 放在using 块中,而是将流对象存储在类的全局变量中,并确保函数处理异步发送结束时将其丢弃。

    还要注意这个问题...

    bot.sendphoto does not work asp.net

    显然SendPhotoAsync 不足以实际发送;那里的答案指定您需要致电.GetAwaiter().GetResult()。我不知道 API,所以你必须自己弄清楚。

    【讨论】:

      【解决方案2】:

      来自 Telegram Bot API 文档 (link)

      发送文件 发送文件(照片、贴纸、音频、媒体等)的三种方式:

      ...

      1. 使用 multipart/form-data 以通常的方式发布文件,即通过浏览器上传文件。照片最大 10 MB,其他文件最大 50 MB。

      【讨论】:

        【解决方案3】:

        你的问题不清楚! 但是,(如果我正确理解您的问题) 您正在使用此存储库中的 TelgramBotClient:https://github.com/TelegramBots

        当您从该客户端调用 SendPhotoAsync 时,它会将 FileToSend 作为参数,表示您处理的具有旋转、透明度和平滑度的照片。

        当您传递此 FileToSend 时,您可以通过从处理后创建的临时文件加载照片来设置照片,也可以从 MemoryStream 加载它的目录,如下所示:

        using System.Drawing;
        using System.Drawing.Drawing2D;
        using Telegram.Bot;
        using Telegram.Bot.Args;
        using System.IO;
        using System.Drawing.Imaging;
        
        namespace LoadGraphicsFromMemory
        {
            public static class ImageExtensions
            {
                public static MemoryStream ToMemoryStream(this Bitmap image, ImageFormat format)
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        image.Save(ms, format);
                        return ms;
                    }
                }
        
            }
        
            class Program
            {
                private static float efficienza_int;
                private static readonly TelegramBotClient Bot = new TelegramBotClient("Your API key");
        
                static void Main(string[] args)
                {
        
        
                    Bot.OnMessage += BotOnMessageReceived;
                }
        
                private static void BotOnMessageReceived(object sender, MessageEventArgs e)
                {
                    Bitmap speedometer = new Bitmap(@"C:\Immagini\bot\speedometer.png");
                    Bitmap pointer = new Bitmap(@"C:\Immagini\bot\pointer.png");
                    Bitmap finalImage = new Bitmap(speedometer);
                    using (Graphics graphics = Graphics.FromImage(finalImage))
                    {
                        Bitmap rotatedPointer = RotateImage(pointer, efficienza_int * (float)1.8);
                        rotatedPointer.MakeTransparent(Color.White);
                        graphics.SmoothingMode = SmoothingMode.HighQuality;
                        graphics.DrawImage(rotatedPointer, 0, 0);
        
                    }
        
                    Bot.SendPhotoAsync(e.Message.Chat.Id, new Telegram.Bot.Types.FileToSend("My File", finalImage.ToMemoryStream(ImageFormat.Jpeg)));
                }
        
                private static Bitmap RotateImage(Bitmap pointer, object p)
                {
                    return pointer;
                }
        
        
            }
        }
        

        【讨论】:

        • 谢谢,你说得对!我正在尝试您的解决方案,但是我正在使用 SendPhotoAsync 命令和 Exception: ObjectDisposedException 我正在处理它。
        • 这个答案不起作用。您不能返回using 块中创建的流- 从离开ToMemoryStream 函数的那一刻起,该流将被释放并因此无效(因此是ObjectDisposedException)。并且不要要求人们在他们只是说它不起作用时接受答案。
        猜你喜欢
        • 2015-11-26
        • 2019-11-18
        • 1970-01-01
        • 1970-01-01
        • 2021-09-14
        • 1970-01-01
        • 2021-11-12
        • 2021-08-22
        • 1970-01-01
        相关资源
        最近更新 更多